summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/loader/script_cache.py
diff options
context:
space:
mode:
Diffstat (limited to 'js/xpconnect/loader/script_cache.py')
-rwxr-xr-xjs/xpconnect/loader/script_cache.py92
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("")