diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-12-13 11:38:57 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-12-13 11:38:57 +0100 |
| commit | 92cca7fbf155602584dee294d04ee0b33135a25e (patch) | |
| tree | 7025cc0d0469a09454909d229415559c857eaf1e /lib/std/Build/Step/CheckObject.zig | |
| parent | 2492488501ee04e132cb552fd11a3025990ea047 (diff) | |
| download | zig-92cca7fbf155602584dee294d04ee0b33135a25e.tar.gz zig-92cca7fbf155602584dee294d04ee0b33135a25e.zip | |
lib/std/Build/CheckObject: implement for ELF
Diffstat (limited to 'lib/std/Build/Step/CheckObject.zig')
| -rw-r--r-- | lib/std/Build/Step/CheckObject.zig | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index 7195b92635..f837f509dd 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -1554,15 +1554,14 @@ const ElfDumper = struct { const archive_symtab_label = "archive symbol table"; fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 { - _ = kind; - const gpa = step.owner.allocator; - return parseAndDumpArchive(gpa, bytes) catch |err| switch (err) { - error.InvalidArchiveMagicNumber => try parseAndDumpObject(gpa, bytes), + return parseAndDumpArchive(step, kind, bytes) catch |err| switch (err) { + error.InvalidArchiveMagicNumber => try parseAndDumpObject(step, kind, bytes), else => |e| return e, }; } - fn parseAndDumpArchive(gpa: Allocator, bytes: []const u8) ![]const u8 { + fn parseAndDumpArchive(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 { + const gpa = step.owner.allocator; var stream = std.io.fixedBufferStream(bytes); const reader = stream.reader(); @@ -1623,8 +1622,15 @@ const ElfDumper = struct { var output = std.ArrayList(u8).init(gpa); const writer = output.writer(); - try ctx.dumpSymtab(writer); - try ctx.dumpObjects(writer); + switch (kind) { + .archive_symtab => if (ctx.symtab.items.len > 0) { + try ctx.dumpSymtab(writer); + } else return step.fail("no archive symbol table found", .{}), + + else => if (ctx.objects.items.len > 0) { + try ctx.dumpObjects(step, kind, writer); + } else return step.fail("empty archive", .{}), + } return output.toOwnedSlice(); } @@ -1666,8 +1672,6 @@ const ElfDumper = struct { } fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void { - if (ctx.symtab.items.len == 0) return; - var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa); defer files.deinit(); try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len)); @@ -1701,10 +1705,10 @@ const ElfDumper = struct { } } - fn dumpObjects(ctx: ArchiveContext, writer: anytype) !void { + fn dumpObjects(ctx: ArchiveContext, step: *Step, kind: Check.Kind, writer: anytype) !void { for (ctx.objects.items) |object| { try writer.print("object {s}\n", .{object.name}); - const output = try parseAndDumpObject(ctx.gpa, ctx.data[object.off..][0..object.len]); + const output = try parseAndDumpObject(step, kind, ctx.data[object.off..][0..object.len]); defer ctx.gpa.free(output); try writer.print("{s}\n", .{output}); } @@ -1722,7 +1726,8 @@ const ElfDumper = struct { }; }; - fn parseAndDumpObject(gpa: Allocator, bytes: []const u8) ![]const u8 { + fn parseAndDumpObject(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 { + const gpa = step.owner.allocator; var stream = std.io.fixedBufferStream(bytes); const reader = stream.reader(); @@ -1774,12 +1779,27 @@ const ElfDumper = struct { var output = std.ArrayList(u8).init(gpa); const writer = output.writer(); - try ctx.dumpHeader(writer); - try ctx.dumpShdrs(writer); - try ctx.dumpPhdrs(writer); - try ctx.dumpDynamicSection(writer); - try ctx.dumpSymtab(.symtab, writer); - try ctx.dumpSymtab(.dysymtab, writer); + switch (kind) { + .headers => { + try ctx.dumpHeader(writer); + try ctx.dumpShdrs(writer); + try ctx.dumpPhdrs(writer); + }, + + .symtab => if (ctx.symtab.symbols.len > 0) { + try ctx.dumpSymtab(.symtab, writer); + } else return step.fail("no symbol table found", .{}), + + .dynamic_symtab => if (ctx.dysymtab.symbols.len > 0) { + try ctx.dumpSymtab(.dysymtab, writer); + } else return step.fail("no dynamic symbol table found", .{}), + + .dynamic_section => if (ctx.getSectionByName(".dynamic")) |shndx| { + try ctx.dumpDynamicSection(shndx, writer); + } else return step.fail("no .dynamic section found", .{}), + + else => return step.fail("invalid check kind for ELF file format: {s}", .{@tagName(kind)}), + } return output.toOwnedSlice(); } @@ -1791,8 +1811,8 @@ const ElfDumper = struct { shdrs: []align(1) const elf.Elf64_Shdr, phdrs: []align(1) const elf.Elf64_Phdr, shstrtab: []const u8, - symtab: ?Symtab = null, - dysymtab: ?Symtab = null, + symtab: Symtab = .{}, + dysymtab: Symtab = .{}, fn dumpHeader(ctx: ObjectContext, writer: anytype) !void { try writer.writeAll("header\n"); @@ -1856,8 +1876,7 @@ const ElfDumper = struct { } } - fn dumpDynamicSection(ctx: ObjectContext, writer: anytype) !void { - const shndx = ctx.getSectionByName(".dynamic") orelse return; + fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void { const shdr = ctx.shdrs[shndx]; const strtab = ctx.getSectionContents(shdr.sh_link); const data = ctx.getSectionContents(shndx); @@ -2097,8 +2116,8 @@ const ElfDumper = struct { }; const Symtab = struct { - symbols: []align(1) const elf.Elf64_Sym, - strings: []const u8, + symbols: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{}, + strings: []const u8 = &[0]u8{}, fn get(st: Symtab, index: usize) ?elf.Elf64_Sym { if (index >= st.symbols.len) return null; |
