tor-browser

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

Interpreter.py (3568B)


      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 InterpreterRegs.
      6 
      7 import gdb
      8 
      9 from mozilla import prettyprinters
     10 
     11 prettyprinters.clear_module_printers(__name__)
     12 
     13 from mozilla.prettyprinters import pretty_printer
     14 
     15 
     16 class InterpreterTypeCache:
     17    # Cache information about the Interpreter types for this objfile.
     18    def __init__(self):
     19        self.tValue = gdb.lookup_type("JS::Value")
     20        self.tJSOp = gdb.lookup_type("JSOp")
     21        try:
     22            self.tScriptFrameIterData = gdb.lookup_type("js::ScriptFrameIter::Data")
     23        except gdb.error:
     24            # Work around problem with gcc optimized debuginfo where it doesn't
     25            # seem to be able to see that ScriptFrameIter inherits the
     26            # FrameIter::Data type.
     27            self.tScriptFrameIterData = gdb.lookup_type("js::FrameIter::Data")
     28        self.tInterpreterFrame = gdb.lookup_type("js::InterpreterFrame")
     29        self.tBaselineFrame = gdb.lookup_type("js::jit::BaselineFrame")
     30        self.tRematerializedFrame = gdb.lookup_type("js::jit::RematerializedFrame")
     31        self.tDebugFrame = gdb.lookup_type("js::wasm::DebugFrame")
     32 
     33 
     34 @pretty_printer("js::InterpreterRegs")
     35 class InterpreterRegs:
     36    def __init__(self, value, cache):
     37        self.value = value
     38        self.cache = cache
     39        if not cache.mod_Interpreter:
     40            cache.mod_Interpreter = InterpreterTypeCache()
     41        self.itc = cache.mod_Interpreter
     42 
     43    # There's basically no way to co-operate with 'set print pretty' (how would
     44    # you get the current level of indentation?), so we don't even bother
     45    # trying. No 'children', just 'to_string'.
     46    def to_string(self):
     47        fp_ = "fp_ = {}".format(self.value["fp_"])
     48        slots = (self.value["fp_"] + 1).cast(self.itc.tValue.pointer())
     49        sp = "sp = fp_.slots() + {}".format(self.value["sp"] - slots)
     50        pc = "pc = {}".format(self.value["pc"])
     51        return f"{{ {fp_}, {sp}, {pc} }}"
     52 
     53 
     54 @pretty_printer("js::AbstractFramePtr")
     55 class AbstractFramePtr:
     56    Tag_InterpreterFrame = 0x0
     57    Tag_BaselineFrame = 0x1
     58    Tag_RematerializedFrame = 0x2
     59    Tag_WasmDebugFrame = 0x3
     60    TagMask = 0x3
     61 
     62    def __init__(self, value, cache):
     63        self.value = value
     64        self.cache = cache
     65        if not cache.mod_Interpreter:
     66            cache.mod_Interpreter = InterpreterTypeCache()
     67        self.itc = cache.mod_Interpreter
     68 
     69    def to_string(self):
     70        ptr = self.value["ptr_"]
     71        tag = ptr & AbstractFramePtr.TagMask
     72        ptr = ptr & ~AbstractFramePtr.TagMask
     73        if tag == AbstractFramePtr.Tag_InterpreterFrame:
     74            label = "js::InterpreterFrame"
     75            ptr = ptr.cast(self.itc.tInterpreterFrame.pointer())
     76        if tag == AbstractFramePtr.Tag_BaselineFrame:
     77            label = "js::jit::BaselineFrame"
     78            ptr = ptr.cast(self.itc.tBaselineFrame.pointer())
     79        if tag == AbstractFramePtr.Tag_RematerializedFrame:
     80            label = "js::jit::RematerializedFrame"
     81            ptr = ptr.cast(self.itc.tRematerializedFrame.pointer())
     82        if tag == AbstractFramePtr.Tag_WasmDebugFrame:
     83            label = "js::wasm::DebugFrame"
     84            ptr = ptr.cast(self.itc.tDebugFrame.pointer())
     85        return f"AbstractFramePtr (({label} *) {ptr})"
     86 
     87    # Provide the ptr_ field as a child, so it prints after the pretty string
     88    # provided above.
     89    def children(self):
     90        yield ("ptr_", self.value["ptr_"])