ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Expressions.C
Go to the documentation of this file.
1 /* This source file contains anything related to SgAsm*Expression nodes. */
2 #include "sage3basic.h"
3 #include "stringify.h" /* used in error messages */
4 #include "integerOps.h"
5 
6 using namespace rose;
7 
9 // Documentation for ROSETTA-generated things.
11 
12 
13 
15 
59 
101 // SgAsmIntegerValueExpression
104 
105 
107 uint64_t
109 {
110  if (!node)
111  return 0;
112  if (isSgAsmFunction(node))
113  return isSgAsmFunction(node)->get_entry_va();
114  if (isSgAsmStatement(node)) // instructions, block, function, staticdata, ...
115  return isSgAsmStatement(node)->get_address();
116  if (isSgAsmGenericSymbol(node))
117  return isSgAsmGenericSymbol(node)->get_value();
118  if (isSgAsmPEImportItem(node))
119  return isSgAsmPEImportItem(node)->get_bound_rva().get_va();
120  if (isSgAsmPERVASizePair(node))
121  return isSgAsmPERVASizePair(node)->get_e_rva().get_va();
122  if (isSgAsmGenericSection(node)) {
124  if (section->is_mapped())
125  return section->get_mapped_actual_va();
126  return 0;
127  }
128 
129  std::cerr <<"SgAsmIntegerValueExpression::virtual_address: non-addressable node type: "
130  <<stringifyVariantT(node->variantT(), "V_") <<std::endl;
131  assert(!"need addressable node type"); // to get location info in error messsage
132  abort(); // if asserts are disabled
133 }
134 
153 std::string
154 SgAsmIntegerValueExpression::get_label(bool quiet/*=false*/) const
155 {
156  SgNode *node = get_base_node();
157  if (!node)
158  return "";
159 
160  // Get the name of the base object if possible.
161  std::string retval;
162  std::string refkind;
163  if (isSgAsmFunction(node)) {
164  retval = isSgAsmFunction(node)->get_name();
165  refkind = "Func";
166  } else if (isSgAsmGenericSymbol(node)) {
167  retval = isSgAsmGenericSymbol(node)->get_name()->get_string();
168  refkind = "Sym";
169  } else if (isSgAsmPEImportItem(node)) {
170  retval = isSgAsmPEImportItem(node)->get_name()->get_string();
171  refkind = "Import";
172  } else if (isSgAsmGenericSection(node)) {
173  retval = isSgAsmGenericSection(node)->get_short_name();
174  refkind = "Section";
175  } else if (isSgAsmInstruction(node)) {
176  refkind = "Insn";
177  } else if (isSgAsmStaticData(node)) {
178  SgAsmBlock *blk = SageInterface::getEnclosingNode<SgAsmBlock>(node);
179  if (blk && 0!=(blk->get_reason() & SgAsmBlock::BLK_JUMPTABLE)) {
180  refkind = "JumpTable";
181  } else {
182  refkind = "StaticData";
183  }
184  } else if (isSgAsmBlock(node)) {
185  refkind = "BBlock";
186  } else if (isSgAsmPERVASizePair(node)) {
187  refkind = "Rva/Size";
188  } else {
189  refkind = "Reference";
190  }
191 
192  // If it has no name, then use something fairly generic. That way we can at least indicate that the value is relative.
193  int64_t offset = (int64_t)get_relative_value();
194  if (retval.empty()) {
195  retval = "<" + refkind; // extra level of brackets to indicate that it's not a real name
196  if (offset)
197  retval += "@" + StringUtility::addrToString(virtual_address(node), 32);
198  retval += ">";
199  }
200 
201  // Append the offset, but consider it to be signed. Disregard the number of significant bits in the absolute value and use
202  // a smaller bit width if possible. But don't use the minimum bit width since this makes it hard to tell how many bits
203  // there are at a glance (use only 8, 16, 32, or 64).
204  size_t nbits = 0;
205  if (offset > 0xffffffffll) {
206  nbits = 64;
207  retval += "+";
208  } else if (offset > 0xffffll) {
209  nbits = 32;
210  retval += "+";
211  } else if (offset > 0xffll) {
212  nbits = 16;
213  retval += "+";
214  } else if (offset > 9) {
215  nbits = 8;
216  retval += "+";
217  } else if (offset > 0) {
218  char buf[64];
219  snprintf(buf, sizeof buf, "+%"PRId64, offset);
220  retval += buf;
221  } else if (offset==0) {
222  /*void*/
223  } else if (-offset > 0xffffffffll) {
224  nbits = 64;
225  offset = -offset;
226  retval += "-";
227  } else if (-offset > 0xffffll) {
228  nbits = 32;
229  offset = -offset;
230  retval += "-";
231  } else if (-offset > 0xffll) {
232  nbits = 16;
233  offset = -offset;
234  retval += "-";
235  } else if (-offset > 9) {
236  nbits = 8;
237  offset = -offset;
238  retval += "-";
239  } else {
240  char buf[64];
241  snprintf(buf, sizeof buf, "%"PRId64, offset);
242  retval += buf;
243  }
244  if (nbits!=0)
245  retval += StringUtility::addrToString(offset, nbits);
246 
247  return retval;
248 }
249 
251 void
253 {
254  assert(nbits>0 && nbits<=64); // usual values are 8, 16, 32, and 64
255  p_significant_bits = nbits;
256 }
257 
259 size_t
261 {
262  return p_significant_bits;
263 }
264 
269 void
271 {
272  uint64_t cur_value = get_absolute_value();
273  uint64_t base_va = virtual_address(base_node);
274  set_base_node(base_node);
275  set_relative_value(cur_value - base_va); // mod 2^64
276 }
277 
280 uint64_t
282 {
283  return virtual_address(get_base_node());
284 }
285 
290 uint64_t
292 {
293  if (0==nbits)
294  nbits = get_significant_bits();
295  uint64_t retval = get_base_address() + get_relative_value();
296  uint64_t mask = IntegerOps::genMask<uint64_t>(nbits);
297  return retval & mask; // clear high-order bits
298 }
299 
301 int64_t
303 {
304  size_t nbits = get_significant_bits();
305  uint64_t u = (get_base_address() + get_relative_value()) & IntegerOps::genMask<uint64_t>(nbits);
306  uint64_t retval = IntegerOps::signExtend2(u, nbits, 64);
307  return (int64_t)retval;
308 }
309 
313 void
315 {
316  uint64_t new_offset = v - get_base_address(); // mod 2^64
317  set_relative_value(new_offset);
318 }