authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-13 11:38:57+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-12-13 11:38:57+01:00
log92cca7fbf155602584dee294d04ee0b33135a25e
tree7025cc0d0469a09454909d229415559c857eaf1e
parent2492488501ee04e132cb552fd11a3025990ea047

lib/std/Build/CheckObject: implement for ELF


1 files changed, 43 insertions(+), 24 deletions(-)

lib/std/Build/Step/CheckObject.zig+43-24
...@@ -1554,15 +1554,14 @@ const ElfDumper = struct {...@@ -1554,15 +1554,14 @@ const ElfDumper = struct {
1554 const archive_symtab_label = "archive symbol table";1554 const archive_symtab_label = "archive symbol table";
15551555
1556 fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {1556 fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1557 _ = kind;1557 return parseAndDumpArchive(step, kind, bytes) catch |err| switch (err) {
1558 const gpa = step.owner.allocator;1558 error.InvalidArchiveMagicNumber => try parseAndDumpObject(step, kind, bytes),
1559 return parseAndDumpArchive(gpa, bytes) catch |err| switch (err) {
1560 error.InvalidArchiveMagicNumber => try parseAndDumpObject(gpa, bytes),
1561 else => |e| return e,1559 else => |e| return e,
1562 };1560 };
1563 }1561 }
15641562
1565 fn parseAndDumpArchive(gpa: Allocator, bytes: []const u8) ![]const u8 {1563 fn parseAndDumpArchive(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1564 const gpa = step.owner.allocator;
1566 var stream = std.io.fixedBufferStream(bytes);1565 var stream = std.io.fixedBufferStream(bytes);
1567 const reader = stream.reader();1566 const reader = stream.reader();
15681567
...@@ -1623,8 +1622,15 @@ const ElfDumper = struct {...@@ -1623,8 +1622,15 @@ const ElfDumper = struct {
1623 var output = std.ArrayList(u8).init(gpa);1622 var output = std.ArrayList(u8).init(gpa);
1624 const writer = output.writer();1623 const writer = output.writer();
16251624
1626 try ctx.dumpSymtab(writer);1625 switch (kind) {
1627 try ctx.dumpObjects(writer);1626 .archive_symtab => if (ctx.symtab.items.len > 0) {
1627 try ctx.dumpSymtab(writer);
1628 } else return step.fail("no archive symbol table found", .{}),
1629
1630 else => if (ctx.objects.items.len > 0) {
1631 try ctx.dumpObjects(step, kind, writer);
1632 } else return step.fail("empty archive", .{}),
1633 }
16281634
1629 return output.toOwnedSlice();1635 return output.toOwnedSlice();
1630 }1636 }
...@@ -1666,8 +1672,6 @@ const ElfDumper = struct {...@@ -1666,8 +1672,6 @@ const ElfDumper = struct {
1666 }1672 }
16671673
1668 fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void {1674 fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void {
1669 if (ctx.symtab.items.len == 0) return;
1670
1671 var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa);1675 var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa);
1672 defer files.deinit();1676 defer files.deinit();
1673 try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len));1677 try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len));
...@@ -1701,10 +1705,10 @@ const ElfDumper = struct {...@@ -1701,10 +1705,10 @@ const ElfDumper = struct {
1701 }1705 }
1702 }1706 }
17031707
1704 fn dumpObjects(ctx: ArchiveContext, writer: anytype) !void {1708 fn dumpObjects(ctx: ArchiveContext, step: *Step, kind: Check.Kind, writer: anytype) !void {
1705 for (ctx.objects.items) |object| {1709 for (ctx.objects.items) |object| {
1706 try writer.print("object {s}\n", .{object.name});1710 try writer.print("object {s}\n", .{object.name});
1707 const output = try parseAndDumpObject(ctx.gpa, ctx.data[object.off..][0..object.len]);1711 const output = try parseAndDumpObject(step, kind, ctx.data[object.off..][0..object.len]);
1708 defer ctx.gpa.free(output);1712 defer ctx.gpa.free(output);
1709 try writer.print("{s}\n", .{output});1713 try writer.print("{s}\n", .{output});
1710 }1714 }
...@@ -1722,7 +1726,8 @@ const ElfDumper = struct {...@@ -1722,7 +1726,8 @@ const ElfDumper = struct {
1722 };1726 };
1723 };1727 };
17241728
1725 fn parseAndDumpObject(gpa: Allocator, bytes: []const u8) ![]const u8 {1729 fn parseAndDumpObject(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 {
1730 const gpa = step.owner.allocator;
1726 var stream = std.io.fixedBufferStream(bytes);1731 var stream = std.io.fixedBufferStream(bytes);
1727 const reader = stream.reader();1732 const reader = stream.reader();
17281733
...@@ -1774,12 +1779,27 @@ const ElfDumper = struct {...@@ -1774,12 +1779,27 @@ const ElfDumper = struct {
1774 var output = std.ArrayList(u8).init(gpa);1779 var output = std.ArrayList(u8).init(gpa);
1775 const writer = output.writer();1780 const writer = output.writer();
17761781
1777 try ctx.dumpHeader(writer);1782 switch (kind) {
1778 try ctx.dumpShdrs(writer);1783 .headers => {
1779 try ctx.dumpPhdrs(writer);1784 try ctx.dumpHeader(writer);
1780 try ctx.dumpDynamicSection(writer);1785 try ctx.dumpShdrs(writer);
1781 try ctx.dumpSymtab(.symtab, writer);1786 try ctx.dumpPhdrs(writer);
1782 try ctx.dumpSymtab(.dysymtab, writer);1787 },
1788
1789 .symtab => if (ctx.symtab.symbols.len > 0) {
1790 try ctx.dumpSymtab(.symtab, writer);
1791 } else return step.fail("no symbol table found", .{}),
1792
1793 .dynamic_symtab => if (ctx.dysymtab.symbols.len > 0) {
1794 try ctx.dumpSymtab(.dysymtab, writer);
1795 } else return step.fail("no dynamic symbol table found", .{}),
1796
1797 .dynamic_section => if (ctx.getSectionByName(".dynamic")) |shndx| {
1798 try ctx.dumpDynamicSection(shndx, writer);
1799 } else return step.fail("no .dynamic section found", .{}),
1800
1801 else => return step.fail("invalid check kind for ELF file format: {s}", .{@tagName(kind)}),
1802 }
17831803
1784 return output.toOwnedSlice();1804 return output.toOwnedSlice();
1785 }1805 }
...@@ -1791,8 +1811,8 @@ const ElfDumper = struct {...@@ -1791,8 +1811,8 @@ const ElfDumper = struct {
1791 shdrs: []align(1) const elf.Elf64_Shdr,1811 shdrs: []align(1) const elf.Elf64_Shdr,
1792 phdrs: []align(1) const elf.Elf64_Phdr,1812 phdrs: []align(1) const elf.Elf64_Phdr,
1793 shstrtab: []const u8,1813 shstrtab: []const u8,
1794 symtab: ?Symtab = null,1814 symtab: Symtab = .{},
1795 dysymtab: ?Symtab = null,1815 dysymtab: Symtab = .{},
17961816
1797 fn dumpHeader(ctx: ObjectContext, writer: anytype) !void {1817 fn dumpHeader(ctx: ObjectContext, writer: anytype) !void {
1798 try writer.writeAll("header\n");1818 try writer.writeAll("header\n");
...@@ -1856,8 +1876,7 @@ const ElfDumper = struct {...@@ -1856,8 +1876,7 @@ const ElfDumper = struct {
1856 }1876 }
1857 }1877 }
18581878
1859 fn dumpDynamicSection(ctx: ObjectContext, writer: anytype) !void {1879 fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void {
1860 const shndx = ctx.getSectionByName(".dynamic") orelse return;
1861 const shdr = ctx.shdrs[shndx];1880 const shdr = ctx.shdrs[shndx];
1862 const strtab = ctx.getSectionContents(shdr.sh_link);1881 const strtab = ctx.getSectionContents(shdr.sh_link);
1863 const data = ctx.getSectionContents(shndx);1882 const data = ctx.getSectionContents(shndx);
...@@ -2097,8 +2116,8 @@ const ElfDumper = struct {...@@ -2097,8 +2116,8 @@ const ElfDumper = struct {
2097 };2116 };
20982117
2099 const Symtab = struct {2118 const Symtab = struct {
2100 symbols: []align(1) const elf.Elf64_Sym,2119 symbols: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{},
2101 strings: []const u8,2120 strings: []const u8 = &[0]u8{},
21022121
2103 fn get(st: Symtab, index: usize) ?elf.Elf64_Sym {2122 fn get(st: Symtab, index: usize) ?elf.Elf64_Sym {
2104 if (index >= st.symbols.len) return null;2123 if (index >= st.symbols.len) return null;