diff --git a/debug/gdb/printers.py b/debug/gdb/printers.py index 236708c0..1f77cb08 100644 --- a/debug/gdb/printers.py +++ b/debug/gdb/printers.py @@ -1,5 +1,8 @@ import re import gdb +import sys +import struct + class CoordPrinter(object): def __init__(self, val): @@ -64,13 +67,55 @@ class ViewPrinter(object): self.val["m_end"] ) +class EndianValuePrinter(object): + val: gdb.Type + + def __init__(self, val: gdb.Value): + self.val = val + # The type should be something like: + # "cruft::endian::value" + order_name = str(val.type.template_argument(0)) + + # Fuck knows how to use the GDB API. It's easier to just search for a + # differentiator that's unlikely to be present in anything else. + if '::BIG' in order_name: + self.order = '>' + elif '::LITTLE' in order_name: + self.order = '<' + else: + raise RuntimeError("Unknown endianness") + + # Find a format specifier for the size of the underlying value + self.size = { + 1: 'B', + 2: 'H', + 4: 'I', + 8: 'Q', + }[self.val.type.sizeof] + + def to_string (self): + # Construct format specifiers for converting to bytes, then from + # bytes, so that we can perform the byte reversal. + to_bytes = f"{self.order}{self.size}" + from_bytes = f"={self.size}" + + raw = int(self.val["raw"]) + native = struct.unpack(from_bytes, struct.pack(to_bytes, raw))[0] + + # Print the value and some annotations so that the user isn't misled + # about what value they're looking at. + return f"{native} (0x{native:x}, from 0x{raw:x})" + + def build_cruft_dict(): pretty_printers_dict[re.compile('^cruft::point.*$') ] = lambda val: CoordPrinter(val) pretty_printers_dict[re.compile('^cruft::vector.*$')] = lambda val: CoordPrinter(val) pretty_printers_dict[re.compile('^cruft::extent.*$')] = lambda val: CoordPrinter(val) pretty_printers_dict[re.compile('^cruft::colour.*$')] = lambda val: CoordPrinter(val) - pretty_printers_dict[re.compile('^cruft::view')] = lambda title, val: ViewPrinter(title, val) + pretty_printers_dict[re.compile('^cruft::view')] = lambda val: ViewPrinter(val) + + pretty_printers_dict[re.compile('^cruft::endian::value')] = lambda val: EndianValuePrinter(val) def lookup(val):