| author | |
| committer | |
| log | 57889cae80310fa774b181ea9d0a8543f8437df7 |
| tree | 291014054a5006247fc41cb8de7f47945273bacf |
| parent | d33c00cad024c15e4fae84317d24d816eaf3da3a |
Not yet fully compatible with the new linker, but still progress.
Closes #257868 files changed, 56 insertions(+), 65 deletions(-)
lib/std/c.zig+3-3| ... | @@ -3971,7 +3971,7 @@ pub const dl_phdr_info = switch (native_os) { | ... | @@ -3971,7 +3971,7 @@ pub const dl_phdr_info = switch (native_os) { |
| 3971 | /// Module name. | 3971 | /// Module name. |
| 3972 | name: ?[*:0]const u8, | 3972 | name: ?[*:0]const u8, |
| 3973 | /// Pointer to module's phdr. | 3973 | /// Pointer to module's phdr. |
| 3974 | phdr: [*]std.elf.Phdr, | 3974 | phdr: [*]std.elf.ElfN.Phdr, |
| 3975 | /// Number of entries in phdr. | 3975 | /// Number of entries in phdr. |
| 3976 | phnum: u16, | 3976 | phnum: u16, |
| 3977 | /// Total number of loads. | 3977 | /// Total number of loads. |
| ... | @@ -3984,7 +3984,7 @@ pub const dl_phdr_info = switch (native_os) { | ... | @@ -3984,7 +3984,7 @@ pub const dl_phdr_info = switch (native_os) { |
| 3984 | .illumos => extern struct { | 3984 | .illumos => extern struct { |
| 3985 | addr: std.elf.Addr, | 3985 | addr: std.elf.Addr, |
| 3986 | name: ?[*:0]const u8, | 3986 | name: ?[*:0]const u8, |
| 3987 | phdr: [*]std.elf.Phdr, | 3987 | phdr: [*]std.elf.ElfN.Phdr, |
| 3988 | phnum: std.elf.Half, | 3988 | phnum: std.elf.Half, |
| 3989 | /// Incremented when a new object is mapped into the process. | 3989 | /// Incremented when a new object is mapped into the process. |
| 3990 | adds: u64, | 3990 | adds: u64, |
| ... | @@ -3995,7 +3995,7 @@ pub const dl_phdr_info = switch (native_os) { | ... | @@ -3995,7 +3995,7 @@ pub const dl_phdr_info = switch (native_os) { |
| 3995 | .openbsd, .haiku, .dragonfly, .netbsd, .serenity => extern struct { | 3995 | .openbsd, .haiku, .dragonfly, .netbsd, .serenity => extern struct { |
| 3996 | addr: usize, | 3996 | addr: usize, |
| 3997 | name: ?[*:0]const u8, | 3997 | name: ?[*:0]const u8, |
| 3998 | phdr: [*]std.elf.Phdr, | 3998 | phdr: [*]std.elf.ElfN.Phdr, |
| 3999 | phnum: std.elf.Half, | 3999 | phnum: std.elf.Half, |
| 4000 | }, | 4000 | }, |
| 4001 | else => void, | 4001 | else => void, |
lib/std/debug/SelfInfo/Elf.zig+10-10| ... | @@ -441,11 +441,11 @@ const DlIterContext = struct { | ... | @@ -441,11 +441,11 @@ const DlIterContext = struct { |
| 441 | 441 | ||
| 442 | // Populate `build_id` and `gnu_eh_frame` | 442 | // Populate `build_id` and `gnu_eh_frame` |
| 443 | for (info.phdr[0..info.phnum]) |phdr| { | 443 | for (info.phdr[0..info.phnum]) |phdr| { |
| 444 | switch (phdr.p_type) { | 444 | switch (phdr.type) { |
| 445 | std.elf.PT_NOTE => { | 445 | .NOTE => { |
| 446 | // Look for .note.gnu.build-id | 446 | // Look for .note.gnu.build-id |
| 447 | const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.p_vaddr); | 447 | const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.vaddr); |
| 448 | var r: std.Io.Reader = .fixed(segment_ptr[0..phdr.p_memsz]); | 448 | var r: std.Io.Reader = .fixed(segment_ptr[0..phdr.memsz]); |
| 449 | const name_size = r.takeInt(u32, native_endian) catch continue; | 449 | const name_size = r.takeInt(u32, native_endian) catch continue; |
| 450 | const desc_size = r.takeInt(u32, native_endian) catch continue; | 450 | const desc_size = r.takeInt(u32, native_endian) catch continue; |
| 451 | const note_type = r.takeInt(u32, native_endian) catch continue; | 451 | const note_type = r.takeInt(u32, native_endian) catch continue; |
| ... | @@ -455,9 +455,9 @@ const DlIterContext = struct { | ... | @@ -455,9 +455,9 @@ const DlIterContext = struct { |
| 455 | const desc = r.take(desc_size) catch continue; | 455 | const desc = r.take(desc_size) catch continue; |
| 456 | build_id = desc; | 456 | build_id = desc; |
| 457 | }, | 457 | }, |
| 458 | std.elf.PT_GNU_EH_FRAME => { | 458 | std.elf.PT.GNU_EH_FRAME => { |
| 459 | const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.p_vaddr); | 459 | const segment_ptr: [*]const u8 = @ptrFromInt(info.addr + phdr.vaddr); |
| 460 | gnu_eh_frame = segment_ptr[0..phdr.p_memsz]; | 460 | gnu_eh_frame = segment_ptr[0..phdr.memsz]; |
| 461 | }, | 461 | }, |
| 462 | else => {}, | 462 | else => {}, |
| 463 | } | 463 | } |
| ... | @@ -478,11 +478,11 @@ const DlIterContext = struct { | ... | @@ -478,11 +478,11 @@ const DlIterContext = struct { |
| 478 | }); | 478 | }); |
| 479 | 479 | ||
| 480 | for (info.phdr[0..info.phnum]) |phdr| { | 480 | for (info.phdr[0..info.phnum]) |phdr| { |
| 481 | if (phdr.p_type != std.elf.PT_LOAD) continue; | 481 | if (phdr.type != .LOAD) continue; |
| 482 | try context.si.ranges.append(gpa, .{ | 482 | try context.si.ranges.append(gpa, .{ |
| 483 | // Overflowing addition handles VSDOs having p_vaddr = 0xffffffffff700000 | 483 | // Overflowing addition handles VSDOs having p_vaddr = 0xffffffffff700000 |
| 484 | .start = info.addr +% phdr.p_vaddr, | 484 | .start = info.addr +% phdr.vaddr, |
| 485 | .len = phdr.p_memsz, | 485 | .len = phdr.memsz, |
| 486 | .module_index = module_index, | 486 | .module_index = module_index, |
| 487 | }); | 487 | }); |
| 488 | } | 488 | } |
lib/std/dynamic_library.zig+1-2| ... | @@ -92,8 +92,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { | ... | @@ -92,8 +92,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { |
| 92 | }); | 92 | }); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | pub fn linkmap_iterator(phdrs: []const elf.Phdr) error{InvalidExe}!LinkMap.Iterator { | 95 | pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { |
| 96 | _ = phdrs; | ||
| 97 | const _DYNAMIC = get_DYNAMIC() orelse { | 96 | const _DYNAMIC = get_DYNAMIC() orelse { |
| 98 | // No PT_DYNAMIC means this is a statically-linked non-PIE program. | 97 | // No PT_DYNAMIC means this is a statically-linked non-PIE program. |
| 99 | return .{ .current = null }; | 98 | return .{ .current = null }; |
lib/std/elf.zig+1| ... | @@ -50,6 +50,7 @@ pub const AT_L2_CACHESIZE = 44; | ... | @@ -50,6 +50,7 @@ pub const AT_L2_CACHESIZE = 44; |
| 50 | pub const AT_L2_CACHEGEOMETRY = 45; | 50 | pub const AT_L2_CACHEGEOMETRY = 45; |
| 51 | pub const AT_L3_CACHESIZE = 46; | 51 | pub const AT_L3_CACHESIZE = 46; |
| 52 | pub const AT_L3_CACHEGEOMETRY = 47; | 52 | pub const AT_L3_CACHEGEOMETRY = 47; |
| 53 | pub const AT_MINSIGSTKSZ = 51; | ||
| 53 | 54 | ||
| 54 | pub const DT_NULL = 0; | 55 | pub const DT_NULL = 0; |
| 55 | pub const DT_NEEDED = 1; | 56 | pub const DT_NEEDED = 1; |
lib/std/os/linux.zig+1-1| ... | @@ -6101,7 +6101,7 @@ pub const dirent64 = extern struct { | ... | @@ -6101,7 +6101,7 @@ pub const dirent64 = extern struct { |
| 6101 | pub const dl_phdr_info = extern struct { | 6101 | pub const dl_phdr_info = extern struct { |
| 6102 | addr: usize, | 6102 | addr: usize, |
| 6103 | name: ?[*:0]const u8, | 6103 | name: ?[*:0]const u8, |
| 6104 | phdr: [*]std.elf.Phdr, | 6104 | phdr: [*]std.elf.ElfN.Phdr, |
| 6105 | phnum: u16, | 6105 | phnum: u16, |
| 6106 | }; | 6106 | }; |
| 6107 | 6107 |
lib/std/posix.zig+30-39| ... | @@ -5048,6 +5048,13 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void { | ... | @@ -5048,6 +5048,13 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void { |
| 5048 | } | 5048 | } |
| 5049 | } | 5049 | } |
| 5050 | 5050 | ||
| 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 | |||
| 5051 | pub fn dl_iterate_phdr( | 5058 | pub fn dl_iterate_phdr( |
| 5052 | context: anytype, | 5059 | context: anytype, |
| 5053 | comptime Error: type, | 5060 | comptime Error: type, |
| ... | @@ -5075,34 +5082,24 @@ pub fn dl_iterate_phdr( | ... | @@ -5075,34 +5082,24 @@ pub fn dl_iterate_phdr( |
| 5075 | } | 5082 | } |
| 5076 | } | 5083 | } |
| 5077 | 5084 | ||
| 5078 | const elf_base = std.process.getBaseAddress(); | 5085 | var it = dl.linkmap_iterator() catch unreachable; |
| 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; | ||
| 5086 | 5086 | ||
| 5087 | // The executable has no dynamic link segment, create a single entry for | 5087 | // The executable has no dynamic link segment, create a single entry for |
| 5088 | // the whole ELF image. | 5088 | // the whole ELF image. |
| 5089 | if (it.end()) { | 5089 | if (it.end()) { |
| 5090 | // Find the base address for the ELF image, if this is a PIE the value | 5090 | const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval; |
| 5091 | // is non-zero. | 5091 | const phdrs = getSelfPhdrs(); |
| 5092 | const base_address = for (phdrs) |*phdr| { | 5092 | var info: dl_phdr_info = .{ |
| 5093 | if (phdr.p_type == elf.PT_PHDR) { | 5093 | .addr = for (phdrs) |phdr| switch (phdr.type) { |
| 5094 | break @intFromPtr(phdrs.ptr) - phdr.p_vaddr; | 5094 | .PHDR => break @intFromPtr(phdrs.ptr) - phdr.vaddr, |
| 5095 | // We could try computing the difference between _DYNAMIC and | 5095 | else => {}, |
| 5096 | // the p_vaddr of the PT_DYNAMIC section, but using the phdr is | 5096 | } else unreachable, |
| 5097 | // good enough (Is it?). | 5097 | .name = switch (getauxval(std.elf.AT_EXECFN)) { |
| 5098 | } | 5098 | 0 => "/proc/self/exe", |
| 5099 | } else unreachable; | 5099 | else => |name| @ptrFromInt(name), |
| 5100 | 5100 | }, | |
| 5101 | var info = dl_phdr_info{ | ||
| 5102 | .addr = base_address, | ||
| 5103 | .name = "/proc/self/exe", | ||
| 5104 | .phdr = phdrs.ptr, | 5101 | .phdr = phdrs.ptr, |
| 5105 | .phnum = ehdr.e_phnum, | 5102 | .phnum = @intCast(phdrs.len), |
| 5106 | }; | 5103 | }; |
| 5107 | 5104 | ||
| 5108 | return callback(&info, @sizeOf(dl_phdr_info), context); | 5105 | return callback(&info, @sizeOf(dl_phdr_info), context); |
| ... | @@ -5110,24 +5107,18 @@ pub fn dl_iterate_phdr( | ... | @@ -5110,24 +5107,18 @@ pub fn dl_iterate_phdr( |
| 5110 | 5107 | ||
| 5111 | // Last return value from the callback function. | 5108 | // Last return value from the callback function. |
| 5112 | while (it.next()) |entry| { | 5109 | while (it.next()) |entry| { |
| 5113 | var phdr: [*]elf.Phdr = undefined; | 5110 | const phdrs: []elf.ElfN.Phdr = if (entry.l_addr != 0) phdrs: { |
| 5114 | var phnum: u16 = undefined; | 5111 | const ehdr: *elf.ElfN.Ehdr = @ptrFromInt(entry.l_addr); |
| 5115 | 5112 | assert(mem.eql(u8, ehdr.ident[0..4], elf.MAGIC)); | |
| 5116 | if (entry.l_addr != 0) { | 5113 | const phdrs: [*]elf.ElfN.Phdr = @ptrFromInt(entry.l_addr + ehdr.phoff); |
| 5117 | const elf_header: *elf.Ehdr = @ptrFromInt(entry.l_addr); | 5114 | break :phdrs phdrs[0..ehdr.phnum]; |
| 5118 | phdr = @ptrFromInt(entry.l_addr + elf_header.e_phoff); | 5115 | } else getSelfPhdrs(); |
| 5119 | phnum = elf_header.e_phnum; | 5116 | |
| 5120 | } else { | 5117 | var info: dl_phdr_info = .{ |
| 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{ | ||
| 5127 | .addr = entry.l_addr, | 5118 | .addr = entry.l_addr, |
| 5128 | .name = entry.l_name, | 5119 | .name = entry.l_name, |
| 5129 | .phdr = phdr, | 5120 | .phdr = phdrs.ptr, |
| 5130 | .phnum = phnum, | 5121 | .phnum = @intCast(phdrs.len), |
| 5131 | }; | 5122 | }; |
| 5132 | 5123 | ||
| 5133 | try callback(&info, @sizeOf(dl_phdr_info), context); | 5124 | try callback(&info, @sizeOf(dl_phdr_info), context); |
lib/std/posix/test.zig+3-3| ... | @@ -257,11 +257,11 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -257,11 +257,11 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 257 | while (i < info.phnum) : (i += 1) { | 257 | while (i < info.phnum) : (i += 1) { |
| 258 | const phdr = info.phdr[i]; | 258 | const phdr = info.phdr[i]; |
| 259 | 259 | ||
| 260 | if (phdr.p_type != elf.PT_LOAD) continue; | 260 | if (phdr.type != .LOAD) continue; |
| 261 | 261 | ||
| 262 | const reloc_addr = info.addr + phdr.p_vaddr; | 262 | const reloc_addr = info.addr + phdr.vaddr; |
| 263 | // Find the ELF header | 263 | // Find the ELF header |
| 264 | const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.p_offset)); | 264 | const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.offset)); |
| 265 | // Validate the magic | 265 | // Validate the magic |
| 266 | if (!mem.eql(u8, elf_header.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic; | 266 | if (!mem.eql(u8, elf_header.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic; |
| 267 | // Consistency check | 267 | // Consistency check |
lib/std/process.zig+7-7| ... | @@ -1658,13 +1658,13 @@ fn posixGetUserInfoPasswdStream(name: []const u8, reader: *std.Io.Reader) !UserI | ... | @@ -1658,13 +1658,13 @@ fn posixGetUserInfoPasswdStream(name: []const u8, reader: *std.Io.Reader) !UserI |
| 1658 | pub fn getBaseAddress() usize { | 1658 | pub fn getBaseAddress() usize { |
| 1659 | switch (native_os) { | 1659 | switch (native_os) { |
| 1660 | .linux => { | 1660 | .linux => { |
| 1661 | const getauxval = if (builtin.link_libc) std.c.getauxval else std.os.linux.getauxval; | 1661 | const phdrs = std.posix.getSelfPhdrs(); |
| 1662 | const base = getauxval(std.elf.AT_BASE); | 1662 | var base: usize = 0; |
| 1663 | if (base != 0) { | 1663 | for (phdrs) |phdr| switch (phdr.type) { |
| 1664 | return base; | 1664 | .LOAD => return base + phdr.vaddr, |
| 1665 | } | 1665 | .PHDR => base = @intFromPtr(phdrs.ptr) - phdr.vaddr, |
| 1666 | const phdr = getauxval(std.elf.AT_PHDR); | 1666 | else => {}, |
| 1667 | return phdr - @sizeOf(std.elf.Ehdr); | 1667 | } else unreachable; |
| 1668 | }, | 1668 | }, |
| 1669 | .driverkit, .ios, .macos, .tvos, .visionos, .watchos => { | 1669 | .driverkit, .ios, .macos, .tvos, .visionos, .watchos => { |
| 1670 | return @intFromPtr(&std.c._mh_execute_header); | 1670 | return @intFromPtr(&std.c._mh_execute_header); |