diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-05-06 06:34:29 +0000 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-05-06 06:34:29 +0000 |
| commit | 858c177d1b96ad6306edcda744e49d0cee906aff (patch) | |
| tree | 7a0d1a867dbd96de53a0e8eca2b4e1f7c7eb6e19 /scripts/gdb | |
| parent | 1e9daa3ccda0a39a8b260649ddc3c75f95a88bdf (diff) | |
| download | kernel-858c177d1b96ad6306edcda744e49d0cee906aff.tar.xz kernel-858c177d1b96ad6306edcda744e49d0cee906aff.zip | |
debug: refactor dump_mb2i tool
Diffstat (limited to 'scripts/gdb')
| -rw-r--r-- | scripts/gdb/teachos/dump_mb2i.py | 199 |
1 files changed, 135 insertions, 64 deletions
diff --git a/scripts/gdb/teachos/dump_mb2i.py b/scripts/gdb/teachos/dump_mb2i.py index 41a2932..06f4531 100644 --- a/scripts/gdb/teachos/dump_mb2i.py +++ b/scripts/gdb/teachos/dump_mb2i.py @@ -1,30 +1,72 @@ import gdb import struct +from enum import IntEnum + + +class TagType(IntEnum): + END = 0 + CMDLINE = 1 + BOOT_LOADER_NAME = 2 + MODULE = 3 + BASIC_MEMINFO = 4 + BOOTDEV = 5 + MMAP = 6 + VBE = 7 + FRAMEBUFFER = 8 + ELF_SECTIONS = 9 + APM = 10 + EFI32_SYSTEM_TABLE_POINTER = 11 + EFI64_SYSTEM_TABLE_POINTER = 12 + SMBIOS_TABLES = 13 + ACPI_OLD = 14 + ACPI_NEW = 15 + NETWORKING = 16 + EFI_MEMORY_MAP = 17 + EFI_BOOT_SERVICES_NOT_TERMINATED = 18 + EFI32_IMAGE_HANDLE_POINTER = 19 + EFI64_IMAGE_HANDLE_POINTER = 20 + LOAD_BASE_ADDR = 21 + + +class MemoryType(IntEnum): + AVAILABLE = 1 + RESERVED = 2 + ACPI_RECLAIM = 3 + NVS = 4 + BAD = 5 TAG_NAMES = { - 0: "End of Tags", - 1: "Boot Command Line", - 2: "Boot Loader Name", - 3: "Boot Module", - 4: "Basic Memory Information", - 5: "BIOS Boot Device", - 6: "Memory Map", - 7: "VBE Info", - 8: "Framebuffer Info", - 9: "ELF Symbols", - 10: "APM Table", - 14: "ACPI old RSDP (1.0)", - 15: "ACPI new RSDP (2.0+)", - 21: "Image Load Base Physical Address", + TagType.END: "End of Tags", + TagType.CMDLINE: "Boot Command Line", + TagType.BOOT_LOADER_NAME: "Boot Loader Name", + TagType.MODULE: "Boot Module", + TagType.BASIC_MEMINFO: "Basic Memory Information", + TagType.BOOTDEV: "BIOS Boot Device", + TagType.MMAP: "Memory Map", + TagType.VBE: "VBE Info", + TagType.FRAMEBUFFER: "Framebuffer Info", + TagType.ELF_SECTIONS: "ELF Symbols", + TagType.APM: "APM Table", + TagType.EFI32_SYSTEM_TABLE_POINTER: "EFI 32-bit System Table Pointer", + TagType.EFI64_SYSTEM_TABLE_POINTER: "EFI 64-bit System Table Pointer", + TagType.SMBIOS_TABLES: "SMBIOS Tables", + TagType.ACPI_OLD: "ACPI old RSDP (1.0)", + TagType.ACPI_NEW: "ACPI new RSDP (2.0+)", + TagType.NETWORKING: "Networking Information", + TagType.EFI_MEMORY_MAP: "EFI Memory Map", + TagType.EFI_BOOT_SERVICES_NOT_TERMINATED: "EFI Boot Services Not Terminated", + TagType.EFI32_IMAGE_HANDLE_POINTER: "EFI 32-bit Image Handle Pointer", + TagType.EFI64_IMAGE_HANDLE_POINTER: "EFI 64-bit Image Handle Pointer", + TagType.LOAD_BASE_ADDR: "Image Load Base Physical Address", } MEMORY_TYPES = { - 1: "Available", - 2: "Reserved", - 3: "ACPI Reclaim", - 4: "Non-volatile storage", - 5: "Bad Memory", + MemoryType.AVAILABLE: "Available", + MemoryType.RESERVED: "Reserved", + MemoryType.ACPI_RECLAIM: "ACPI Reclaim", + MemoryType.NVS: "Non-volatile storage", + MemoryType.BAD: "Bad Memory", } INDENT = f"{' '*11}" @@ -64,7 +106,9 @@ class DumpMB2I(gdb.Command): return if total_size < 8 or total_size > 1024 * 1024: - gdb.write("Warning: suspicious total size ({total_size} bytes). Aborting.") + gdb.write( + f"Warning: suspicious total size ({total_size} bytes). Aborting.\n" + ) return gdb.write(f"+{'-'*70}+\n") @@ -86,11 +130,11 @@ class DumpMB2I(gdb.Command): ) break - self._print_tag(inferior, tag_address, tag_type, tag_size) - - if tag_type == 0 and tag_size == 0: + if tag_type == TagType.END and tag_size == 8: break + self._print_tag(inferior, tag_address, tag_type, tag_size) + offset += (tag_size + 7) & ~7 def _format_size(self, size): @@ -104,50 +148,77 @@ class DumpMB2I(gdb.Command): def _print_tag(self, inferior, tag_address, tag_type, tag_size): name = TAG_NAMES.get(tag_type, f"Unknown Tag") - gdb.write(f"[Tag {tag_type:#04x}] {name} (size: {self._format_size(tag_size)})\n") + gdb.write( + f"[Tag {tag_type:#04x}] {name} (size: {self._format_size(tag_size)})\n" + ) - if tag_size <= 8 and tag_type != 0: + if tag_size <= 8 and tag_type != TagType.END: return try: - if tag_type in (1, 2): - data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() - text = data.split(b"\x00")[0].decode("ascii", "replace") - gdb.write(f'{INDENT}"{text}"\n') - elif tag_type == 3: - data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() - start, end = struct.unpack_from("<II", data) - string = data[8:].split(b"\x00")[0].decode("ascii", "replace") - gdb.write( - f"{INDENT}start: {start:#010x} | end: {end:#010x} | size: {self._format_size(end - start)}\n" - ) - if string: - gdb.write(f'{INDENT}string: "{string}"\n') - elif tag_type == 5: - data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() - device, partition, sub_partition = struct.unpack_from("<III", data) - gdb.write( - f"{INDENT}device: {device:#04x} | partition: {partition:#06x} | sub-partion: {sub_partition:#06x}\n" - ) - elif tag_type == 6: - data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() - entry_size, entry_version = struct.unpack_from("<II", data) - if entry_size < 24: - return - num_entries = (tag_size - 16) // entry_size - for i in range(num_entries): - entry_offset = 8 + i * entry_size - base, length, memory_type = struct.unpack_from( - "<QQI", data, entry_offset - ) - type_string = MEMORY_TYPES.get(memory_type, "Unknown") - gdb.write( - f"{INDENT}[{i:02d}] {base:#018x} - {base + length:#018x} | {self._format_size(length)} | type: {type_string}\n" - ) - elif tag_type == 21: - data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() - base = struct.unpack("<I", data)[0] - gdb.write(f"{INDENT}address: {base:#010x}\n") + data = inferior.read_memory(tag_address + 8, tag_size - 8).tobytes() + + handlers = { + TagType.CMDLINE: self._write_string_tag, + TagType.BOOT_LOADER_NAME: self._write_string_tag, + TagType.MODULE: self._write_module_tag, + TagType.BASIC_MEMINFO: self._write_basic_memory_info_tag, + TagType.BOOTDEV: self._write_boot_device_tag, + TagType.MMAP: self._write_memory_map_tag, + TagType.LOAD_BASE_ADDR: self._write_image_load_base_physical_address_tag, + TagType.FRAMEBUFFER: self._write_framebuffer_info_tag, + } + + handler = handlers.get(tag_type) + if handler: + handler(data) except Exception as e: - gdb.write(f"{INDENT}<failed to decode tag: {e}>\n") + gdb.write( + f"{INDENT}<failed to decode tag: {e} ({tag_type:#04x} | {tag_size:#06x})>\n" + ) + + def _write_string_tag(self, data): + text = data.split(b"\x00")[0].decode("ascii", "replace") + gdb.write(f'{INDENT}"{text}"\n') + + def _write_module_tag(self, data): + start, end = struct.unpack_from("<II", data) + string = data[8:].split(b"\x00")[0].decode("ascii", "replace") + gdb.write( + f"{INDENT}start: {start:#010x} | end: {end:#010x} | size: {self._format_size(end - start)}\n" + ) + if string: + gdb.write(f'{INDENT}string: "{string}"\n') + + def _write_basic_memory_info_tag(self, data): + lower, upper = struct.unpack_from("<II", data) + gdb.write( + f"{INDENT}upper memory: {self._format_size(upper * 1024)} | lower memory: {self._format_size(lower * 1024)}\n" + ) + + def _write_boot_device_tag(self, data): + device, partition, sub_partition = struct.unpack_from("<III", data) + gdb.write( + f"{INDENT}device: {device:#04x} | partition: {partition:#06x} | sub-partition: {sub_partition:#06x}\n" + ) + + def _write_memory_map_tag(self, data): + entry_size, entry_version = struct.unpack_from("<II", data) + if entry_size < 24: + return + num_entries = (len(data) - 8) // entry_size + for i in range(num_entries): + entry_offset = 8 + i * entry_size + base, length, memory_type = struct.unpack_from("<QQI", data, entry_offset) + type_string = MEMORY_TYPES.get(memory_type, "Unknown") + gdb.write( + f"{INDENT}[{i:02d}] {base:#018x} - {base + length:#018x} | {self._format_size(length)} | type: {type_string}\n" + ) + + def _write_image_load_base_physical_address_tag(self, data): + base = struct.unpack("<I", data)[0] + gdb.write(f"{INDENT}address: {base:#010x}\n") + + def _write_framebuffer_info_tag(self, data): + pass |
