@@ -1857,15 +1857,26 @@ const ElfDumper = struct {
18571857
18581858 fn parseAndDumpObject (step : * Step , check : Check , bytes : []const u8 ) ! []const u8 {
18591859 const gpa = step .owner .allocator ;
1860- var reader : std.Io.Reader = .fixed (bytes );
18611860
1862- const hdr = try reader .takeStruct (elf .Elf64_Ehdr , .little );
1863- if (! mem .eql (u8 , hdr .e_ident [0.. 4], "\x7f ELF" )) {
1864- return error .InvalidMagicNumber ;
1861+ // `std.elf.Header` takes care of endianness issues for us.
1862+ var reader : std.Io.Reader = .fixed (bytes );
1863+ const hdr = try elf .Header .read (& reader );
1864+
1865+ var shdrs = try gpa .alloc (elf .Elf64_Shdr , hdr .shnum );
1866+ defer gpa .free (shdrs );
1867+ {
1868+ var shdr_it = hdr .iterateSectionHeadersBuffer (bytes );
1869+ var shdr_i : usize = 0 ;
1870+ while (try shdr_it .next ()) | shdr | : (shdr_i += 1 ) shdrs [shdr_i ] = shdr ;
18651871 }
18661872
1867- const shdrs = @as ([* ]align (1 ) const elf .Elf64_Shdr , @ptrCast (bytes .ptr + hdr .e_shoff ))[0.. hdr .e_shnum ];
1868- const phdrs = @as ([* ]align (1 ) const elf .Elf64_Phdr , @ptrCast (bytes .ptr + hdr .e_phoff ))[0.. hdr .e_phnum ];
1873+ var phdrs = try gpa .alloc (elf .Elf64_Phdr , hdr .shnum );
1874+ defer gpa .free (phdrs );
1875+ {
1876+ var phdr_it = hdr .iterateProgramHeadersBuffer (bytes );
1877+ var phdr_i : usize = 0 ;
1878+ while (try phdr_it .next ()) | phdr | : (phdr_i += 1 ) phdrs [phdr_i ] = phdr ;
1879+ }
18691880
18701881 var ctx = ObjectContext {
18711882 .gpa = gpa ,
@@ -1875,13 +1886,21 @@ const ElfDumper = struct {
18751886 .phdrs = phdrs ,
18761887 .shstrtab = undefined ,
18771888 };
1878- ctx .shstrtab = ctx .getSectionContents (ctx .hdr .e_shstrndx );
1889+ ctx .shstrtab = ctx .getSectionContents (ctx .hdr .shstrndx );
1890+
1891+ defer gpa .free (ctx .symtab .symbols );
1892+ defer gpa .free (ctx .dysymtab .symbols );
1893+ defer gpa .free (ctx .dyns );
18791894
18801895 for (ctx .shdrs , 0.. ) | shdr , i | switch (shdr .sh_type ) {
18811896 elf .SHT_SYMTAB , elf .SHT_DYNSYM = > {
18821897 const raw = ctx .getSectionContents (i );
18831898 const nsyms = @divExact (raw .len , @sizeOf (elf .Elf64_Sym ));
1884- const symbols = @as ([* ]align (1 ) const elf .Elf64_Sym , @ptrCast (raw .ptr ))[0.. nsyms ];
1899+ const symbols = try gpa .alloc (elf .Elf64_Sym , nsyms );
1900+
1901+ var r : std.Io.Reader = .fixed (raw );
1902+ for (0.. nsyms ) | si | symbols [si ] = r .takeStruct (elf .Elf64_Sym , ctx .hdr .endian ) catch unreachable ;
1903+
18851904 const strings = ctx .getSectionContents (shdr .sh_link );
18861905
18871906 switch (shdr .sh_type ) {
@@ -1900,6 +1919,17 @@ const ElfDumper = struct {
19001919 else = > unreachable ,
19011920 }
19021921 },
1922+ elf .SHT_DYNAMIC = > {
1923+ const raw = ctx .getSectionContents (i );
1924+ const ndyns = @divExact (raw .len , @sizeOf (elf .Elf64_Dyn ));
1925+ const dyns = try gpa .alloc (elf .Elf64_Dyn , ndyns );
1926+
1927+ var r : std.Io.Reader = .fixed (raw );
1928+ for (0.. ndyns ) | si | dyns [si ] = r .takeStruct (elf .Elf64_Dyn , ctx .hdr .endian ) catch unreachable ;
1929+
1930+ ctx .dyns = dyns ;
1931+ ctx .dyns_strings = ctx .getSectionContents (shdr .sh_link );
1932+ },
19031933
19041934 else = > {},
19051935 };
@@ -1923,9 +1953,9 @@ const ElfDumper = struct {
19231953 try ctx .dumpSymtab (.dysymtab , writer );
19241954 } else return step .fail ("no dynamic symbol table found" , .{}),
19251955
1926- .dynamic_section = > if (ctx .getSectionByName ( ".dynamic" )) | shndx | {
1927- try ctx .dumpDynamicSection (shndx , writer );
1928- } else return step .fail ("no . dynamic section found" , .{}),
1956+ .dynamic_section = > if (ctx .dyns . len > 0 ) {
1957+ try ctx .dumpDynamicSection (writer );
1958+ } else return step .fail ("no dynamic section found" , .{}),
19291959
19301960 .dump_section = > {
19311961 const name = mem .sliceTo (@as ([* :0 ]const u8 , @ptrCast (check .data .items .ptr + check .payload .dump_section )), 0 );
@@ -1942,17 +1972,19 @@ const ElfDumper = struct {
19421972 const ObjectContext = struct {
19431973 gpa : Allocator ,
19441974 data : []const u8 ,
1945- hdr : elf.Elf64_Ehdr ,
1946- shdrs : []align ( 1 ) const elf.Elf64_Shdr ,
1947- phdrs : []align ( 1 ) const elf.Elf64_Phdr ,
1975+ hdr : elf.Header ,
1976+ shdrs : []const elf.Elf64_Shdr ,
1977+ phdrs : []const elf.Elf64_Phdr ,
19481978 shstrtab : []const u8 ,
19491979 symtab : Symtab = .{},
19501980 dysymtab : Symtab = .{},
1981+ dyns : []const elf.Elf64_Dyn = &.{},
1982+ dyns_strings : []const u8 = &.{},
19511983
19521984 fn dumpHeader (ctx : ObjectContext , writer : anytype ) ! void {
19531985 try writer .writeAll ("header\n " );
1954- try writer .print ("type {s}\n " , .{@tagName (ctx .hdr .e_type )});
1955- try writer .print ("entry {x}\n " , .{ctx .hdr .e_entry });
1986+ try writer .print ("type {s}\n " , .{@tagName (ctx .hdr .type )});
1987+ try writer .print ("entry {x}\n " , .{ctx .hdr .entry });
19561988 }
19571989
19581990 fn dumpPhdrs (ctx : ObjectContext , writer : anytype ) ! void {
@@ -2011,16 +2043,10 @@ const ElfDumper = struct {
20112043 }
20122044 }
20132045
2014- fn dumpDynamicSection (ctx : ObjectContext , shndx : usize , writer : anytype ) ! void {
2015- const shdr = ctx .shdrs [shndx ];
2016- const strtab = ctx .getSectionContents (shdr .sh_link );
2017- const data = ctx .getSectionContents (shndx );
2018- const nentries = @divExact (data .len , @sizeOf (elf .Elf64_Dyn ));
2019- const entries = @as ([* ]align (1 ) const elf .Elf64_Dyn , @ptrCast (data .ptr ))[0.. nentries ];
2020-
2046+ fn dumpDynamicSection (ctx : ObjectContext , writer : anytype ) ! void {
20212047 try writer .writeAll (ElfDumper .dynamic_section_label ++ "\n " );
20222048
2023- for (entries ) | entry | {
2049+ for (ctx . dyns ) | entry | {
20242050 const key = @as (u64 , @bitCast (entry .d_tag ));
20252051 const value = entry .d_val ;
20262052
@@ -2067,7 +2093,7 @@ const ElfDumper = struct {
20672093 elf .DT_RPATH ,
20682094 elf .DT_RUNPATH ,
20692095 = > {
2070- const name = getString (strtab , @intCast (value ));
2096+ const name = getString (ctx . dyns_strings , @intCast (value ));
20712097 try writer .print (" {s}" , .{name });
20722098 },
20732099
@@ -2256,8 +2282,8 @@ const ElfDumper = struct {
22562282 };
22572283
22582284 const Symtab = struct {
2259- symbols : []align ( 1 ) const elf.Elf64_Sym = &[ 0 ] elf.Elf64_Sym {},
2260- strings : []const u8 = &[ 0 ] u8 {},
2285+ symbols : []const elf.Elf64_Sym = &. {},
2286+ strings : []const u8 = &. {},
22612287
22622288 fn get (st : Symtab , index : usize ) ? elf.Elf64_Sym {
22632289 if (index >= st .symbols .len ) return null ;
0 commit comments