jsop.py (1911B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 # You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 # Pretty-printers for JSOp and jsbytecode values. 6 7 import gdb 8 import gdb.types 9 10 import mozilla.prettyprinters 11 from mozilla.prettyprinters import pretty_printer, ptr_pretty_printer 12 13 # Forget any printers from previous loads of this module. 14 mozilla.prettyprinters.clear_module_printers(__name__) 15 16 17 class JSOpTypeCache: 18 # Cache information about the JSOp type for this objfile. 19 def __init__(self, cache): 20 self.tJSOp = gdb.lookup_type("JSOp") 21 22 @classmethod 23 def get_or_create(cls, cache): 24 if not cache.mod_JSOp: 25 cache.mod_JSOp = cls(cache) 26 return cache.mod_JSOp 27 28 29 @pretty_printer("JSOp") 30 class JSOp: 31 def __init__(self, value, cache): 32 self.value = value 33 self.cache = cache 34 self.jotc = JSOpTypeCache.get_or_create(cache) 35 36 def to_string(self): 37 # JSOp's storage type is |uint8_t|, but gdb uses a signed value. 38 # Manually convert it to an unsigned value. 39 # 40 # https://sourceware.org/bugzilla/show_bug.cgi?id=25325 41 idx = int(self.value.cast(self.jotc.tJSOp.target())) 42 assert 0 <= idx <= 255 43 fields = self.jotc.tJSOp.fields() 44 if idx < len(fields): 45 return fields[idx].name 46 return f"(JSOp) {idx:d}" 47 48 49 @ptr_pretty_printer("jsbytecode") 50 class JSBytecodePtr(mozilla.prettyprinters.Pointer): 51 def __init__(self, value, cache): 52 super().__init__(value, cache) 53 self.jotc = JSOpTypeCache.get_or_create(cache) 54 55 def to_string(self): 56 try: 57 opcode = str(self.value.dereference().cast(self.jotc.tJSOp)) 58 except Exception: 59 opcode = "bad pc" 60 return f"{self.value.cast(self.cache.void_ptr_t)} ({opcode})"