Commit 77026c67a4

Jakub Konka <kubkon@jakubkonka.com>
2023-07-13 21:27:18
check-object: dump info on PHDRs
1 parent 33154b5
Changed files (1)
lib
std
Build
lib/std/Build/Step/CheckObject.zig
@@ -785,6 +785,7 @@ const ElfDumper = struct {
 
         try dumpHeader(ctx, writer);
         try dumpShdrs(ctx, writer);
+        try dumpPhdrs(ctx, writer);
 
         return output.toOwnedSlice();
     }
@@ -814,52 +815,114 @@ const ElfDumper = struct {
         for (ctx.shdrs, 0..) |shdr, shndx| {
             try writer.print("shdr {d}\n", .{shndx});
             try writer.print("name {s}\n", .{getSectionName(ctx, shndx)});
-            try writer.print("type {s}\n", .{try fmtShType(ctx.gpa, shdr.sh_type)});
+            try writer.print("type {s}\n", .{fmtShType(shdr.sh_type)});
             try writer.print("addr {x}\n", .{shdr.sh_addr});
             try writer.print("offset {x}\n", .{shdr.sh_offset});
             try writer.print("size {x}\n", .{shdr.sh_size});
             try writer.print("addralign {x}\n", .{shdr.sh_addralign});
+            // TODO dump formatted sh_flags
         }
     }
 
-    fn fmtShType(gpa: Allocator, sh_type: u32) ![]const u8 {
-        return switch (sh_type) {
-            elf.SHT_NULL => "NULL",
-            elf.SHT_PROGBITS => "PROGBITS",
-            elf.SHT_SYMTAB => "SYMTAB",
-            elf.SHT_STRTAB => "STRTAB",
-            elf.SHT_RELA => "RELA",
-            elf.SHT_HASH => "HASH",
-            elf.SHT_DYNAMIC => "DYNAMIC",
-            elf.SHT_NOTE => "NOTE",
-            elf.SHT_NOBITS => "NOBITS",
-            elf.SHT_REL => "REL",
-            elf.SHT_SHLIB => "SHLIB",
-            elf.SHT_DYNSYM => "DYNSYM",
-            elf.SHT_INIT_ARRAY => "INIT_ARRAY",
-            elf.SHT_FINI_ARRAY => "FINI_ARRAY",
-            elf.SHT_PREINIT_ARRAY => "PREINIT_ARRAY",
-            elf.SHT_GROUP => "GROUP",
-            elf.SHT_SYMTAB_SHNDX => "SYMTAB_SHNDX",
-            elf.SHT_X86_64_UNWIND => "X86_64_UNWIND",
-            elf.SHT_LLVM_ADDRSIG => "LLVM_ADDRSIG",
-            elf.SHT_GNU_HASH => "GNU_HASH",
-            elf.SHT_GNU_VERDEF => "VERDEF",
-            elf.SHT_GNU_VERNEED => "VERNEED",
-            elf.SHT_GNU_VERSYM => "VERSYM",
-            else => |sht| blk: {
-                if (elf.SHT_LOOS <= sht and sht < elf.SHT_HIOS) {
-                    break :blk try std.fmt.allocPrint(gpa, "LOOS+0x{x}", .{sht - elf.SHT_LOOS});
-                }
-                if (elf.SHT_LOPROC <= sht and sht < elf.SHT_HIPROC) {
-                    break :blk try std.fmt.allocPrint(gpa, "LOPROC+0x{x}", .{sht - elf.SHT_LOPROC});
-                }
-                if (elf.SHT_LOUSER <= sht and sht < elf.SHT_HIUSER) {
-                    break :blk try std.fmt.allocPrint(gpa, "LOUSER+0x{x}", .{sht - elf.SHT_LOUSER});
-                }
-                break :blk "UNKNOWN";
-            },
-        };
+    fn fmtShType(sh_type: u32) std.fmt.Formatter(formatShType) {
+        return .{ .data = sh_type };
+    }
+
+    fn formatShType(
+        sh_type: u32,
+        comptime unused_fmt_string: []const u8,
+        options: std.fmt.FormatOptions,
+        writer: anytype,
+    ) !void {
+        _ = unused_fmt_string;
+        _ = options;
+        if (elf.SHT_LOOS <= sh_type and sh_type < elf.SHT_HIOS) {
+            try writer.print("LOOS+0x{x}", .{sh_type - elf.SHT_LOOS});
+        } else if (elf.SHT_LOPROC <= sh_type and sh_type < elf.SHT_HIPROC) {
+            try writer.print("LOPROC+0x{x}", .{sh_type - elf.SHT_LOPROC});
+        } else if (elf.SHT_LOUSER <= sh_type and sh_type < elf.SHT_HIUSER) {
+            try writer.print("LOUSER+0x{x}", .{sh_type - elf.SHT_LOUSER});
+        } else {
+            const name = switch (sh_type) {
+                elf.SHT_NULL => "NULL",
+                elf.SHT_PROGBITS => "PROGBITS",
+                elf.SHT_SYMTAB => "SYMTAB",
+                elf.SHT_STRTAB => "STRTAB",
+                elf.SHT_RELA => "RELA",
+                elf.SHT_HASH => "HASH",
+                elf.SHT_DYNAMIC => "DYNAMIC",
+                elf.SHT_NOTE => "NOTE",
+                elf.SHT_NOBITS => "NOBITS",
+                elf.SHT_REL => "REL",
+                elf.SHT_SHLIB => "SHLIB",
+                elf.SHT_DYNSYM => "DYNSYM",
+                elf.SHT_INIT_ARRAY => "INIT_ARRAY",
+                elf.SHT_FINI_ARRAY => "FINI_ARRAY",
+                elf.SHT_PREINIT_ARRAY => "PREINIT_ARRAY",
+                elf.SHT_GROUP => "GROUP",
+                elf.SHT_SYMTAB_SHNDX => "SYMTAB_SHNDX",
+                elf.SHT_X86_64_UNWIND => "X86_64_UNWIND",
+                elf.SHT_LLVM_ADDRSIG => "LLVM_ADDRSIG",
+                elf.SHT_GNU_HASH => "GNU_HASH",
+                elf.SHT_GNU_VERDEF => "VERDEF",
+                elf.SHT_GNU_VERNEED => "VERNEED",
+                elf.SHT_GNU_VERSYM => "VERSYM",
+                else => "UNKNOWN",
+            };
+            try writer.writeAll(name);
+        }
+    }
+
+    fn dumpPhdrs(ctx: Context, writer: anytype) !void {
+        if (ctx.phdrs.len == 0) return;
+
+        for (ctx.phdrs, 0..) |phdr, phndx| {
+            try writer.print("phdr {d}\n", .{phndx});
+            try writer.print("type {s}\n", .{fmtPhType(phdr.p_type)});
+            try writer.print("vaddr {x}\n", .{phdr.p_vaddr});
+            try writer.print("paddr {x}\n", .{phdr.p_paddr});
+            try writer.print("offset {x}\n", .{phdr.p_offset});
+            try writer.print("memsz {x}\n", .{phdr.p_memsz});
+            try writer.print("filesz {x}\n", .{phdr.p_filesz});
+            try writer.print("align {x}\n", .{phdr.p_align});
+            // TODO dump formatted p_flags
+        }
+    }
+
+    fn fmtPhType(ph_type: u32) std.fmt.Formatter(formatPhType) {
+        return .{ .data = ph_type };
+    }
+
+    fn formatPhType(
+        ph_type: u32,
+        comptime unused_fmt_string: []const u8,
+        options: std.fmt.FormatOptions,
+        writer: anytype,
+    ) !void {
+        _ = unused_fmt_string;
+        _ = options;
+        if (elf.PT_LOOS <= ph_type and ph_type < elf.PT_HIOS) {
+            try writer.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS});
+        } else if (elf.PT_LOPROC <= ph_type and ph_type < elf.PT_HIPROC) {
+            try writer.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC});
+        } else {
+            const p_type = switch (ph_type) {
+                elf.PT_NULL => "NULL",
+                elf.PT_LOAD => "LOAD",
+                elf.PT_DYNAMIC => "DYNAMIC",
+                elf.PT_INTERP => "INTERP",
+                elf.PT_NOTE => "NOTE",
+                elf.PT_SHLIB => "SHLIB",
+                elf.PT_PHDR => "PHDR",
+                elf.PT_TLS => "TLS",
+                elf.PT_NUM => "NUM",
+                elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME",
+                elf.PT_GNU_STACK => "GNU_STACK",
+                elf.PT_GNU_RELRO => "GNU_RELRO",
+                else => "UNKNOWN",
+            };
+            try writer.writeAll(p_type);
+        }
     }
 };