| ... | ... | @@ -1554,15 +1554,14 @@ const ElfDumper = struct { |
| 1554 | 1554 | const archive_symtab_label = "archive symbol table"; |
| 1555 | 1555 | |
| 1556 | 1556 | fn parseAndDump(step: *Step, kind: Check.Kind, bytes: []const u8) ![]const u8 { |
| 1557 | | _ = kind; |
| 1558 | | const gpa = step.owner.allocator; |
| 1559 | | return parseAndDumpArchive(gpa, bytes) catch |err| switch (err) { |
| 1560 | | error.InvalidArchiveMagicNumber => try parseAndDumpObject(gpa, bytes), |
| 1557 | return parseAndDumpArchive(step, kind, bytes) catch |err| switch (err) { |
| 1558 | error.InvalidArchiveMagicNumber => try parseAndDumpObject(step, kind, bytes), |
| 1561 | 1559 | else => |e| return e, |
| 1562 | 1560 | }; |
| 1563 | 1561 | } |
| 1564 | 1562 | |
| 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 | 1565 | var stream = std.io.fixedBufferStream(bytes); |
| 1567 | 1566 | const reader = stream.reader(); |
| 1568 | 1567 | |
| ... | ... | @@ -1623,8 +1622,15 @@ const ElfDumper = struct { |
| 1623 | 1622 | var output = std.ArrayList(u8).init(gpa); |
| 1624 | 1623 | const writer = output.writer(); |
| 1625 | 1624 | |
| 1626 | | try ctx.dumpSymtab(writer); |
| 1627 | | try ctx.dumpObjects(writer); |
| 1625 | switch (kind) { |
| 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 | } |
| 1628 | 1634 | |
| 1629 | 1635 | return output.toOwnedSlice(); |
| 1630 | 1636 | } |
| ... | ... | @@ -1666,8 +1672,6 @@ const ElfDumper = struct { |
| 1666 | 1672 | } |
| 1667 | 1673 | |
| 1668 | 1674 | fn dumpSymtab(ctx: ArchiveContext, writer: anytype) !void { |
| 1669 | | if (ctx.symtab.items.len == 0) return; |
| 1670 | | |
| 1671 | 1675 | var files = std.AutoHashMap(usize, []const u8).init(ctx.gpa); |
| 1672 | 1676 | defer files.deinit(); |
| 1673 | 1677 | try files.ensureUnusedCapacity(@intCast(ctx.objects.items.len)); |
| ... | ... | @@ -1701,10 +1705,10 @@ const ElfDumper = struct { |
| 1701 | 1705 | } |
| 1702 | 1706 | } |
| 1703 | 1707 | |
| 1704 | | fn dumpObjects(ctx: ArchiveContext, writer: anytype) !void { |
| 1708 | fn dumpObjects(ctx: ArchiveContext, step: *Step, kind: Check.Kind, writer: anytype) !void { |
| 1705 | 1709 | for (ctx.objects.items) |object| { |
| 1706 | 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 | 1712 | defer ctx.gpa.free(output); |
| 1709 | 1713 | try writer.print("{s}\n", .{output}); |
| 1710 | 1714 | } |
| ... | ... | @@ -1722,7 +1726,8 @@ const ElfDumper = struct { |
| 1722 | 1726 | }; |
| 1723 | 1727 | }; |
| 1724 | 1728 | |
| 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 | 1731 | var stream = std.io.fixedBufferStream(bytes); |
| 1727 | 1732 | const reader = stream.reader(); |
| 1728 | 1733 | |
| ... | ... | @@ -1774,12 +1779,27 @@ const ElfDumper = struct { |
| 1774 | 1779 | var output = std.ArrayList(u8).init(gpa); |
| 1775 | 1780 | const writer = output.writer(); |
| 1776 | 1781 | |
| 1777 | | try ctx.dumpHeader(writer); |
| 1778 | | try ctx.dumpShdrs(writer); |
| 1779 | | try ctx.dumpPhdrs(writer); |
| 1780 | | try ctx.dumpDynamicSection(writer); |
| 1781 | | try ctx.dumpSymtab(.symtab, writer); |
| 1782 | | try ctx.dumpSymtab(.dysymtab, writer); |
| 1782 | switch (kind) { |
| 1783 | .headers => { |
| 1784 | try ctx.dumpHeader(writer); |
| 1785 | try ctx.dumpShdrs(writer); |
| 1786 | try ctx.dumpPhdrs(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 | } |
| 1783 | 1803 | |
| 1784 | 1804 | return output.toOwnedSlice(); |
| 1785 | 1805 | } |
| ... | ... | @@ -1791,8 +1811,8 @@ const ElfDumper = struct { |
| 1791 | 1811 | shdrs: []align(1) const elf.Elf64_Shdr, |
| 1792 | 1812 | phdrs: []align(1) const elf.Elf64_Phdr, |
| 1793 | 1813 | shstrtab: []const u8, |
| 1794 | | symtab: ?Symtab = null, |
| 1795 | | dysymtab: ?Symtab = null, |
| 1814 | symtab: Symtab = .{}, |
| 1815 | dysymtab: Symtab = .{}, |
| 1796 | 1816 | |
| 1797 | 1817 | fn dumpHeader(ctx: ObjectContext, writer: anytype) !void { |
| 1798 | 1818 | try writer.writeAll("header\n"); |
| ... | ... | @@ -1856,8 +1876,7 @@ const ElfDumper = struct { |
| 1856 | 1876 | } |
| 1857 | 1877 | } |
| 1858 | 1878 | |
| 1859 | | fn dumpDynamicSection(ctx: ObjectContext, writer: anytype) !void { |
| 1860 | | const shndx = ctx.getSectionByName(".dynamic") orelse return; |
| 1879 | fn dumpDynamicSection(ctx: ObjectContext, shndx: usize, writer: anytype) !void { |
| 1861 | 1880 | const shdr = ctx.shdrs[shndx]; |
| 1862 | 1881 | const strtab = ctx.getSectionContents(shdr.sh_link); |
| 1863 | 1882 | const data = ctx.getSectionContents(shndx); |
| ... | ... | @@ -2097,8 +2116,8 @@ const ElfDumper = struct { |
| 2097 | 2116 | }; |
| 2098 | 2117 | |
| 2099 | 2118 | const Symtab = struct { |
| 2100 | | symbols: []align(1) const elf.Elf64_Sym, |
| 2101 | | strings: []const u8, |
| 2119 | symbols: []align(1) const elf.Elf64_Sym = &[0]elf.Elf64_Sym{}, |
| 2120 | strings: []const u8 = &[0]u8{}, |
| 2102 | 2121 | |
| 2103 | 2122 | fn get(st: Symtab, index: usize) ?elf.Elf64_Sym { |
| 2104 | 2123 | if (index >= st.symbols.len) return null; |