tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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})"