Ghidra Decompiler Analysis Engine
address.hh
Go to the documentation of this file.
1 /* ###
2  * IP: GHIDRA
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
25 
26 #ifndef __CPUI_ADDR__
27 #define __CPUI_ADDR__
28 
29 #include "space.hh"
30 
31 class AddrSpaceManager;
32 
46 class Address {
47 protected:
49  uintb offset;
50 public:
52  enum mach_extreme {
55  };
56  Address(mach_extreme ex);
57  Address(void);
58  Address(AddrSpace *id,uintb off);
59  Address(const Address &op2);
60 
61  bool isInvalid(void) const;
62  int4 getAddrSize(void) const;
63  bool isBigEndian(void) const;
64  void printRaw(ostream &s) const;
65  int4 read(const string &s);
66  AddrSpace *getSpace(void) const;
67  uintb getOffset(void) const;
68  void toPhysical(void);
69  char getShortcut(void) const;
70  Address &operator=(const Address &op2);
71  bool operator==(const Address &op2) const;
72  bool operator!=(const Address &op2) const;
73  bool operator<(const Address &op2) const;
74  bool operator<=(const Address &op2) const;
75  Address operator+(int4 off) const;
76  Address operator-(int4 off) const;
77  friend ostream &operator<<(ostream &s,const Address &addr);
78  bool containedBy(int4 sz,const Address &op2,int4 sz2) const;
79  int4 justifiedContain(int4 sz,const Address &op2,int4 sz2,bool forceleft) const;
80  int4 overlap(int4 skip,const Address &op,int4 size) const;
81  bool isContiguous(int4 sz,const Address &loaddr,int4 losz) const;
82  bool isConstant(void) const;
83  void renormalize(int4 size);
84  bool isJoin(void) const;
85  void saveXml(ostream &s) const;
86  void saveXml(ostream &s,int4 size) const;
87 
89  static Address restoreXml(const Element *el,const AddrSpaceManager *manage);
90 
92  static Address restoreXml(const Element *el,const AddrSpaceManager *manage,int4 &size);
93 
95  static AddrSpace *getSpaceFromConst(const Address &addr);
96 };
97 
111 class SeqNum {
112  Address pc;
113  uintm uniq;
114  uintm order;
115 public:
116  SeqNum(void) {}
118 
120  SeqNum(const Address &a,uintm b) : pc(a) { uniq = b; }
121 
123  SeqNum(const SeqNum &op2) : pc(op2.pc) { uniq = op2.uniq; }
124 
126  const Address &getAddr(void) const { return pc; }
127 
129  uintm getTime(void) const { return uniq; }
130 
132  uintm getOrder(void) const { return order; }
133 
135  void setOrder(uintm ord) { order = ord; }
136 
138  bool operator==(const SeqNum &op2) const { return (uniq == op2.uniq); }
139 
141  bool operator!=(const SeqNum &op2) const { return (uniq != op2.uniq); }
142 
144  bool operator<(const SeqNum &op2) const {
145  if (pc == op2.pc)
146  return (uniq < op2.uniq);
147  return (pc < op2.pc);
148  }
149 
151  void saveXml(ostream &s) const;
152 
154  static SeqNum restoreXml(const Element *el,const AddrSpaceManager *manage);
155 
157  friend ostream &operator<<(ostream &s,const SeqNum &sq);
158 };
159 
161 class Range {
162  friend class RangeList;
163  AddrSpace *spc;
164  uintb first;
165  uintb last;
166 public:
173  Range(AddrSpace *s,uintb f,uintb l) {
174  spc = s; first = f; last = l; }
175  Range(void) {}
176  AddrSpace *getSpace(void) const { return spc; }
177  uintb getFirst(void) const { return first; }
178  uintb getLast(void) const { return last; }
179  Address getFirstAddr(void) const { return Address(spc,first); }
180  Address getLastAddr(void) const { return Address(spc,last); }
181  Address getLastAddrOpen(const AddrSpaceManager *manage) const;
182  bool contains(const Address &addr) const;
183 
189  bool operator<(const Range &op2) const {
190  if (spc->getIndex() != op2.spc->getIndex())
191  return (spc->getIndex() < op2.spc->getIndex());
192  return (first < op2.first); }
193  void printBounds(ostream &s) const;
194  void saveXml(ostream &s) const;
195  void restoreXml(const Element *el,const AddrSpaceManager *manage);
196 };
197 
203 class RangeList {
204  set<Range> tree;
205 public:
206  RangeList(const RangeList &op2) { tree = op2.tree; }
207  RangeList(void) {}
208  void clear(void) { tree.clear(); }
209  bool empty(void) const { return tree.empty(); }
210  set<Range>::const_iterator begin(void) const { return tree.begin(); }
211  set<Range>::const_iterator end(void) const { return tree.end(); }
212  int4 numRanges(void) const { return tree.size(); }
213  const Range *getFirstRange(void) const;
214  const Range *getLastRange(void) const;
215  const Range *getLastSignedRange(AddrSpace *spaceid) const;
216  const Range *getRange(AddrSpace *spaceid,uintb offset) const;
217  void insertRange(AddrSpace *spc,uintb first,uintb last);
218  void removeRange(AddrSpace *spc,uintb first,uintb last);
219  void merge(const RangeList &op2);
220  bool inRange(const Address &addr,int4 size) const;
221  uintb longestFit(const Address &addr,uintb maxsize) const;
222  void printBounds(ostream &s) const;
223  void saveXml(ostream &s) const;
224  void restoreXml(const Element *el,const AddrSpaceManager *manage);
225 };
226 
228 extern uintb uintbmasks[];
229 
230 // Inline functions
231 
234 inline Address::Address(void) {
235  base = (AddrSpace *)0;
236 }
237 
241 inline Address::Address(AddrSpace *id,uintb off) {
242  base=id; offset=off;
243 }
244 
248 inline Address::Address(const Address &op2) {
249  base = op2.base;
250  offset = op2.offset;
251 }
252 
256 inline bool Address::isInvalid(void) const {
257  return (base == (AddrSpace *)0);
258 }
259 
263 inline int4 Address::getAddrSize(void) const {
264  return base->getAddrSize();
265 }
266 
269 inline bool Address::isBigEndian(void) const {
270  return base->isBigEndian();
271 }
272 
276 inline void Address::printRaw(ostream &s) const {
277  if (base == (AddrSpace *)0) {
278  s << "invalid_addr";
279  return;
280  }
281  base->printRaw(s,offset);
282 }
283 
288 inline int4 Address::read(const string &s) {
289  int4 sz; offset=base->read(s,sz); return sz;
290 }
291 
294 inline AddrSpace *Address::getSpace(void) const {
295  return base;
296 }
297 
300 inline uintb Address::getOffset(void) const {
301  return offset;
302 }
303 
307 inline char Address::getShortcut(void) const {
308  return base->getShortcut();
309 }
310 
315 inline Address &Address::operator=(const Address &op2)
316 
317 {
318  base = op2.base;
319  offset = op2.offset;
320  return *this;
321 }
322 
327 inline bool Address::operator==(const Address &op2) const {
328  return ((base==op2.base)&&(offset==op2.offset));
329 }
330 
335 inline bool Address::operator!=(const Address &op2) const {
336  return !(*this==op2);
337 }
338 
346 inline bool Address::operator<(const Address &op2) const {
347  if (base != op2.base) {
348  if (base == (AddrSpace *)0) {
349  return true;
350  }
351  else if (base == (AddrSpace *) ~((uintp)0)) {
352  return false;
353  }
354  else if (op2.base == (AddrSpace *)0) {
355  return false;
356  }
357  else if (op2.base == (AddrSpace *) ~((uintp)0)) {
358  return true;
359  }
360  return (base->getIndex() < op2.base->getIndex());
361  }
362  if (offset != op2.offset) return (offset < op2.offset);
363  return false;
364 }
365 
369 inline bool Address::operator<=(const Address &op2) const {
370  if (base != op2.base) {
371  if (base == (AddrSpace *)0) {
372  return true;
373  }
374  else if (base == (AddrSpace *) ~((uintp)0)) {
375  return false;
376  }
377  else if (op2.base == (AddrSpace *)0) {
378  return false;
379  }
380  else if (op2.base == (AddrSpace *) ~((uintp)0)) {
381  return true;
382  }
383  return (base->getIndex() < op2.base->getIndex());
384  }
385  if (offset != op2.offset) return (offset < op2.offset);
386  return true;
387 }
388 
394 inline Address Address::operator+(int4 off) const {
395  return Address(base,base->wrapOffset(offset+off));
396 }
397 
404 inline Address Address::operator-(int4 off) const {
405  return Address(base,base->wrapOffset(offset-off));
406 }
407 
412 inline bool Address::isConstant(void) const {
413  return (base->getType() == IPTR_CONSTANT);
414 }
415 
418 inline bool Address::isJoin(void) const {
419  return (base->getType() == IPTR_JOIN);
420 }
421 
426 inline void Address::saveXml(ostream &s) const {
427  s << "<addr";
428  if (base!=(AddrSpace *)0)
430  s << "/>";
431 }
432 
438 inline void Address::saveXml(ostream &s,int4 size) const {
439  s << "<addr";
440  if (base!=(AddrSpace *)0)
441  base->saveXmlAttributes(s,offset,size);
442  s << "/>";
443 }
444 
453  return (AddrSpace *)(uintp)addr.offset;
454 }
455 
458 inline bool Range::contains(const Address &addr) const {
459  if (spc != addr.getSpace()) return false;
460  if (first > addr.getOffset()) return false;
461  if (last < addr.getOffset()) return false;
462  return true;
463 }
464 
467 inline uintb calc_mask(int4 size) { return uintbmasks[(size<8)? size : 8]; }
468 
473 inline uintb pcode_right(uintb val,int4 sa) {
474  if (sa >= 8*sizeof(uintb)) return 0;
475  return val >> sa;
476 }
477 
482 inline uintb pcode_left(uintb val,int4 sa) {
483  if (sa >= 8*sizeof(uintb)) return 0;
484  return val << sa;
485 }
486 
493 inline uintb minimalmask(uintb val)
494 
495 {
496  if (val > 0xffffffff)
497  return ~((uintb)0);
498  if (val > 0xffff)
499  return 0xffffffff;
500  if (val > 0xff)
501  return 0xffff;
502  return 0xff;
503 }
504 
505 extern bool signbit_negative(uintb val,int4 size);
506 extern uintb calc_mask(int4 size);
507 extern uintb uintb_negate(uintb in,int4 size);
508 extern uintb sign_extend(uintb in,int4 sizein,int4 sizeout);
509 
510 extern void sign_extend(intb &val,int4 bit);
511 extern void zero_extend(intb &val,int4 bit);
512 extern void byte_swap(intb &val,int4 size);
513 
514 extern uintb byte_swap(uintb val,int4 size);
515 extern int4 leastsigbit_set(uintb val);
516 extern int4 mostsigbit_set(uintb val);
517 extern int4 popcount(uintb val);
518 extern int4 count_leading_zeros(uintb val);
519 
520 extern uintb coveringmask(uintb val);
521 extern int4 bit_transitions(uintb val,int4 sz);
522 
523 extern void mult64to128(uint8 *res,uint8 x,uint8 y);
524 extern void unsignedSubtract128(uint8 *a,uint8 *b);
525 extern int4 unsignedCompare128(uint8 *a,uint8 *b);
526 extern int4 power2Divide(int4 n,uint8 divisor,uint8 &q,uint8 &r);
527 
528 #endif
power2Divide
int4 power2Divide(int4 n, uint8 divisor, uint8 &q, uint8 &r)
Unsigned division of a power of 2 (upto 2^127) by a 64-bit divisor.
Definition: address.cc:870
SeqNum::restoreXml
static SeqNum restoreXml(const Element *el, const AddrSpaceManager *manage)
Restore a SeqNum from parsed XML.
Definition: address.cc:56
SeqNum::getTime
uintm getTime(void) const
Get the time field of a sequence number.
Definition: address.hh:129
Range::operator<
bool operator<(const Range &op2) const
Sorting operator for Ranges.
Definition: address.hh:189
AddrSpace::printRaw
virtual void printRaw(ostream &s, uintb offset) const
Write an address in this space to a stream.
Definition: space.cc:189
RangeList::longestFit
uintb longestFit(const Address &addr, uintb maxsize) const
Find size of biggest Range containing given address.
Definition: address.cc:446
RangeList::getLastSignedRange
const Range * getLastSignedRange(AddrSpace *spaceid) const
Get the last Range viewing offsets as signed.
Definition: address.cc:496
AddrSpace
A region where processor data is stored.
Definition: space.hh:73
count_leading_zeros
int4 count_leading_zeros(uintb val)
Return the number of leading zero bits in the given value.
Definition: address.cc:743
bit_transitions
int4 bit_transitions(uintb val, int4 sz)
Calculate the number of bit transitions in the sized value.
Definition: address.cc:788
Address::Address
Address(void)
Create an invalid address.
Definition: address.hh:234
pcode_left
uintb pcode_left(uintb val, int4 sa)
Definition: address.hh:482
RangeList::restoreXml
void restoreXml(const Element *el, const AddrSpaceManager *manage)
Restore this RangeList from an XML stream.
Definition: address.cc:554
SeqNum::SeqNum
SeqNum(Address::mach_extreme ex)
Create an extremal sequence number.
Definition: address.cc:41
Address::overlap
int4 overlap(int4 skip, const Address &op, int4 size) const
Determine how two address ranges overlap.
Definition: address.cc:147
Address::read
int4 read(const string &s)
Read in the address from a string.
Definition: address.hh:288
AddrSpace::getAddrSize
uint4 getAddrSize(void) const
Get the size of the space.
Definition: space.hh:335
RangeList::getLastRange
const Range * getLastRange(void) const
Get the last Range.
Definition: address.cc:482
SeqNum
A class for uniquely labelling and comparing PcodeOps.
Definition: address.hh:111
Range::saveXml
void saveXml(ostream &s) const
Save this Range to an XML stream.
Definition: address.cc:264
SeqNum::getOrder
uintm getOrder(void) const
Get the order field of a sequence number.
Definition: address.hh:132
AddrSpace::read
virtual uintb read(const string &s, int4 &size) const
Read in an address (and possible size) from a string.
Definition: space.cc:238
Address::operator+
Address operator+(int4 off) const
Increment address by a number of bytes.
Definition: address.hh:394
AddrSpace::getShortcut
char getShortcut(void) const
Get the shortcut character.
Definition: space.hh:384
Address::operator<=
bool operator<=(const Address &op2) const
Compare two addresses via their natural ordering.
Definition: address.hh:369
RangeList::inRange
bool inRange(const Address &addr, int4 size) const
Check containment an address range.
Definition: address.cc:402
Address::operator<<
friend ostream & operator<<(ostream &s, const Address &addr)
Write out an address to stream.
Definition: address.cc:34
SeqNum::SeqNum
SeqNum(const Address &a, uintm b)
Create a sequence number with a specific time field.
Definition: address.hh:120
mult64to128
void mult64to128(uint8 *res, uint8 x, uint8 y)
Multiply 2 unsigned 64-bit values, producing a 128-bit value.
Definition: address.cc:812
Range::printBounds
void printBounds(ostream &s) const
Print this Range to a stream.
Definition: address.cc:255
Address::renormalize
void renormalize(int4 size)
Make sure there is a backing JoinRecord if this is in the join space.
Definition: address.cc:185
uintb_negate
uintb uintb_negate(uintb in, int4 size)
Negate the sized value.
Definition: address.cc:592
Address::mach_extreme
mach_extreme
An enum for specifying extremal addresses.
Definition: address.hh:52
Address::toPhysical
void toPhysical(void)
Convert this to a physical address.
Definition: address.cc:91
AddrSpace::getType
spacetype getType(void) const
Get the type of space.
Definition: space.hh:291
Address::isInvalid
bool isInvalid(void) const
Is the address invalid?
Definition: address.hh:256
Range::restoreXml
void restoreXml(const Element *el, const AddrSpaceManager *manage)
Restore this from XML stream.
Definition: address.cc:277
Address::getOffset
uintb getOffset(void) const
Get the address offset.
Definition: address.hh:300
pcode_right
uintb pcode_right(uintb val, int4 sa)
Definition: address.hh:473
SeqNum::operator<
bool operator<(const SeqNum &op2) const
Compare two sequence numbers with their natural order.
Definition: address.hh:144
zero_extend
void zero_extend(intb &val, int4 bit)
Clear all bits above given bit.
Definition: address.cc:639
Element
An XML element. A node in the DOM tree.
Definition: xml.hh:150
minimalmask
uintb minimalmask(uintb val)
Calculate smallest mask that covers the given value.
Definition: address.hh:493
Address::getSpaceFromConst
static AddrSpace * getSpaceFromConst(const Address &addr)
Recover an encoded address space from an address.
Definition: address.hh:452
SeqNum::operator==
bool operator==(const SeqNum &op2) const
Compare two sequence numbers for equality.
Definition: address.hh:138
Address::base
AddrSpace * base
Pointer to our address space.
Definition: address.hh:48
Address::getShortcut
char getShortcut(void) const
Get the shortcut character for the address space.
Definition: address.hh:307
Address::saveXml
void saveXml(ostream &s) const
Save this to a stream as an XML tag.
Definition: address.hh:426
Address::isConstant
bool isConstant(void) const
Is this a constant value.
Definition: address.hh:412
IPTR_JOIN
@ IPTR_JOIN
Special virtual space to represent split variables.
Definition: space.hh:35
Address::operator-
Address operator-(int4 off) const
Decrement address by a number of bytes.
Definition: address.hh:404
Range::contains
bool contains(const Address &addr) const
Determine if the address is in this Range.
Definition: address.hh:458
space.hh
Classes for describing address spaces.
RangeList
A disjoint set of Ranges, possibly across multiple address spaces.
Definition: address.hh:203
Address::m_minimal
@ m_minimal
Smallest possible address.
Definition: address.hh:53
sign_extend
uintb sign_extend(uintb in, int4 sizein, int4 sizeout)
Sign-extend a value between two byte sizes.
Definition: address.cc:604
mostsigbit_set
int4 mostsigbit_set(uintb val)
Return index of most significant bit set in given value.
Definition: address.cc:705
IPTR_CONSTANT
@ IPTR_CONSTANT
Special space to represent constants.
Definition: space.hh:29
AddrSpace::saveXmlAttributes
virtual void saveXmlAttributes(ostream &s, uintb offset) const
Save an address as XML.
Definition: space.cc:119
SeqNum::getAddr
const Address & getAddr(void) const
Get the address portion of a sequence number.
Definition: address.hh:126
Address::operator!=
bool operator!=(const Address &op2) const
Compare two addresses for inequality.
Definition: address.hh:335
popcount
int4 popcount(uintb val)
Return the number of one bits in the given value.
Definition: address.cc:726
unsignedCompare128
int4 unsignedCompare128(uint8 *a, uint8 *b)
Compare two unsigned 128-bit values.
Definition: address.cc:852
coveringmask
uintb coveringmask(uintb val)
Return a mask that covers the given value.
Definition: address.cc:770
Address::operator=
Address & operator=(const Address &op2)
Copy an address.
Definition: address.hh:315
RangeList::merge
void merge(const RangeList &op2)
Merge another RangeList into this.
Definition: address.cc:385
Address::operator==
bool operator==(const Address &op2) const
Compare two addresses for equality.
Definition: address.hh:327
Address::getSpace
AddrSpace * getSpace(void) const
Get the address space.
Definition: address.hh:294
RangeList::saveXml
void saveXml(ostream &s) const
Write this RangeList to an XML stream.
Definition: address.cc:538
RangeList::printBounds
void printBounds(ostream &s) const
Print a description of this RangeList to stream.
Definition: address.cc:522
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
SeqNum::SeqNum
SeqNum(const SeqNum &op2)
Copy a sequence number.
Definition: address.hh:123
RangeList::getRange
const Range * getRange(AddrSpace *spaceid, uintb offset) const
Get Range containing the given byte.
Definition: address.cc:425
AddrSpace::getIndex
int4 getIndex(void) const
Get the integer identifier.
Definition: space.hh:319
Address::isJoin
bool isJoin(void) const
Is this a join value.
Definition: address.hh:418
SeqNum::operator<<
friend ostream & operator<<(ostream &s, const SeqNum &sq)
Write out a SeqNum to a stream.
Definition: address.cc:19
Address::isBigEndian
bool isBigEndian(void) const
Is data at this address big endian encoded.
Definition: address.hh:269
Address::justifiedContain
int4 justifiedContain(int4 sz, const Address &op2, int4 sz2, bool forceleft) const
Determine if op2 is the least significant part of this.
Definition: address.cc:125
unsignedSubtract128
void unsignedSubtract128(uint8 *a, uint8 *b)
Subtract (in-place) a 128-bit value from a base 128-value.
Definition: address.cc:834
Address::isContiguous
bool isContiguous(int4 sz, const Address &loaddr, int4 losz) const
Does this form a contigous range with loaddr.
Definition: address.cc:167
RangeList::insertRange
void insertRange(AddrSpace *spc, uintb first, uintb last)
Insert a range of addresses.
Definition: address.cc:317
RangeList::getFirstRange
const Range * getFirstRange(void) const
Get the first Range.
Definition: address.cc:474
Range
A contiguous range of bytes in some address space.
Definition: address.hh:161
signbit_negative
bool signbit_negative(uintb val, int4 size)
Return true if the sign-bit is set.
Definition: address.cc:579
Range::Range
Range(AddrSpace *s, uintb f, uintb l)
Construct a Range from offsets.
Definition: address.hh:173
Address::printRaw
void printRaw(ostream &s) const
Write a raw version of the address to a stream.
Definition: address.hh:276
AddrSpace::isBigEndian
bool isBigEndian(void) const
Return true if values in this space are big endian.
Definition: space.hh:417
Address::containedBy
bool containedBy(int4 sz, const Address &op2, int4 sz2) const
Determine if op2 range contains this range.
Definition: address.cc:104
SeqNum::saveXml
void saveXml(ostream &s) const
Save a SeqNum to a stream as an XML tag.
Definition: address.cc:47
Range::getLastAddrOpen
Address getLastAddrOpen(const AddrSpaceManager *manage) const
Get address of first byte after this.
Definition: address.cc:237
Address::getAddrSize
int4 getAddrSize(void) const
Get the number of bytes in the address.
Definition: address.hh:263
Address::operator<
bool operator<(const Address &op2) const
Compare two addresses via their natural ordering.
Definition: address.hh:346
SeqNum::operator!=
bool operator!=(const SeqNum &op2) const
Compare two sequence numbers for inequality.
Definition: address.hh:141
AddrSpace::wrapOffset
uintb wrapOffset(uintb off) const
Wrap -off- to the offset that fits into this space.
Definition: space.hh:370
uintbmasks
uintb uintbmasks[]
Precalculated masks indexed by size.
Definition: address.cc:571
Address::restoreXml
static Address restoreXml(const Element *el, const AddrSpaceManager *manage)
Restore an address from parsed XML.
Definition: address.cc:201
SeqNum::setOrder
void setOrder(uintm ord)
Set the order field of a sequence number.
Definition: address.hh:135
AddrSpaceManager
A manager for different address spaces.
Definition: translate.hh:218
Address::m_maximal
@ m_maximal
Biggest possible address.
Definition: address.hh:54
RangeList::removeRange
void removeRange(AddrSpace *spc, uintb first, uintb last)
Remove a range of addresses.
Definition: address.cc:351
leastsigbit_set
int4 leastsigbit_set(uintb val)
Return index of least significant bit set in given value.
Definition: address.cc:684
Address::offset
uintb offset
Offset (in bytes)
Definition: address.hh:49
calc_mask
uintb calc_mask(int4 size)
Calculate a mask for a given byte size.
Definition: address.hh:467
byte_swap
void byte_swap(intb &val, int4 size)
Swap bytes in the given value.
Definition: address.cc:651