diff options
Diffstat (limited to 'js/xpconnect/loader/script_cache.py')
-rwxr-xr-x | js/xpconnect/loader/script_cache.py | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/js/xpconnect/loader/script_cache.py b/js/xpconnect/loader/script_cache.py new file mode 100755 index 0000000000..bd3a746fcf --- /dev/null +++ b/js/xpconnect/loader/script_cache.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import io +import os +import struct +import sys + +MAGIC = b"mozXDRcachev002\0" + + +def usage(): + print( + """Usage: script_cache.py <file.bin> ... + + Decodes and prints out the contents of a startup script cache file + (e.g., startupCache/scriptCache.bin) in human-readable form.""" + ) + + sys.exit(1) + + +class ProcessTypes: + Uninitialized = 0 + Parent = 1 + Web = 2 + Extension = 3 + Privileged = 4 + + def __init__(self, val): + self.val = val + + def __str__(self): + res = [] + if self.val & (1 << self.Uninitialized): + raise Exception("Uninitialized process type") + if self.val & (1 << self.Parent): + res.append("Parent") + if self.val & (1 << self.Web): + res.append("Web") + if self.val & (1 << self.Extension): + res.append("Extension") + if self.val & (1 << self.Privileged): + res.append("Privileged") + return "|".join(res) + + +class InputBuffer(object): + def __init__(self, data): + self.data = data + self.offset = 0 + + @property + def remaining(self): + return len(self.data) - self.offset + + def unpack(self, fmt): + res = struct.unpack_from(fmt, self.data, self.offset) + self.offset += struct.calcsize(fmt) + return res + + def unpack_str(self): + (size,) = self.unpack("<H") + res = self.data[self.offset : self.offset + size].decode("utf-8") + self.offset += size + return res + + +if len(sys.argv) < 2 or not os.path.exists(sys.argv[1]): + usage() + +for filename in sys.argv[1:]: + with io.open(filename, "rb") as f: + magic = f.read(len(MAGIC)) + if magic != MAGIC: + raise Exception("Bad magic number") + + (hdrSize,) = struct.unpack("<I", f.read(4)) + + hdr = InputBuffer(f.read(hdrSize)) + + i = 0 + while hdr.remaining: + i += 1 + print("{}: {}".format(i, hdr.unpack_str())) + print(" Key: {}".format(hdr.unpack_str())) + print(" Offset: {:>9,}".format(*hdr.unpack("<I"))) + print(" Size: {:>9,}".format(*hdr.unpack("<I"))) + print(" Processes: {}".format(ProcessTypes(*hdr.unpack("B")))) + print("") |