1from __future__ import print_function 2import struct 3import sys 4 5import gdb.printing 6import gdb.types 7 8class Iterator: 9 def __iter__(self): 10 return self 11 12 if sys.version_info.major == 2: 13 def next(self): 14 return self.__next__() 15 16 def children(self): 17 return self 18 19class SmallStringPrinter: 20 """Print an llvm::SmallString object.""" 21 22 def __init__(self, val): 23 self.val = val 24 25 def to_string(self): 26 data = self.val['BeginX'].cast(gdb.lookup_type('char').pointer()) 27 length = self.val['Size'] 28 return data.lazy_string(length=length) 29 30 def display_hint (self): 31 return 'string' 32 33class StringRefPrinter: 34 """Print an llvm::StringRef object.""" 35 36 def __init__(self, val): 37 self.val = val 38 39 def to_string(self): 40 data = self.val['Data'] 41 length = self.val['Length'] 42 return data.lazy_string(length=length) 43 44 def display_hint(self): 45 return 'string' 46 47class SmallVectorPrinter(Iterator): 48 """Print an llvm::SmallVector object.""" 49 50 def __init__(self, val): 51 self.val = val 52 t = val.type.template_argument(0).pointer() 53 self.begin = val['BeginX'].cast(t) 54 self.size = val['Size'] 55 self.i = 0 56 57 def __next__(self): 58 if self.i == self.size: 59 raise StopIteration 60 ret = '[{}]'.format(self.i), (self.begin+self.i).dereference() 61 self.i += 1 62 return ret 63 64 def to_string(self): 65 return 'llvm::SmallVector of Size {}, Capacity {}'.format(self.size, self.val['Capacity']) 66 67 def display_hint (self): 68 return 'array' 69 70class ArrayRefPrinter: 71 """Print an llvm::ArrayRef object.""" 72 73 class _iterator: 74 def __init__(self, begin, end): 75 self.cur = begin 76 self.end = end 77 self.count = 0 78 79 def __iter__(self): 80 return self 81 82 def __next__(self): 83 if self.cur == self.end: 84 raise StopIteration 85 count = self.count 86 self.count = self.count + 1 87 cur = self.cur 88 self.cur = self.cur + 1 89 return '[%d]' % count, cur.dereference() 90 91 if sys.version_info.major == 2: 92 next = __next__ 93 94 def __init__(self, val): 95 self.val = val 96 97 def children(self): 98 data = self.val['Data'] 99 return self._iterator(data, data + self.val['Length']) 100 101 def to_string(self): 102 return 'llvm::ArrayRef of length %d' % (self.val['Length']) 103 104 def display_hint (self): 105 return 'array' 106 107class ExpectedPrinter(Iterator): 108 """Print an llvm::Expected object.""" 109 110 def __init__(self, val): 111 self.val = val 112 113 def __next__(self): 114 val = self.val 115 if val is None: 116 raise StopIteration 117 self.val = None 118 if val['HasError']: 119 return ('error', val['ErrorStorage'].address.cast( 120 gdb.lookup_type('llvm::ErrorInfoBase').pointer()).dereference()) 121 return ('value', val['TStorage'].address.cast( 122 val.type.template_argument(0).pointer()).dereference()) 123 124 def to_string(self): 125 return 'llvm::Expected{}'.format(' is error' if self.val['HasError'] else '') 126 127class OptionalPrinter(Iterator): 128 """Print an llvm::Optional object.""" 129 130 def __init__(self, val): 131 self.val = val 132 133 def __next__(self): 134 val = self.val 135 if val is None: 136 raise StopIteration 137 self.val = None 138 if not val['Storage']['hasVal']: 139 raise StopIteration 140 return ('value', val['Storage']['val']) 141 142 def to_string(self): 143 return 'llvm::Optional{}'.format('' if self.val['Storage']['hasVal'] else ' is not initialized') 144 145class DenseMapPrinter: 146 "Print a DenseMap" 147 148 class _iterator: 149 def __init__(self, key_info_t, begin, end): 150 self.key_info_t = key_info_t 151 self.cur = begin 152 self.end = end 153 self.advancePastEmptyBuckets() 154 self.first = True 155 156 def __iter__(self): 157 return self 158 159 def advancePastEmptyBuckets(self): 160 # disabled until the comments below can be addressed 161 # keeping as notes/posterity/hints for future contributors 162 return 163 n = self.key_info_t.name 164 is_equal = gdb.parse_and_eval(n + '::isEqual') 165 empty = gdb.parse_and_eval(n + '::getEmptyKey()') 166 tombstone = gdb.parse_and_eval(n + '::getTombstoneKey()') 167 # the following is invalid, GDB fails with: 168 # Python Exception <class 'gdb.error'> Attempt to take address of value 169 # not located in memory. 170 # because isEqual took parameter (for the unsigned long key I was testing) 171 # by const ref, and GDB 172 # It's also not entirely general - we should be accessing the "getFirst()" 173 # member function, not the 'first' member variable, but I've yet to figure 174 # out how to find/call member functions (especially (const) overloaded 175 # ones) on a gdb.Value. 176 while self.cur != self.end and (is_equal(self.cur.dereference()['first'], empty) or is_equal(self.cur.dereference()['first'], tombstone)): 177 self.cur = self.cur + 1 178 179 def __next__(self): 180 if self.cur == self.end: 181 raise StopIteration 182 cur = self.cur 183 v = cur.dereference()['first' if self.first else 'second'] 184 if not self.first: 185 self.cur = self.cur + 1 186 self.advancePastEmptyBuckets() 187 self.first = True 188 else: 189 self.first = False 190 return 'x', v 191 192 if sys.version_info.major == 2: 193 next = __next__ 194 195 def __init__(self, val): 196 self.val = val 197 198 def children(self): 199 t = self.val.type.template_argument(3).pointer() 200 begin = self.val['Buckets'].cast(t) 201 end = (begin + self.val['NumBuckets']).cast(t) 202 return self._iterator(self.val.type.template_argument(2), begin, end) 203 204 def to_string(self): 205 return 'llvm::DenseMap with %d elements' % (self.val['NumEntries']) 206 207 def display_hint(self): 208 return 'map' 209 210class StringMapPrinter: 211 "Print a StringMap" 212 213 def __init__(self, val): 214 self.val = val 215 216 def children(self): 217 it = self.val['TheTable'] 218 end = (it + self.val['NumBuckets']) 219 value_ty = self.val.type.template_argument(0) 220 entry_base_ty = gdb.lookup_type('llvm::StringMapEntryBase') 221 tombstone = gdb.parse_and_eval('llvm::StringMapImpl::TombstoneIntVal'); 222 223 while it != end: 224 it_deref = it.dereference() 225 if it_deref == 0 or it_deref == tombstone: 226 it = it + 1 227 continue 228 229 entry_ptr = it_deref.cast(entry_base_ty.pointer()) 230 entry = entry_ptr.dereference() 231 232 str_len = entry['keyLength'] 233 value_ptr = (entry_ptr + 1).cast(value_ty.pointer()) 234 str_data = (entry_ptr + 1).cast(gdb.lookup_type('uintptr_t')) + max(value_ty.sizeof, entry_base_ty.alignof) 235 str_data = str_data.cast(gdb.lookup_type('char').const().pointer()) 236 string_ref = gdb.Value(struct.pack('PN', int(str_data), int(str_len)), gdb.lookup_type('llvm::StringRef')) 237 yield 'key', string_ref 238 239 value = value_ptr.dereference() 240 yield 'value', value 241 242 it = it + 1 243 244 def to_string(self): 245 return 'llvm::StringMap with %d elements' % (self.val['NumItems']) 246 247 def display_hint(self): 248 return 'map' 249 250class TwinePrinter: 251 "Print a Twine" 252 253 def __init__(self, val): 254 self._val = val 255 256 def display_hint(self): 257 return 'string' 258 259 def string_from_pretty_printer_lookup(self, val): 260 '''Lookup the default pretty-printer for val and use it. 261 262 If no pretty-printer is defined for the type of val, print an error and 263 return a placeholder string.''' 264 265 pp = gdb.default_visualizer(val) 266 if pp: 267 s = pp.to_string() 268 269 # The pretty-printer may return a LazyString instead of an actual Python 270 # string. Convert it to a Python string. However, GDB doesn't seem to 271 # register the LazyString type, so we can't check 272 # "type(s) == gdb.LazyString". 273 if 'LazyString' in type(s).__name__: 274 s = s.value().string() 275 276 else: 277 print(('No pretty printer for {} found. The resulting Twine ' + 278 'representation will be incomplete.').format(val.type.name)) 279 s = '(missing {})'.format(val.type.name) 280 281 return s 282 283 def is_twine_kind(self, kind, expected): 284 if not kind.endswith(expected): 285 return False 286 # apparently some GDB versions add the NodeKind:: namespace 287 # (happens for me on GDB 7.11) 288 return kind in ('llvm::Twine::' + expected, 289 'llvm::Twine::NodeKind::' + expected) 290 291 def string_from_child(self, child, kind): 292 '''Return the string representation of the Twine::Child child.''' 293 294 if self.is_twine_kind(kind, 'EmptyKind') or self.is_twine_kind(kind, 'NullKind'): 295 return '' 296 297 if self.is_twine_kind(kind, 'TwineKind'): 298 return self.string_from_twine_object(child['twine'].dereference()) 299 300 if self.is_twine_kind(kind, 'CStringKind'): 301 return child['cString'].string() 302 303 if self.is_twine_kind(kind, 'StdStringKind'): 304 val = child['stdString'].dereference() 305 return self.string_from_pretty_printer_lookup(val) 306 307 if self.is_twine_kind(kind, 'PtrAndLengthKind'): 308 val = child['ptrAndLength'] 309 data = val['ptr'] 310 length = val['length'] 311 return data.string(length=length) 312 313 if self.is_twine_kind(kind, 'CharKind'): 314 return chr(child['character']) 315 316 if self.is_twine_kind(kind, 'DecUIKind'): 317 return str(child['decUI']) 318 319 if self.is_twine_kind(kind, 'DecIKind'): 320 return str(child['decI']) 321 322 if self.is_twine_kind(kind, 'DecULKind'): 323 return str(child['decUL'].dereference()) 324 325 if self.is_twine_kind(kind, 'DecLKind'): 326 return str(child['decL'].dereference()) 327 328 if self.is_twine_kind(kind, 'DecULLKind'): 329 return str(child['decULL'].dereference()) 330 331 if self.is_twine_kind(kind, 'DecLLKind'): 332 return str(child['decLL'].dereference()) 333 334 if self.is_twine_kind(kind, 'UHexKind'): 335 val = child['uHex'].dereference() 336 return hex(int(val)) 337 338 print(('Unhandled NodeKind {} in Twine pretty-printer. The result will be ' 339 'incomplete.').format(kind)) 340 341 return '(unhandled {})'.format(kind) 342 343 def string_from_twine_object(self, twine): 344 '''Return the string representation of the Twine object twine.''' 345 346 lhs = twine['LHS'] 347 rhs = twine['RHS'] 348 349 lhs_kind = str(twine['LHSKind']) 350 rhs_kind = str(twine['RHSKind']) 351 352 lhs_str = self.string_from_child(lhs, lhs_kind) 353 rhs_str = self.string_from_child(rhs, rhs_kind) 354 355 return lhs_str + rhs_str 356 357 def to_string(self): 358 return self.string_from_twine_object(self._val) 359 360 def display_hint(self): 361 return 'string' 362 363def get_pointer_int_pair(val): 364 """Get tuple from llvm::PointerIntPair.""" 365 info_name = val.type.template_argument(4).strip_typedefs().name 366 # Note: this throws a gdb.error if the info type is not used (by means of a 367 # call to getPointer() or similar) in the current translation unit. 368 enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants') 369 enum_dict = gdb.types.make_enum_dict(enum_type) 370 ptr_mask = enum_dict[info_name + '::PointerBitMask'] 371 int_shift = enum_dict[info_name + '::IntShift'] 372 int_mask = enum_dict[info_name + '::IntMask'] 373 pair_union = val['Value'] 374 pointer = (pair_union & ptr_mask) 375 value = ((pair_union >> int_shift) & int_mask) 376 return (pointer, value) 377 378class PointerIntPairPrinter: 379 """Print a PointerIntPair.""" 380 381 def __init__(self, pointer, value): 382 self.pointer = pointer 383 self.value = value 384 385 def children(self): 386 yield ('pointer', self.pointer) 387 yield ('value', self.value) 388 389 def to_string(self): 390 return '(%s, %s)' % (self.pointer.type, self.value.type) 391 392def make_pointer_int_pair_printer(val): 393 """Factory for an llvm::PointerIntPair printer.""" 394 try: 395 pointer, value = get_pointer_int_pair(val) 396 except gdb.error: 397 return None # If PointerIntPair cannot be analyzed, print as raw value. 398 pointer_type = val.type.template_argument(0) 399 value_type = val.type.template_argument(2) 400 return PointerIntPairPrinter(pointer.cast(pointer_type), 401 value.cast(value_type)) 402 403class PointerUnionPrinter: 404 """Print a PointerUnion.""" 405 406 def __init__(self, pointer): 407 self.pointer = pointer 408 409 def children(self): 410 yield ('pointer', self.pointer) 411 412 def to_string(self): 413 return "Containing %s" % self.pointer.type 414 415def make_pointer_union_printer(val): 416 """Factory for an llvm::PointerUnion printer.""" 417 try: 418 pointer, value = get_pointer_int_pair(val['Val']) 419 except gdb.error: 420 return None # If PointerIntPair cannot be analyzed, print as raw value. 421 pointer_type = val.type.template_argument(int(value)) 422 return PointerUnionPrinter(pointer.cast(pointer_type)) 423 424class IlistNodePrinter: 425 """Print an llvm::ilist_node object.""" 426 427 def __init__(self, val): 428 impl_type = val.type.fields()[0].type 429 base_type = impl_type.fields()[0].type 430 derived_type = val.type.template_argument(0) 431 432 def get_prev_and_sentinel(base): 433 # One of Prev and PrevAndSentinel exists. Depending on #defines used to 434 # compile LLVM, the base_type's template argument is either true of false. 435 if base_type.template_argument(0): 436 return get_pointer_int_pair(base['PrevAndSentinel']) 437 return base['Prev'], None 438 439 # Casts a base_type pointer to the appropriate derived type. 440 def cast_pointer(pointer): 441 sentinel = get_prev_and_sentinel(pointer.dereference())[1] 442 pointer = pointer.cast(impl_type.pointer()) 443 if sentinel: 444 return pointer 445 return pointer.cast(derived_type.pointer()) 446 447 # Repeated cast becaue val.type's base_type is ambiguous when using tags. 448 base = val.cast(impl_type).cast(base_type) 449 (prev, sentinel) = get_prev_and_sentinel(base) 450 prev = prev.cast(base_type.pointer()) 451 self.prev = cast_pointer(prev) 452 self.next = cast_pointer(val['Next']) 453 self.sentinel = sentinel 454 455 def children(self): 456 if self.sentinel: 457 yield 'sentinel', 'yes' 458 yield 'prev', self.prev 459 yield 'next', self.next 460 461class IlistPrinter: 462 """Print an llvm::simple_ilist or llvm::iplist object.""" 463 464 def __init__(self, val): 465 self.node_type = val.type.template_argument(0) 466 sentinel = val['Sentinel'] 467 # First field is common base type of sentinel and ilist_node. 468 base_type = sentinel.type.fields()[0].type 469 self.sentinel = sentinel.address.cast(base_type.pointer()) 470 471 def _pointers(self): 472 pointer = self.sentinel 473 while True: 474 pointer = pointer['Next'].cast(pointer.type) 475 if pointer == self.sentinel: 476 return 477 yield pointer.cast(self.node_type.pointer()) 478 479 def children(self): 480 for k, v in enumerate(self._pointers()): 481 yield ('[%d]' % k, v.dereference()) 482 483 484pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport") 485pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter) 486pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter) 487pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter) 488pp.add_printer('llvm::ArrayRef', '^llvm::(Mutable)?ArrayRef<.*>$', ArrayRefPrinter) 489pp.add_printer('llvm::Expected', '^llvm::Expected<.*>$', ExpectedPrinter) 490pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter) 491pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter) 492pp.add_printer('llvm::StringMap', '^llvm::StringMap<.*>$', StringMapPrinter) 493pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter) 494pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', make_pointer_int_pair_printer) 495pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', make_pointer_union_printer) 496pp.add_printer('llvm::ilist_node', '^llvm::ilist_node<.*>$', IlistNodePrinter) 497pp.add_printer('llvm::iplist', '^llvm::iplist<.*>$', IlistPrinter) 498pp.add_printer('llvm::simple_ilist', '^llvm::simple_ilist<.*>$', IlistPrinter) 499gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) 500