ROSE  0.11.31.0
unparsePowerpcAsm.C
1 #include <featureTests.h>
2 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
3 #include "sage3basic.h"
4 #include "AsmUnparser.h"
5 
6 #include <iomanip>
7 #include <boost/lexical_cast.hpp>
8 #include "integerOps.h"
9 #include "Registers.h"
10 #include "Diagnostics.h"
11 
12 using namespace Rose;
13 using namespace Rose::Diagnostics;
14 using namespace Rose::BinaryAnalysis;
15 
16 /****************************************************
17  * resolve expression
18  ****************************************************/
19 static std::string unparsePowerpcRegister(SgAsmInstruction *insn, RegisterDescriptor rdesc, const RegisterDictionary *registers)
20 {
21  if (!registers)
22  registers = RegisterDictionary::dictionary_powerpc32();
23  std::string name = registers->lookup(rdesc);
24  if (name.empty())
25  name = AsmUnparser::invalid_register(insn, rdesc, registers);
26  return name;
27 }
28 
29 /* Helper for unparsePowerpcExpression(SgAsmExpression*) */
30 static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
31  const RegisterDictionary *registers, bool useHex) {
32  std::string result = "";
33  if (expr == NULL) return "BOGUS:NULL";
34  switch (expr->variantT()) {
35  case V_SgAsmBinaryAdd:
36  result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
37  unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
38  break;
39  case V_SgAsmMemoryReferenceExpression: {
40  SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
41  SgAsmExpression* addr = mr->get_address();
42  switch (addr->variantT()) {
43  case V_SgAsmBinaryAdd: {
44  SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr);
45  std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false);
46  if (isSgAsmValueExpression(a->get_rhs())) {
47  // Sign-extend from 16 bits
48  SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs());
49  ASSERT_not_null(ve);
50  result = boost::lexical_cast<std::string>(
51  (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve)));
52  result += "(" + lhs + ")";
53  } else {
54  result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false);
55  }
56  break;
57  }
58  default:
59  result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")";
60  break;
61  }
62  break;
63  }
64  case V_SgAsmDirectRegisterExpression: {
65  SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
66  SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
67  result = unparsePowerpcRegister(insn, rr->get_descriptor(), registers);
68  break;
69  }
70  case V_SgAsmIntegerValueExpression: {
71  uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absoluteValue();
72  if (useHex) {
73  result = StringUtility::intToHex(v);
74  } else {
76  }
77  if (expr->get_comment().empty() && labels) {
78  AsmUnparser::LabelMap::const_iterator li = labels->find(v);
79  if (li!=labels->end())
80  result = StringUtility::appendAsmComment(result, li->second);
81  }
82  break;
83  }
84  default: {
85  ASSERT_not_reachable("invalid PowerPC expression: " + expr->class_name());
86  }
87  }
88  result = StringUtility::appendAsmComment(result, expr->get_comment());
89  return result;
90 }
91 
93 std::string unparsePowerpcMnemonic(SgAsmPowerpcInstruction *insn) {
94  ASSERT_not_null(insn);
95  return insn->get_mnemonic();
96 }
97 
99 std::string unparsePowerpcExpression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels,
100  const RegisterDictionary *registers) {
101  /* Find the instruction with which this expression is associated. */
102  SgAsmPowerpcInstruction *insn = NULL;
103  for (SgNode *node=expr; !insn && node; node=node->get_parent()) {
104  insn = isSgAsmPowerpcInstruction(node);
105  }
106  ASSERT_not_null(insn);
107 
108  PowerpcInstructionKind kind = insn->get_kind();
109  bool isBranchTarget = (((kind == powerpc_b ||
110  kind == powerpc_bl ||
111  kind == powerpc_ba ||
112  kind == powerpc_bla) &&
113  expr==insn->operand(0)) ||
114  ((kind == powerpc_bc ||
115  kind == powerpc_bcl ||
116  kind == powerpc_bca ||
117  kind == powerpc_bcla) &&
118  insn->nOperands() >= 3 &&
119  expr==insn->operand(2)));
120  return unparsePowerpcExpression(expr, labels, registers, isBranchTarget);
121 }
122 
123 #endif
ROSE_UTIL_API std::string intToHex(uint64_t)
Convert an integer to a hexadecimal string.
Expression that adds two operands.
ROSE_UTIL_API std::string numberToString(long long)
Convert an integer to a string.
SgAsmExpression * get_lhs() const
Property: Left-hand side operand.
Base class for machine instructions.
const std::string & get_comment() const
Property: Comment.
SgAsmExpression * get_address() const
Property: Memory address expression.
Main namespace for the ROSE library.
virtual VariantT variantT() const
returns new style SageIII enum values
PowerpcInstructionKind
PowerPC instruction types.
const std::string & get_mnemonic() const
Property: Instruction mnemonic string.
SgAsmExpression * get_rhs() const
Property: Right-hand side operand.
Reference to memory locations.
ROSE_UTIL_API std::string appendAsmComment(const std::string &s, const std::string &comment)
Append an assembly comment to a string.
Expression representing a machine register.
Binary analysis.
Describes (part of) a physical CPU register.
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:9451
Represents one PowerPC machine instruction.
Rose::BinaryAnalysis::PowerpcInstructionKind get_kind() const
Property: Instruction kind.
Base class for expressions.
virtual std::string class_name() const
returns a string representing the class name
std::map< uint64_t, std::string > LabelMap
Maps integers to labels.
Definition: AsmUnparser.h:900
Base class for values.
SgNode * get_parent() const
Access function for parent node.
size_t nOperands() const
Number of operands.
Defines registers available for a particular architecture.
Definition: Registers.h:38
uint64_t get_absoluteValue(size_t nbits=0) const
Returns the current absolute value zero filled to 64 bits.
Controls diagnostic messages from ROSE.
Definition: Diagnostics.h:290
SgAsmExpression * operand(size_t) const
Nth operand.