ROSE  0.9.9.109
unparsePowerpcAsm.C
1 #include "sage3basic.h"
2 #include "AsmUnparser.h"
3 
4 #include <iomanip>
5 #include <boost/lexical_cast.hpp>
6 #include "integerOps.h"
7 #include "Registers.h"
8 #include "Diagnostics.h"
9 
10 using namespace Rose;
11 using namespace Rose::Diagnostics;
12 using namespace Rose::BinaryAnalysis;
13 
14 /****************************************************
15  * resolve expression
16  ****************************************************/
17 static std::string unparsePowerpcRegister(SgAsmInstruction *insn, RegisterDescriptor rdesc, const RegisterDictionary *registers)
18 {
19  if (!registers)
21  std::string name = registers->lookup(rdesc);
22  if (name.empty())
23  name = AsmUnparser::invalid_register(insn, rdesc, registers);
24  return name;
25 }
26 
27 /* Helper for unparsePowerpcExpression(SgAsmExpression*) */
28 static std::string unparsePowerpcExpression(SgAsmExpression* expr, const AsmUnparser::LabelMap *labels,
29  const RegisterDictionary *registers, bool useHex) {
30  std::string result = "";
31  if (expr == NULL) return "BOGUS:NULL";
32  switch (expr->variantT()) {
33  case V_SgAsmBinaryAdd:
34  result = unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " +
35  unparsePowerpcExpression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false);
36  break;
37  case V_SgAsmMemoryReferenceExpression: {
38  SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr);
39  SgAsmExpression* addr = mr->get_address();
40  switch (addr->variantT()) {
41  case V_SgAsmBinaryAdd: {
42  SgAsmBinaryAdd* a = isSgAsmBinaryAdd(addr);
43  std::string lhs = unparsePowerpcExpression(a->get_lhs(), labels, registers, false);
44  if (isSgAsmValueExpression(a->get_rhs())) {
45  // Sign-extend from 16 bits
46  SgAsmValueExpression *ve = isSgAsmValueExpression(a->get_rhs());
47  ASSERT_not_null(ve);
48  result = boost::lexical_cast<std::string>(
49  (int64_t)IntegerOps::signExtend<16, 64>(SageInterface::getAsmConstant(ve)));
50  result += "(" + lhs + ")";
51  } else {
52  result = lhs + ", " + unparsePowerpcExpression(a->get_rhs(), labels, registers, false);
53  }
54  break;
55  }
56  default:
57  result = "(" + unparsePowerpcExpression(addr, labels, registers, false) + ")";
58  break;
59  }
60  break;
61  }
62  case V_SgAsmDirectRegisterExpression: {
63  SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr);
64  SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr);
65  result = unparsePowerpcRegister(insn, rr->get_descriptor(), registers);
66  break;
67  }
68  case V_SgAsmIntegerValueExpression: {
69  uint64_t v = isSgAsmIntegerValueExpression(expr)->get_absoluteValue();
70  if (useHex) {
71  result = StringUtility::intToHex(v);
72  } else {
74  }
75  if (expr->get_comment().empty() && labels) {
76  AsmUnparser::LabelMap::const_iterator li = labels->find(v);
77  if (li!=labels->end())
78  result = StringUtility::appendAsmComment(result, li->second);
79  }
80  break;
81  }
82  default: {
83  ASSERT_not_reachable("invalid PowerPC expression: " + expr->class_name());
84  }
85  }
86  result = StringUtility::appendAsmComment(result, expr->get_comment());
87  return result;
88 }
89 
91 std::string unparsePowerpcMnemonic(SgAsmPowerpcInstruction *insn) {
92  ASSERT_not_null(insn);
93  return insn->get_mnemonic();
94 }
95 
97 std::string unparsePowerpcExpression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels,
98  const RegisterDictionary *registers) {
99  /* Find the instruction with which this expression is associated. */
100  SgAsmPowerpcInstruction *insn = NULL;
101  for (SgNode *node=expr; !insn && node; node=node->get_parent()) {
102  insn = isSgAsmPowerpcInstruction(node);
103  }
104  ASSERT_not_null(insn);
105 
106  PowerpcInstructionKind kind = insn->get_kind();
107  bool isBranchTarget = (((kind == powerpc_b ||
108  kind == powerpc_bl ||
109  kind == powerpc_ba ||
110  kind == powerpc_bla) &&
111  expr==insn->get_operandList()->get_operands()[0]) ||
112  ((kind == powerpc_bc ||
113  kind == powerpc_bcl ||
114  kind == powerpc_bca ||
115  kind == powerpc_bcla) &&
116  insn->get_operandList()->get_operands().size()>=3 &&
117  expr==insn->get_operandList()->get_operands()[2]));
118  return unparsePowerpcExpression(expr, labels, registers, isBranchTarget);
119 }
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.
const SgAsmExpressionPtrList & get_operands() const
Property: Ordered list of instruction operands.
SgAsmExpression * get_address() const
Property: Memory address expression.
Main namespace for the ROSE library.
Describes (part of) a physical CPU register.
virtual VariantT variantT() const
returns new style SageIII enum values
const std::string & get_mnemonic() const
Property: Instruction mnemonic string.
SgAsmExpression * get_rhs() const
Property: Right-hand side operand.
Reference to memory locations.
SgAsmOperandList * get_operandList() const
Property: AST node that holds all operands.
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.
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:8322
uint64_t getAsmConstant(SgAsmValueExpression *e)
Get the unsigned value of a disassembled constant.
PowerpcInstructionKind get_kind() const
Property: Instruction kind.
Represents one PowerPC machine instruction.
static const RegisterDictionary * dictionary_powerpc()
PowerPC registers.
Defines registers available for a particular architecture.
Definition: Registers.h:32
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:897
Base class for values.
SgNode * get_parent() const
Access function for parent node.
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:264
const RegisterDescriptor * lookup(const std::string &name) const
Returns a descriptor for a given register name.