diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-07-20 08:39:49 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-07-20 20:01:06 +0200 |
| commit | 5839054e8591f60cbfdd3693398ecd5844530fe9 (patch) | |
| tree | efd4d79e0926916c0031d3e7f5277d25801a9f3e /lib/std/Build/Step/CheckObject.zig | |
| parent | 17255bed41a4b2c31a3f4342d51aa80a6f9d6b0b (diff) | |
| download | zig-5839054e8591f60cbfdd3693398ecd5844530fe9.tar.gz zig-5839054e8591f60cbfdd3693398ecd5844530fe9.zip | |
check-object: dump contents of .dynamic section
Diffstat (limited to 'lib/std/Build/Step/CheckObject.zig')
| -rw-r--r-- | lib/std/Build/Step/CheckObject.zig | 152 |
1 files changed, 150 insertions, 2 deletions
diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index 0c74a4e40e..5708328523 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -712,8 +712,7 @@ const ElfDumper = struct { fn getName(st: Symtab, index: usize) ?[]const u8 { const sym = st.get(index) orelse return null; - assert(sym.st_name < st.strings.len); - return mem.sliceTo(@ptrCast(st.strings.ptr + sym.st_name), 0); + return getString(st.strings, sym.st_name); } }; @@ -786,6 +785,7 @@ const ElfDumper = struct { try dumpHeader(ctx, writer); try dumpShdrs(ctx, writer); try dumpPhdrs(ctx, writer); + try dumpDynamic(ctx, writer); return output.toOwnedSlice(); } @@ -803,6 +803,17 @@ const ElfDumper = struct { return ctx.data[shdr.sh_offset..][0..shdr.sh_size]; } + fn getSectionByName(ctx: Context, name: []const u8) ?usize { + for (0..ctx.shdrs.len) |shndx| { + if (mem.eql(u8, getSectionName(ctx, shndx), name)) return shndx; + } else return null; + } + + fn getString(strtab: []const u8, off: u32) []const u8 { + assert(off < strtab.len); + return mem.sliceTo(@as([*:0]const u8, @ptrCast(strtab.ptr + off)), 0); + } + fn dumpHeader(ctx: Context, writer: anytype) !void { try writer.writeAll("header\n"); try writer.print("type {s}\n", .{@tagName(ctx.hdr.e_type)}); @@ -824,6 +835,143 @@ const ElfDumper = struct { } } + fn dumpDynamic(ctx: Context, writer: anytype) !void { + const shndx = getSectionByName(ctx, ".dynamic") orelse return; + const shdr = ctx.shdrs[shndx]; + const strtab = getSectionContents(ctx, shdr.sh_link); + const data = getSectionContents(ctx, shndx); + const nentries = @divExact(data.len, @sizeOf(elf.Elf64_Dyn)); + const entries = @as([*]align(1) const elf.Elf64_Dyn, @ptrCast(data.ptr))[0..nentries]; + + for (entries) |entry| { + const key = @as(u64, @bitCast(entry.d_tag)); + const value = entry.d_val; + + const key_str = switch (key) { + elf.DT_NEEDED => "NEEDED", + elf.DT_SONAME => "SONAME", + elf.DT_INIT_ARRAY => "INIT_ARRAY", + elf.DT_INIT_ARRAYSZ => "INIT_ARRAYSZ", + elf.DT_FINI_ARRAY => "FINI_ARRAY", + elf.DT_FINI_ARRAYSZ => "FINI_ARRAYSZ", + elf.DT_HASH => "HASH", + elf.DT_GNU_HASH => "GNU_HASH", + elf.DT_STRTAB => "STRTAB", + elf.DT_SYMTAB => "SYMTAB", + elf.DT_STRSZ => "STRSZ", + elf.DT_SYMENT => "SYMENT", + elf.DT_PLTGOT => "PLTGOT", + elf.DT_PLTRELSZ => "PLTRELSZ", + elf.DT_PLTREL => "PLTREL", + elf.DT_JMPREL => "JMPREL", + elf.DT_RELA => "RELA", + elf.DT_RELASZ => "RELASZ", + elf.DT_RELAENT => "RELAENT", + elf.DT_VERDEF => "VERDEF", + elf.DT_VERDEFNUM => "VERDEFNUM", + elf.DT_FLAGS => "FLAGS", + elf.DT_FLAGS_1 => "FLAGS_1", + elf.DT_VERNEED => "VERNEED", + elf.DT_VERNEEDNUM => "VERNEEDNUM", + elf.DT_VERSYM => "VERSYM", + elf.DT_RELACOUNT => "RELACOUNT", + elf.DT_RPATH => "RPATH", + elf.DT_RUNPATH => "RUNPATH", + elf.DT_INIT => "INIT", + elf.DT_FINI => "FINI", + elf.DT_NULL => "NULL", + else => "UNKNOWN", + }; + try writer.print("{s}", .{key_str}); + + switch (key) { + elf.DT_NEEDED, + elf.DT_SONAME, + elf.DT_RPATH, + elf.DT_RUNPATH, + => { + const name = getString(strtab, @intCast(value)); + try writer.print(" {s}", .{name}); + }, + + elf.DT_INIT_ARRAY, + elf.DT_FINI_ARRAY, + elf.DT_HASH, + elf.DT_GNU_HASH, + elf.DT_STRTAB, + elf.DT_SYMTAB, + elf.DT_PLTGOT, + elf.DT_JMPREL, + elf.DT_RELA, + elf.DT_VERDEF, + elf.DT_VERNEED, + elf.DT_VERSYM, + elf.DT_INIT, + elf.DT_FINI, + elf.DT_NULL, + => try writer.print(" {x}", .{value}), + + elf.DT_INIT_ARRAYSZ, + elf.DT_FINI_ARRAYSZ, + elf.DT_STRSZ, + elf.DT_SYMENT, + elf.DT_PLTRELSZ, + elf.DT_RELASZ, + elf.DT_RELAENT, + elf.DT_RELACOUNT, + => try writer.print(" {d}", .{value}), + + elf.DT_PLTREL => try writer.writeAll(switch (value) { + elf.DT_REL => " REL", + elf.DT_RELA => " RELA", + else => " UNKNOWN", + }), + + elf.DT_FLAGS => if (value > 0) { + if (value & elf.DF_ORIGIN != 0) try writer.writeAll(" ORIGIN"); + if (value & elf.DF_SYMBOLIC != 0) try writer.writeAll(" SYMBOLIC"); + if (value & elf.DF_TEXTREL != 0) try writer.writeAll(" TEXTREL"); + if (value & elf.DF_BIND_NOW != 0) try writer.writeAll(" BIND_NOW"); + if (value & elf.DF_STATIC_TLS != 0) try writer.writeAll(" STATIC_TLS"); + }, + + elf.DT_FLAGS_1 => if (value > 0) { + if (value & elf.DF_1_NOW != 0) try writer.writeAll(" NOW"); + if (value & elf.DF_1_GLOBAL != 0) try writer.writeAll(" GLOBAL"); + if (value & elf.DF_1_GROUP != 0) try writer.writeAll(" GROUP"); + if (value & elf.DF_1_NODELETE != 0) try writer.writeAll(" NODELETE"); + if (value & elf.DF_1_LOADFLTR != 0) try writer.writeAll(" LOADFLTR"); + if (value & elf.DF_1_INITFIRST != 0) try writer.writeAll(" INITFIRST"); + if (value & elf.DF_1_NOOPEN != 0) try writer.writeAll(" NOOPEN"); + if (value & elf.DF_1_ORIGIN != 0) try writer.writeAll(" ORIGIN"); + if (value & elf.DF_1_DIRECT != 0) try writer.writeAll(" DIRECT"); + if (value & elf.DF_1_TRANS != 0) try writer.writeAll(" TRANS"); + if (value & elf.DF_1_INTERPOSE != 0) try writer.writeAll(" INTERPOSE"); + if (value & elf.DF_1_NODEFLIB != 0) try writer.writeAll(" NODEFLIB"); + if (value & elf.DF_1_NODUMP != 0) try writer.writeAll(" NODUMP"); + if (value & elf.DF_1_CONFALT != 0) try writer.writeAll(" CONFALT"); + if (value & elf.DF_1_ENDFILTEE != 0) try writer.writeAll(" ENDFILTEE"); + if (value & elf.DF_1_DISPRELDNE != 0) try writer.writeAll(" DISPRELDNE"); + if (value & elf.DF_1_DISPRELPND != 0) try writer.writeAll(" DISPRELPND"); + if (value & elf.DF_1_NODIRECT != 0) try writer.writeAll(" NODIRECT"); + if (value & elf.DF_1_IGNMULDEF != 0) try writer.writeAll(" IGNMULDEF"); + if (value & elf.DF_1_NOKSYMS != 0) try writer.writeAll(" NOKSYMS"); + if (value & elf.DF_1_NOHDR != 0) try writer.writeAll(" NOHDR"); + if (value & elf.DF_1_EDITED != 0) try writer.writeAll(" EDITED"); + if (value & elf.DF_1_NORELOC != 0) try writer.writeAll(" NORELOC"); + if (value & elf.DF_1_SYMINTPOSE != 0) try writer.writeAll(" SYMINTPOSE"); + if (value & elf.DF_1_GLOBAUDIT != 0) try writer.writeAll(" GLOBAUDIT"); + if (value & elf.DF_1_SINGLETON != 0) try writer.writeAll(" SINGLETON"); + if (value & elf.DF_1_STUB != 0) try writer.writeAll(" STUB"); + if (value & elf.DF_1_PIE != 0) try writer.writeAll(" PIE"); + }, + + else => try writer.print(" {x}", .{value}), + } + try writer.writeByte('\n'); + } + } + fn fmtShType(sh_type: u32) std.fmt.Formatter(formatShType) { return .{ .data = sh_type }; } |
