@@ -5048,6 +5048,13 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
50485048 }
50495049}
50505050
5051+ pub fn getSelfPhdrs () []std.elf.ElfN.Phdr {
5052+ const getauxval = if (builtin .link_libc ) std .c .getauxval else std .os .linux .getauxval ;
5053+ assert (getauxval (std .elf .AT_PHENT ) == @sizeOf (std .elf .ElfN .Phdr ));
5054+ const phdrs : [* ]std.elf.ElfN.Phdr = @ptrFromInt (getauxval (std .elf .AT_PHDR ));
5055+ return phdrs [0.. getauxval (std .elf .AT_PHNUM )];
5056+ }
5057+
50515058pub fn dl_iterate_phdr (
50525059 context : anytype ,
50535060 comptime Error : type ,
@@ -5075,59 +5082,43 @@ pub fn dl_iterate_phdr(
50755082 }
50765083 }
50775084
5078- const elf_base = std .process .getBaseAddress ();
5079- const ehdr : * elf.Ehdr = @ptrFromInt (elf_base );
5080- // Make sure the base address points to an ELF image.
5081- assert (mem .eql (u8 , ehdr .e_ident [0.. 4], elf .MAGIC ));
5082- const n_phdr = ehdr .e_phnum ;
5083- const phdrs = (@as ([* ]elf .Phdr , @ptrFromInt (elf_base + ehdr .e_phoff )))[0.. n_phdr ];
5084-
5085- var it = dl .linkmap_iterator (phdrs ) catch unreachable ;
5085+ var it = dl .linkmap_iterator () catch unreachable ;
50865086
50875087 // The executable has no dynamic link segment, create a single entry for
50885088 // the whole ELF image.
50895089 if (it .end ()) {
5090- // Find the base address for the ELF image, if this is a PIE the value
5091- // is non-zero.
5092- const base_address = for (phdrs ) | * phdr | {
5093- if (phdr .p_type == elf .PT_PHDR ) {
5094- break @intFromPtr (phdrs .ptr ) - phdr .p_vaddr ;
5095- // We could try computing the difference between _DYNAMIC and
5096- // the p_vaddr of the PT_DYNAMIC section, but using the phdr is
5097- // good enough (Is it?).
5098- }
5099- } else unreachable ;
5100-
5101- var info = dl_phdr_info {
5102- .addr = base_address ,
5103- .name = "/proc/self/exe" ,
5090+ const getauxval = if (builtin .link_libc ) std .c .getauxval else std .os .linux .getauxval ;
5091+ const phdrs = getSelfPhdrs ();
5092+ var info : dl_phdr_info = .{
5093+ .addr = for (phdrs ) | phdr | switch (phdr .type ) {
5094+ .PHDR = > break @intFromPtr (phdrs .ptr ) - phdr .vaddr ,
5095+ else = > {},
5096+ } else unreachable ,
5097+ .name = switch (getauxval (std .elf .AT_EXECFN )) {
5098+ 0 = > "/proc/self/exe" ,
5099+ else = > | name | @ptrFromInt (name ),
5100+ },
51045101 .phdr = phdrs .ptr ,
5105- .phnum = ehdr . e_phnum ,
5102+ .phnum = @intCast ( phdrs . len ) ,
51065103 };
51075104
51085105 return callback (& info , @sizeOf (dl_phdr_info ), context );
51095106 }
51105107
51115108 // Last return value from the callback function.
51125109 while (it .next ()) | entry | {
5113- var phdr : [* ]elf.Phdr = undefined ;
5114- var phnum : u16 = undefined ;
5115-
5116- if (entry .l_addr != 0 ) {
5117- const elf_header : * elf.Ehdr = @ptrFromInt (entry .l_addr );
5118- phdr = @ptrFromInt (entry .l_addr + elf_header .e_phoff );
5119- phnum = elf_header .e_phnum ;
5120- } else {
5121- // This is the running ELF image
5122- phdr = @ptrFromInt (elf_base + ehdr .e_phoff );
5123- phnum = ehdr .e_phnum ;
5124- }
5125-
5126- var info = dl_phdr_info {
5110+ const phdrs : []elf.ElfN.Phdr = if (entry .l_addr != 0 ) phdrs : {
5111+ const ehdr : * elf.ElfN.Ehdr = @ptrFromInt (entry .l_addr );
5112+ assert (mem .eql (u8 , ehdr .ident [0.. 4], elf .MAGIC ));
5113+ const phdrs : [* ]elf.ElfN.Phdr = @ptrFromInt (entry .l_addr + ehdr .phoff );
5114+ break :phdrs phdrs [0.. ehdr .phnum ];
5115+ } else getSelfPhdrs ();
5116+
5117+ var info : dl_phdr_info = .{
51275118 .addr = entry .l_addr ,
51285119 .name = entry .l_name ,
5129- .phdr = phdr ,
5130- .phnum = phnum ,
5120+ .phdr = phdrs . ptr ,
5121+ .phnum = @intCast ( phdrs . len ) ,
51315122 };
51325123
51335124 try callback (& info , @sizeOf (dl_phdr_info ), context );
0 commit comments