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