ROSE  0.9.11.56
unparseX86Asm.C
1 #include "sage3basic.h"
2 #include "Registers.h"
3 #include "AsmUnparser.h"
4 #include "Diagnostics.h"
5 #include "stringify.h"
6 
7 #include <iomanip>
8 
9 using namespace Rose;
10 using namespace Diagnostics;
11 using namespace BinaryAnalysis;
12 
14 std::string unparseX86Mnemonic(SgAsmX86Instruction *insn) {
15  ASSERT_not_null(insn);
16  std::string result;
17  if (insn->get_lockPrefix())
18  result += "lock ";
19  result += insn->get_mnemonic();
20  switch (insn->get_branchPrediction()) {
21  case x86_branch_prediction_none: break;
22  case x86_branch_prediction_taken: result += ",pt"; break;
23  case x86_branch_prediction_not_taken: result += ",pn"; break;
24  default:
25  ASSERT_not_reachable("bad x86 branch prediction: " +
26  stringifyBinaryAnalysisX86BranchPrediction(insn->get_branchPrediction()));
27  }
28  return result;
29 }
30 
35 std::string unparseX86Register(SgAsmInstruction *insn, RegisterDescriptor reg, const RegisterDictionary *registers) {
36  if (!registers)
37  registers = RegisterDictionary::dictionary_amd64();
38  std::string name = registers->lookup(reg);
39  if (name.empty())
40  name = AsmUnparser::invalid_register(insn, reg, registers);
41  return name;
42 }
43 
44 std::string unparseX86Register(RegisterDescriptor reg, const RegisterDictionary *registers) {
45  return unparseX86Register(NULL, reg, registers);
46 }
47 
48 static std::string x86ValToLabel(uint64_t val, const AsmUnparser::LabelMap *labels)
49 {
50  if (!val || !labels)
51  return "";
52 
53  AsmUnparser::LabelMap::const_iterator li = labels->find(val);
54  if (li==labels->end())
55  return "";
56 
57  return li->second;
58 }
59 
60 static std::string x86TypeToPtrName(SgAsmType* ty) {
61  if (NULL==ty) {
62  mlog[ERROR] <<"x86TypeToPtrName: null type\n";
63  return "BAD_TYPE";
64  }
65 
66  if (SgAsmIntegerType *it = isSgAsmIntegerType(ty)) {
67  switch (it->get_nBits()) {
68  case 8: return "byte";
69  case 16: return "word";
70  case 32: return "dword";
71  case 64: return "qword";
72  }
73  } else if (SgAsmFloatType *ft = isSgAsmFloatType(ty)) {
74  switch (ft->get_nBits()) {
75  case 32: return "float";
76  case 64: return "double";
77  case 80: return "ldouble";
78  }
80  return "dqword";
81  } else if (SgAsmVectorType *vt = isSgAsmVectorType(ty)) {
82  return "v" + StringUtility::numberToString(vt->get_nElmts()) + x86TypeToPtrName(vt->get_elmtType());
83  }
84  ASSERT_not_reachable("unhandled type: " + ty->toString());
85 }
86 
87 std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels,
88  const RegisterDictionary *registers, bool leaMode) {
89  std::string result = "";
90  if (expr == NULL) return "BOGUS:NULL";
91 
92  switch (expr->variantT()) {
93  case V_SgAsmBinaryAdd:
94  result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
95  unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
96  break;
97 
98  case V_SgAsmBinarySubtract:
99  result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " - " +
100  unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
101  break;
102 
103  case V_SgAsmBinaryMultiply:
104  result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + "*" +
105  unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
106  break;
107 
108  case V_SgAsmMemoryReferenceExpression: {
109  SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
110  if (!leaMode) {
111  result += x86TypeToPtrName(mr->get_type()) + " " +
112  (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, registers, false) + ":" : "");
113  }
114  result += "[" + unparseX86Expression(mr->get_address(), labels, registers, false) + "]";
115  break;
116  }
117 
118  case V_SgAsmDirectRegisterExpression: {
119  SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
120  SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
121  result = unparseX86Register(insn, rr->get_descriptor(), registers);
122  break;
123  }
124 
125  case V_SgAsmIndirectRegisterExpression: {
126  SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
127  SgAsmIndirectRegisterExpression* rr = isSgAsmIndirectRegisterExpression(expr);
128  result = unparseX86Register(insn, rr->get_descriptor(), registers);
129  if (!result.empty() && '0'==result[result.size()-1])
130  result = result.substr(0, result.size()-1);
131  result += "(" + StringUtility::numberToString(rr->get_index()) + ")";
132  break;
133  }
134 
135  case V_SgAsmIntegerValueExpression: {
136  SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr);
137  ASSERT_not_null(ival);
138  uint64_t value = ival->get_absoluteValue(); // not sign extended
139 
140  // If the value looks like it might be an address, then don't bother showing the decimal form.
141  if ((32==ival->get_significantBits() || 64==ival->get_significantBits()) &&
142  value > 0x0000ffff && value < 0xffff0000) {
143  result = StringUtility::addrToString(value, ival->get_significantBits());
144  } else {
145  result = StringUtility::signedToHex2(value, ival->get_significantBits());
146  }
147 
148  // Optional label. Prefer a label supplied by the caller's LabelMap, but not for single-byte constants. If
149  // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node.
150  if (expr->get_comment().empty()) {
151  std::string label;
152  if (label.empty() && ival->get_significantBits()>8)
153  label =x86ValToLabel(value, labels);
154  if (label.empty())
155  label = ival->get_label();
156  result = StringUtility::appendAsmComment(result, label);
157  }
158  break;
159  }
160 
161  default: {
162  ASSERT_not_reachable("invalid x86 expression: " + expr->class_name());
163  }
164  }
165 
166  result = StringUtility::appendAsmComment(result, expr->get_comment());
167  return result;
168 }
169 
171 std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels,
172  const RegisterDictionary *registers) {
173  /* Find the instruction with which this expression is associated. */
174  SgAsmX86Instruction *insn = NULL;
175  for (SgNode *node=expr; !insn && node; node=node->get_parent()) {
176  insn = isSgAsmX86Instruction(node);
177  }
178  ASSERT_not_null(insn);
179  return unparseX86Expression(expr, labels, registers, insn->get_kind()==x86_lea);
180 }
SgAsmType * get_type() const
Property: Type of expression.
ROSE_UTIL_API std::string signedToHex2(uint64_t value, size_t nbits)
Convert a number to a hexadecimal and decimal string.
ROSE_UTIL_API std::string numberToString(long long)
Convert an integer to a string.
SgAsmExpression * get_segment() const
Property: Optional memory segment register.
Base class for machine instructions.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
const std::string & get_comment() const
Property: Comment.
SgAsmIntegerType * buildTypeU64()
64-bit unsigned
Rose::BinaryAnalysis::X86BranchPrediction get_branchPrediction() const
Property: An enum constant describing branch prediction.
Error messages that indicate an abnormal situation from which the program was able to at least partia...
Definition: Message.h:327
SgAsmExpression * get_address() const
Property: Memory address expression.
Main namespace for the ROSE library.
virtual VariantT variantT() const
returns new style SageIII enum values
const std::string & get_mnemonic() const
Property: Instruction mnemonic string.
Reference to memory locations.
virtual std::string toString() const
Convert a type to a string.
ROSE_UTIL_API std::string appendAsmComment(const std::string &s, const std::string &comment)
Append an assembly comment to a string.
std::string get_label(bool quiet=false) const
Returns a label for the value.
Expression representing a machine register.
Base class for integer values.
bool get_lockPrefix() const
Property: Whether the x86 lock prefix was present.
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:8908
ROSE_UTIL_API std::string addrToString(uint64_t value, size_t nbits=0)
Convert a virtual address to a string.
size_t get_significantBits() const
Return the number of significant bits in the value.
Represents one Intel x86 machine instruction.
Base class for expressions.
virtual std::string class_name() const
returns a string representing the class name
Base class for binary types.
Registers accessed indirectly.
SgNode * get_parent() const
Access function for parent node.
Rose::BinaryAnalysis::X86InstructionKind get_kind() const
Property: Instruction kind.
Integer types.
uint64_t get_absoluteValue(size_t nbits=0) const
Returns the current absolute value zero filled to 64 bits.
Floating point types.
SgAsmVectorType * buildTypeVector(size_t, SgAsmType *)
Fixed-size, packed array.
Base class for vector types.