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_ty = gdb.lookup_type('llvm::StringMapEntry<{}>'.format(value_ty.name)) 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_ty.pointer()) 224 entry = entry_ptr.dereference() 225 226 str_len = entry['keyLength'] 227 str_data = (entry_ptr + 1).cast(gdb.lookup_type('char').const().pointer()) 228 string_ref = gdb.Value(struct.pack('PN', int(str_data), int(str_len)), gdb.lookup_type('llvm::StringRef')) 229 yield 'key', string_ref 230 231 value = entry['second'] 232 yield 'value', value 233 234 it = it + 1 235 236 def to_string(self): 237 return 'llvm::StringMap with %d elements' % (self.val['NumItems']) 238 239 def display_hint(self): 240 return 'map' 241 242class TwinePrinter: 243 "Print a Twine" 244 245 def __init__(self, val): 246 self._val = val 247 248 def display_hint(self): 249 return 'string' 250 251 def string_from_pretty_printer_lookup(self, val): 252 '''Lookup the default pretty-printer for val and use it. 253 254 If no pretty-printer is defined for the type of val, print an error and 255 return a placeholder string.''' 256 257 pp = gdb.default_visualizer(val) 258 if pp: 259 s = pp.to_string() 260 261 # The pretty-printer may return a LazyString instead of an actual Python 262 # string. Convert it to a Python string. However, GDB doesn't seem to 263 # register the LazyString type, so we can't check 264 # "type(s) == gdb.LazyString". 265 if 'LazyString' in type(s).__name__: 266 s = s.value().address.string() 267 268 else: 269 print(('No pretty printer for {} found. The resulting Twine ' + 270 'representation will be incomplete.').format(val.type.name)) 271 s = '(missing {})'.format(val.type.name) 272 273 return s 274 275 def is_twine_kind(self, kind, expected): 276 if not kind.endswith(expected): 277 return False 278 # apparently some GDB versions add the NodeKind:: namespace 279 # (happens for me on GDB 7.11) 280 return kind in ('llvm::Twine::' + expected, 281 'llvm::Twine::NodeKind::' + expected) 282 283 def string_from_child(self, child, kind): 284 '''Return the string representation of the Twine::Child child.''' 285 286 if self.is_twine_kind(kind, 'EmptyKind') or self.is_twine_kind(kind, 'NullKind'): 287 return '' 288 289 if self.is_twine_kind(kind, 'TwineKind'): 290 return self.string_from_twine_object(child['twine'].dereference()) 291 292 if self.is_twine_kind(kind, 'CStringKind'): 293 return child['cString'].string() 294 295 if self.is_twine_kind(kind, 'StdStringKind'): 296 val = child['stdString'].dereference() 297 return self.string_from_pretty_printer_lookup(val) 298 299 if self.is_twine_kind(kind, 'StringRefKind'): 300 val = child['stringRef'].dereference() 301 pp = StringRefPrinter(val) 302 return pp.to_string() 303 304 if self.is_twine_kind(kind, 'SmallStringKind'): 305 val = child['smallString'].dereference() 306 pp = SmallStringPrinter(val) 307 return pp.to_string() 308 309 if self.is_twine_kind(kind, 'CharKind'): 310 return chr(child['character']) 311 312 if self.is_twine_kind(kind, 'DecUIKind'): 313 return str(child['decUI']) 314 315 if self.is_twine_kind(kind, 'DecIKind'): 316 return str(child['decI']) 317 318 if self.is_twine_kind(kind, 'DecULKind'): 319 return str(child['decUL'].dereference()) 320 321 if self.is_twine_kind(kind, 'DecLKind'): 322 return str(child['decL'].dereference()) 323 324 if self.is_twine_kind(kind, 'DecULLKind'): 325 return str(child['decULL'].dereference()) 326 327 if self.is_twine_kind(kind, 'DecLLKind'): 328 return str(child['decLL'].dereference()) 329 330 if self.is_twine_kind(kind, 'UHexKind'): 331 val = child['uHex'].dereference() 332 return hex(int(val)) 333 334 print(('Unhandled NodeKind {} in Twine pretty-printer. The result will be ' 335 'incomplete.').format(kind)) 336 337 return '(unhandled {})'.format(kind) 338 339 def string_from_twine_object(self, twine): 340 '''Return the string representation of the Twine object twine.''' 341 342 lhs_str = '' 343 rhs_str = '' 344 345 lhs = twine['LHS'] 346 rhs = twine['RHS'] 347 lhs_kind = str(twine['LHSKind']) 348 rhs_kind = str(twine['RHSKind']) 349 350 lhs_str = self.string_from_child(lhs, lhs_kind) 351 rhs_str = self.string_from_child(rhs, rhs_kind) 352 353 return lhs_str + rhs_str 354 355 def to_string(self): 356 return self.string_from_twine_object(self._val) 357 358def get_pointer_int_pair(val): 359 """Get tuple from llvm::PointerIntPair.""" 360 info_name = val.type.template_argument(4).strip_typedefs().name 361 # Note: this throws a gdb.error if the info type is not used (by means of a 362 # call to getPointer() or similar) in the current translation unit. 363 enum_type = gdb.lookup_type(info_name + '::MaskAndShiftConstants') 364 enum_dict = gdb.types.make_enum_dict(enum_type) 365 ptr_mask = enum_dict[info_name + '::PointerBitMask'] 366 int_shift = enum_dict[info_name + '::IntShift'] 367 int_mask = enum_dict[info_name + '::IntMask'] 368 pair_union = val['Value'] 369 pointer = (pair_union & ptr_mask) 370 value = ((pair_union >> int_shift) & int_mask) 371 return (pointer, value) 372 373class PointerIntPairPrinter: 374 """Print a PointerIntPair.""" 375 376 def __init__(self, pointer, value): 377 self.pointer = pointer 378 self.value = value 379 380 def children(self): 381 yield ('pointer', self.pointer) 382 yield ('value', self.value) 383 384def make_pointer_int_pair_printer(val): 385 """Factory for an llvm::PointerIntPair printer.""" 386 try: 387 pointer, value = get_pointer_int_pair(val) 388 except gdb.error: 389 return None # If PointerIntPair cannot be analyzed, print as raw value. 390 pointer_type = val.type.template_argument(0) 391 value_type = val.type.template_argument(2) 392 return PointerIntPairPrinter(pointer.cast(pointer_type), 393 value.cast(value_type)) 394 395class PointerUnionPrinter: 396 """Print a PointerUnion.""" 397 398 def __init__(self, pointer): 399 self.pointer = pointer 400 401 def children(self): 402 yield ('pointer', self.pointer) 403 404 def to_string(self): 405 return "Containing %s" % self.pointer.type 406 407def make_pointer_union_printer(val): 408 """Factory for an llvm::PointerUnion printer.""" 409 try: 410 pointer, value = get_pointer_int_pair(val['Val']) 411 except gdb.error: 412 return None # If PointerIntPair cannot be analyzed, print as raw value. 413 pointer_type = val.type.template_argument(int(value)) 414 return PointerUnionPrinter(pointer.cast(pointer_type)) 415 416class IlistNodePrinter: 417 """Print an llvm::ilist_node object.""" 418 419 def __init__(self, val): 420 impl_type = val.type.fields()[0].type 421 base_type = impl_type.fields()[0].type 422 derived_type = val.type.template_argument(0) 423 424 def get_prev_and_sentinel(base): 425 # One of Prev and PrevAndSentinel exists. Depending on #defines used to 426 # compile LLVM, the base_type's template argument is either true of false. 427 if base_type.template_argument(0): 428 return get_pointer_int_pair(base['PrevAndSentinel']) 429 return base['Prev'], None 430 431 # Casts a base_type pointer to the appropriate derived type. 432 def cast_pointer(pointer): 433 sentinel = get_prev_and_sentinel(pointer.dereference())[1] 434 pointer = pointer.cast(impl_type.pointer()) 435 if sentinel: 436 return pointer 437 return pointer.cast(derived_type.pointer()) 438 439 # Repeated cast becaue val.type's base_type is ambiguous when using tags. 440 base = val.cast(impl_type).cast(base_type) 441 (prev, sentinel) = get_prev_and_sentinel(base) 442 prev = prev.cast(base_type.pointer()) 443 self.prev = cast_pointer(prev) 444 self.next = cast_pointer(val['Next']) 445 self.sentinel = sentinel 446 447 def children(self): 448 if self.sentinel: 449 yield 'sentinel', 'yes' 450 yield 'prev', self.prev 451 yield 'next', self.next 452 453class IlistPrinter: 454 """Print an llvm::simple_ilist or llvm::iplist object.""" 455 456 def __init__(self, val): 457 self.node_type = val.type.template_argument(0) 458 sentinel = val['Sentinel'] 459 # First field is common base type of sentinel and ilist_node. 460 base_type = sentinel.type.fields()[0].type 461 self.sentinel = sentinel.address.cast(base_type.pointer()) 462 463 def _pointers(self): 464 pointer = self.sentinel 465 while True: 466 pointer = pointer['Next'].cast(pointer.type) 467 if pointer == self.sentinel: 468 return 469 yield pointer.cast(self.node_type.pointer()) 470 471 def children(self): 472 for k, v in enumerate(self._pointers()): 473 yield ('[%d]' % k, v.dereference()) 474 475 476pp = gdb.printing.RegexpCollectionPrettyPrinter("LLVMSupport") 477pp.add_printer('llvm::SmallString', '^llvm::SmallString<.*>$', SmallStringPrinter) 478pp.add_printer('llvm::StringRef', '^llvm::StringRef$', StringRefPrinter) 479pp.add_printer('llvm::SmallVectorImpl', '^llvm::SmallVector(Impl)?<.*>$', SmallVectorPrinter) 480pp.add_printer('llvm::ArrayRef', '^llvm::(Mutable)?ArrayRef<.*>$', ArrayRefPrinter) 481pp.add_printer('llvm::Expected', '^llvm::Expected<.*>$', ExpectedPrinter) 482pp.add_printer('llvm::Optional', '^llvm::Optional<.*>$', OptionalPrinter) 483pp.add_printer('llvm::DenseMap', '^llvm::DenseMap<.*>$', DenseMapPrinter) 484pp.add_printer('llvm::StringMap', '^llvm::StringMap<.*>$', StringMapPrinter) 485pp.add_printer('llvm::Twine', '^llvm::Twine$', TwinePrinter) 486pp.add_printer('llvm::PointerIntPair', '^llvm::PointerIntPair<.*>$', make_pointer_int_pair_printer) 487pp.add_printer('llvm::PointerUnion', '^llvm::PointerUnion<.*>$', make_pointer_union_printer) 488pp.add_printer('llvm::ilist_node', '^llvm::ilist_node<.*>$', IlistNodePrinter) 489pp.add_printer('llvm::iplist', '^llvm::iplist<.*>$', IlistPrinter) 490pp.add_printer('llvm::simple_ilist', '^llvm::simple_ilist<.*>$', IlistPrinter) 491gdb.printing.register_pretty_printer(gdb.current_objfile(), pp) 492