| author | |
| committer | |
| log | ea006188aaf110a33cbf0ca00888306f263cce98 |
| tree | 1aea8c55e6dd2d79abd46fded12d70c82d75a992 |
| parent | 9be16fe65fc15a74abf32c6b198a28bc5e86cd27 |
12 files changed, 57 insertions(+), 98 deletions(-)
lib/compiler/objcopy.zig+1-1| ... | @@ -435,7 +435,7 @@ const BinaryElfOutput = struct { | ... | @@ -435,7 +435,7 @@ const BinaryElfOutput = struct { |
| 435 | 435 | ||
| 436 | var program_headers = elf_hdr.iterateProgramHeaders(in); | 436 | var program_headers = elf_hdr.iterateProgramHeaders(in); |
| 437 | while (try program_headers.next()) |phdr| { | 437 | while (try program_headers.next()) |phdr| { |
| 438 | if (phdr.p_type == elf.PT_LOAD) { | 438 | if (phdr.p_type == @backingInt(elf.PT.LOAD)) { |
| 439 | const newSegment = try allocator.create(BinaryElfSegment); | 439 | const newSegment = try allocator.create(BinaryElfSegment); |
| 440 | 440 | ||
| 441 | newSegment.physicalAddress = phdr.p_paddr; | 441 | newSegment.physicalAddress = phdr.p_paddr; |
lib/std/Build/Step/Compile.zig+1-1| ... | @@ -101,7 +101,7 @@ each_lib_rpath: ?bool = null, | ... | @@ -101,7 +101,7 @@ each_lib_rpath: ?bool = null, |
| 101 | /// This option overrides the CLI argument passed to `zig build`. | 101 | /// This option overrides the CLI argument passed to `zig build`. |
| 102 | build_id: ?std.zig.BuildId = null, | 102 | build_id: ?std.zig.BuildId = null, |
| 103 | 103 | ||
| 104 | /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF | 104 | /// Create a .eh_frame_hdr section and a PT.GNU_EH_FRAME segment in the ELF |
| 105 | /// file. | 105 | /// file. |
| 106 | link_eh_frame_hdr: bool = false, | 106 | link_eh_frame_hdr: bool = false, |
| 107 | link_emit_relocs: bool = false, | 107 | link_emit_relocs: bool = false, |
lib/std/dynamic_library.zig+4-4| ... | @@ -103,7 +103,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { | ... | @@ -103,7 +103,7 @@ pub fn get_DYNAMIC() ?[*]const elf.Dyn { |
| 103 | 103 | ||
| 104 | pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { | 104 | pub fn linkmap_iterator() error{InvalidExe}!LinkMap.Iterator { |
| 105 | const _DYNAMIC = get_DYNAMIC() orelse { | 105 | const _DYNAMIC = get_DYNAMIC() orelse { |
| 106 | // No PT_DYNAMIC means this is a statically-linked non-PIE program. | 106 | // No PT.DYNAMIC means this is a statically-linked non-PIE program. |
| 107 | return .{ .current = null }; | 107 | return .{ .current = null }; |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| ... | @@ -263,8 +263,8 @@ pub const ElfDynLib = struct { | ... | @@ -263,8 +263,8 @@ pub const ElfDynLib = struct { |
| 263 | }) { | 263 | }) { |
| 264 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); | 264 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); |
| 265 | switch (ph.p_type) { | 265 | switch (ph.p_type) { |
| 266 | elf.PT_LOAD => virt_addr_end = @max(virt_addr_end, ph.p_vaddr + ph.p_memsz), | 266 | @backingInt(elf.PT.LOAD) => virt_addr_end = @max(virt_addr_end, ph.p_vaddr + ph.p_memsz), |
| 267 | elf.PT_DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(elf_addr + ph.p_offset)), | 267 | @backingInt(elf.PT.DYNAMIC) => maybe_dynv = @as([*]usize, @ptrFromInt(elf_addr + ph.p_offset)), |
| 268 | else => {}, | 268 | else => {}, |
| 269 | } | 269 | } |
| 270 | } | 270 | } |
| ... | @@ -294,7 +294,7 @@ pub const ElfDynLib = struct { | ... | @@ -294,7 +294,7 @@ pub const ElfDynLib = struct { |
| 294 | }) { | 294 | }) { |
| 295 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); | 295 | const ph = @as(*elf.Phdr, @ptrFromInt(ph_addr)); |
| 296 | switch (ph.p_type) { | 296 | switch (ph.p_type) { |
| 297 | elf.PT_LOAD => { | 297 | @backingInt(elf.PT.LOAD) => { |
| 298 | // The VirtAddr may not be page-aligned; in such case there will be | 298 | // The VirtAddr may not be page-aligned; in such case there will be |
| 299 | // extra nonsense mapped before/after the VirtAddr,MemSiz | 299 | // extra nonsense mapped before/after the VirtAddr,MemSiz |
| 300 | const aligned_addr = (base + ph.p_vaddr) & ~(@as(usize, page_size) - 1); | 300 | const aligned_addr = (base + ph.p_vaddr) & ~(@as(usize, page_size) - 1); |
lib/std/elf.zig-41| ... | @@ -290,47 +290,6 @@ pub const VER_FLG_BASE = 1; | ... | @@ -290,47 +290,6 @@ pub const VER_FLG_BASE = 1; |
| 290 | /// Weak version identifier | 290 | /// Weak version identifier |
| 291 | pub const VER_FLG_WEAK = 2; | 291 | pub const VER_FLG_WEAK = 2; |
| 292 | 292 | ||
| 293 | /// Deprecated, use `@intFromEnum(std.elf.PT.NULL)` | ||
| 294 | pub const PT_NULL = @backingInt(std.elf.PT.NULL); | ||
| 295 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOAD)` | ||
| 296 | pub const PT_LOAD = @backingInt(std.elf.PT.LOAD); | ||
| 297 | /// Deprecated, use `@intFromEnum(std.elf.PT.DYNAMIC)` | ||
| 298 | pub const PT_DYNAMIC = @backingInt(std.elf.PT.DYNAMIC); | ||
| 299 | /// Deprecated, use `@intFromEnum(std.elf.PT.INTERP)` | ||
| 300 | pub const PT_INTERP = @backingInt(std.elf.PT.INTERP); | ||
| 301 | /// Deprecated, use `@intFromEnum(std.elf.PT.NOTE)` | ||
| 302 | pub const PT_NOTE = @backingInt(std.elf.PT.NOTE); | ||
| 303 | /// Deprecated, use `@intFromEnum(std.elf.PT.SHLIB)` | ||
| 304 | pub const PT_SHLIB = @backingInt(std.elf.PT.SHLIB); | ||
| 305 | /// Deprecated, use `@intFromEnum(std.elf.PT.PHDR)` | ||
| 306 | pub const PT_PHDR = @backingInt(std.elf.PT.PHDR); | ||
| 307 | /// Deprecated, use `@intFromEnum(std.elf.PT.TLS)` | ||
| 308 | pub const PT_TLS = @backingInt(std.elf.PT.TLS); | ||
| 309 | /// Deprecated, use `std.elf.PT.NUM`. | ||
| 310 | pub const PT_NUM = PT.NUM; | ||
| 311 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOOS)` | ||
| 312 | pub const PT_LOOS = @backingInt(std.elf.PT.LOOS); | ||
| 313 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_EH_FRAME)` | ||
| 314 | pub const PT_GNU_EH_FRAME = @backingInt(std.elf.PT.GNU_EH_FRAME); | ||
| 315 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_STACK)` | ||
| 316 | pub const PT_GNU_STACK = @backingInt(std.elf.PT.GNU_STACK); | ||
| 317 | /// Deprecated, use `@intFromEnum(std.elf.PT.GNU_RELRO)` | ||
| 318 | pub const PT_GNU_RELRO = @backingInt(std.elf.PT.GNU_RELRO); | ||
| 319 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOSUNW)` | ||
| 320 | pub const PT_LOSUNW = @backingInt(std.elf.PT.LOSUNW); | ||
| 321 | /// Deprecated, use `@intFromEnum(std.elf.PT.SUNWBSS)` | ||
| 322 | pub const PT_SUNWBSS = @backingInt(std.elf.PT.SUNWBSS); | ||
| 323 | /// Deprecated, use `@intFromEnum(std.elf.PT.SUNWSTACK)` | ||
| 324 | pub const PT_SUNWSTACK = @backingInt(std.elf.PT.SUNWSTACK); | ||
| 325 | /// Deprecated, use `@intFromEnum(std.elf.PT.HISUNW)` | ||
| 326 | pub const PT_HISUNW = @backingInt(std.elf.PT.HISUNW); | ||
| 327 | /// Deprecated, use `@intFromEnum(std.elf.PT.HIOS)` | ||
| 328 | pub const PT_HIOS = @backingInt(std.elf.PT.HIOS); | ||
| 329 | /// Deprecated, use `@intFromEnum(std.elf.PT.LOPROC)` | ||
| 330 | pub const PT_LOPROC = @backingInt(std.elf.PT.LOPROC); | ||
| 331 | /// Deprecated, use `@intFromEnum(std.elf.PT.HIPROC)` | ||
| 332 | pub const PT_HIPROC = @backingInt(std.elf.PT.HIPROC); | ||
| 333 | |||
| 334 | pub const PN_XNUM = 0xffff; | 293 | pub const PN_XNUM = 0xffff; |
| 335 | 294 | ||
| 336 | /// Deprecated, use `@intFromEnum(std.elf.SHT.NULL)` | 295 | /// Deprecated, use `@intFromEnum(std.elf.SHT.NULL)` |
lib/std/os/linux/tls.zig+4-4| ... | @@ -22,7 +22,7 @@ const page_size_min = std.heap.page_size_min; | ... | @@ -22,7 +22,7 @@ const page_size_min = std.heap.page_size_min; |
| 22 | /// Represents an ELF TLS variant. | 22 | /// Represents an ELF TLS variant. |
| 23 | /// | 23 | /// |
| 24 | /// In all variants, the TP and the TLS blocks must be aligned to the `p_align` value in the | 24 | /// In all variants, the TP and the TLS blocks must be aligned to the `p_align` value in the |
| 25 | /// `PT_TLS` ELF program header. Everything else has natural alignment. | 25 | /// `PT.TLS` ELF program header. Everything else has natural alignment. |
| 26 | /// | 26 | /// |
| 27 | /// The location of the DTV does not actually matter. For simplicity, we put it in the TLS area, but | 27 | /// The location of the DTV does not actually matter. For simplicity, we put it in the TLS area, but |
| 28 | /// there is no actual ABI requirement that it reside there. | 28 | /// there is no actual ABI requirement that it reside there. |
| ... | @@ -489,8 +489,8 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { | ... | @@ -489,8 +489,8 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { |
| 489 | 489 | ||
| 490 | for (phdrs) |*phdr| { | 490 | for (phdrs) |*phdr| { |
| 491 | switch (phdr.p_type) { | 491 | switch (phdr.p_type) { |
| 492 | elf.PT_PHDR => img_base = @intFromPtr(phdrs.ptr) - phdr.p_vaddr, | 492 | @backingInt(elf.PT.PHDR) => img_base = @intFromPtr(phdrs.ptr) - phdr.p_vaddr, |
| 493 | elf.PT_TLS => tls_phdr = phdr, | 493 | @backingInt(elf.PT.TLS) => tls_phdr = phdr, |
| 494 | else => {}, | 494 | else => {}, |
| 495 | } | 495 | } |
| 496 | } | 496 | } |
| ... | @@ -503,7 +503,7 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { | ... | @@ -503,7 +503,7 @@ fn computeAreaDesc(phdrs: []elf.Phdr) void { |
| 503 | align_factor = phdr.p_align; | 503 | align_factor = phdr.p_align; |
| 504 | 504 | ||
| 505 | // The effective size in memory is represented by `p_memsz`; the length of the data stored | 505 | // The effective size in memory is represented by `p_memsz`; the length of the data stored |
| 506 | // in the `PT_TLS` segment is `p_filesz` and may be less than the former. | 506 | // in the `PT.TLS` segment is `p_filesz` and may be less than the former. |
| 507 | block_init = @as([*]u8, @ptrFromInt(img_base + phdr.p_vaddr))[0..phdr.p_filesz]; | 507 | block_init = @as([*]u8, @ptrFromInt(img_base + phdr.p_vaddr))[0..phdr.p_filesz]; |
| 508 | block_size = phdr.p_memsz; | 508 | block_size = phdr.p_memsz; |
| 509 | } else { | 509 | } else { |
lib/std/os/linux/vdso.zig+2-2| ... | @@ -25,8 +25,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { | ... | @@ -25,8 +25,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 25 | // of the memory space (e.g. p_vaddr = 0xffffffffff700000 on WSL1). | 25 | // of the memory space (e.g. p_vaddr = 0xffffffffff700000 on WSL1). |
| 26 | // Wrapping operations are used on this line as well as subsequent calculations relative to base | 26 | // Wrapping operations are used on this line as well as subsequent calculations relative to base |
| 27 | // (lines 47, 78) to ensure no overflow check is tripped. | 27 | // (lines 47, 78) to ensure no overflow check is tripped. |
| 28 | elf.PT_LOAD => base = vdso_addr +% this_ph.p_offset -% this_ph.p_vaddr, | 28 | @backingInt(elf.PT.LOAD) => base = vdso_addr +% this_ph.p_offset -% this_ph.p_vaddr, |
| 29 | elf.PT_DYNAMIC => maybe_dynv = @as([*]usize, @ptrFromInt(vdso_addr + this_ph.p_offset)), | 29 | @backingInt(elf.PT.DYNAMIC) => maybe_dynv = @as([*]usize, @ptrFromInt(vdso_addr + this_ph.p_offset)), |
| 30 | else => {}, | 30 | else => {}, |
| 31 | } | 31 | } |
| 32 | } | 32 | } |
lib/std/pie.zig+1-1| ... | @@ -303,7 +303,7 @@ pub fn relocate(phdrs: []const elf.Phdr) void { | ... | @@ -303,7 +303,7 @@ pub fn relocate(phdrs: []const elf.Phdr) void { |
| 303 | // the theoretical load addresses for the `_DYNAMIC` symbol. | 303 | // the theoretical load addresses for the `_DYNAMIC` symbol. |
| 304 | const base_addr = base: { | 304 | const base_addr = base: { |
| 305 | for (phdrs) |*phdr| { | 305 | for (phdrs) |*phdr| { |
| 306 | if (phdr.p_type != elf.PT_DYNAMIC) continue; | 306 | if (phdr.p_type != @backingInt(elf.PT.DYNAMIC)) continue; |
| 307 | break :base @intFromPtr(dynv) - phdr.p_vaddr; | 307 | break :base @intFromPtr(dynv) - phdr.p_vaddr; |
| 308 | } | 308 | } |
| 309 | // This is not supposed to happen for well-formed binaries. | 309 | // This is not supposed to happen for well-formed binaries. |
lib/std/posix/test.zig+1-1| ... | @@ -75,7 +75,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -75,7 +75,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 75 | // Count how many libraries are loaded | 75 | // Count how many libraries are loaded |
| 76 | counter.* += @as(usize, 1); | 76 | counter.* += @as(usize, 1); |
| 77 | 77 | ||
| 78 | // The image should contain at least a PT_LOAD segment | 78 | // The image should contain at least a PT.LOAD segment |
| 79 | if (info.phnum < 1) return error.MissingPtLoadSegment; | 79 | if (info.phnum < 1) return error.MissingPtLoadSegment; |
| 80 | 80 | ||
| 81 | // Quick & dirty validation of the phdr pointers, make sure we're not | 81 | // Quick & dirty validation of the phdr pointers, make sure we're not |
lib/std/start.zig+2-2| ... | @@ -621,7 +621,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { | ... | @@ -621,7 +621,7 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.c) noreturn { |
| 621 | std.os.linux.tls.initStatic(phdrs); | 621 | std.os.linux.tls.initStatic(phdrs); |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | // The way Linux executables represent stack size is via the PT_GNU_STACK | 624 | // The way Linux executables represent stack size is via the PT.GNU_STACK |
| 625 | // program header. However the kernel does not recognize it; it always gives 8 MiB. | 625 | // program header. However the kernel does not recognize it; it always gives 8 MiB. |
| 626 | // Here we look for the stack size in our program headers and use setrlimit | 626 | // Here we look for the stack size in our program headers and use setrlimit |
| 627 | // to ask for more stack space. | 627 | // to ask for more stack space. |
| ... | @@ -649,7 +649,7 @@ fn expandStackSize(phdrs: []elf.Phdr) void { | ... | @@ -649,7 +649,7 @@ fn expandStackSize(phdrs: []elf.Phdr) void { |
| 649 | @disableInstrumentation(); | 649 | @disableInstrumentation(); |
| 650 | for (phdrs) |*phdr| { | 650 | for (phdrs) |*phdr| { |
| 651 | switch (phdr.p_type) { | 651 | switch (phdr.p_type) { |
| 652 | elf.PT_GNU_STACK => { | 652 | @backingInt(elf.PT.GNU_STACK) => { |
| 653 | if (phdr.p_memsz == 0) break; | 653 | if (phdr.p_memsz == 0) break; |
| 654 | assert(phdr.p_memsz % std.heap.page_size_min == 0); | 654 | assert(phdr.p_memsz % std.heap.page_size_min == 0); |
| 655 | 655 |
lib/std/zig/system.zig+4-4| ... | @@ -597,14 +597,14 @@ fn abiAndDynamicLinkerFromFile( | ... | @@ -597,14 +597,14 @@ fn abiAndDynamicLinkerFromFile( |
| 597 | .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), | 597 | .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), |
| 598 | .dynamic_linker = query.dynamic_linker orelse .none, | 598 | .dynamic_linker = query.dynamic_linker orelse .none, |
| 599 | }; | 599 | }; |
| 600 | var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC | 600 | var rpath_offset: ?u64 = null; // Found inside PT.DYNAMIC |
| 601 | const look_for_ld = query.dynamic_linker == null; | 601 | const look_for_ld = query.dynamic_linker == null; |
| 602 | 602 | ||
| 603 | var got_dyn_section: bool = false; | 603 | var got_dyn_section: bool = false; |
| 604 | { | 604 | { |
| 605 | var it = header.iterateProgramHeaders(file_reader); | 605 | var it = header.iterateProgramHeaders(file_reader); |
| 606 | while (try it.next()) |phdr| switch (phdr.p_type) { | 606 | while (try it.next()) |phdr| switch (phdr.p_type) { |
| 607 | elf.PT_INTERP => { | 607 | @backingInt(elf.PT.INTERP) => { |
| 608 | got_dyn_section = true; | 608 | got_dyn_section = true; |
| 609 | 609 | ||
| 610 | if (look_for_ld) { | 610 | if (look_for_ld) { |
| ... | @@ -613,7 +613,7 @@ fn abiAndDynamicLinkerFromFile( | ... | @@ -613,7 +613,7 @@ fn abiAndDynamicLinkerFromFile( |
| 613 | const filesz: usize = @intCast(p_filesz); | 613 | const filesz: usize = @intCast(p_filesz); |
| 614 | try file_reader.seekTo(phdr.p_offset); | 614 | try file_reader.seekTo(phdr.p_offset); |
| 615 | try file_reader.interface.readSliceAll(result.dynamic_linker.buffer[0..filesz]); | 615 | try file_reader.interface.readSliceAll(result.dynamic_linker.buffer[0..filesz]); |
| 616 | // PT_INTERP includes a null byte in filesz. | 616 | // PT.INTERP includes a null byte in filesz. |
| 617 | const len = filesz - 1; | 617 | const len = filesz - 1; |
| 618 | // dynamic_linker.max_byte is "max", not "len". | 618 | // dynamic_linker.max_byte is "max", not "len". |
| 619 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. | 619 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. |
| ... | @@ -631,7 +631,7 @@ fn abiAndDynamicLinkerFromFile( | ... | @@ -631,7 +631,7 @@ fn abiAndDynamicLinkerFromFile( |
| 631 | } | 631 | } |
| 632 | }, | 632 | }, |
| 633 | // We only need this for detecting glibc version. | 633 | // We only need this for detecting glibc version. |
| 634 | elf.PT_DYNAMIC => { | 634 | @backingInt(elf.PT.DYNAMIC) => { |
| 635 | got_dyn_section = true; | 635 | got_dyn_section = true; |
| 636 | 636 | ||
| 637 | if (builtin.target.os.tag == .linux and result.isGnuLibC() and query.glibc_version == null) { | 637 | if (builtin.target.os.tag == .linux and result.isGnuLibC() and query.glibc_version == null) { |
src/link/Elf.zig+35-35| ... | @@ -159,21 +159,21 @@ const ProgramHeaderIndex = enum(u16) { | ... | @@ -159,21 +159,21 @@ const ProgramHeaderIndex = enum(u16) { |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | const ProgramHeaderIndexes = struct { | 161 | const ProgramHeaderIndexes = struct { |
| 162 | /// PT_PHDR | 162 | /// PT.PHDR |
| 163 | table: OptionalProgramHeaderIndex = .none, | 163 | table: OptionalProgramHeaderIndex = .none, |
| 164 | /// PT_LOAD for PHDR table | 164 | /// PT.LOAD for PHDR table |
| 165 | /// We add this special load segment to ensure the EHDR and PHDR table are always | 165 | /// We add this special load segment to ensure the EHDR and PHDR table are always |
| 166 | /// loaded into memory. | 166 | /// loaded into memory. |
| 167 | table_load: OptionalProgramHeaderIndex = .none, | 167 | table_load: OptionalProgramHeaderIndex = .none, |
| 168 | /// PT_INTERP | 168 | /// PT.INTERP |
| 169 | interp: OptionalProgramHeaderIndex = .none, | 169 | interp: OptionalProgramHeaderIndex = .none, |
| 170 | /// PT_DYNAMIC | 170 | /// PT.DYNAMIC |
| 171 | dynamic: OptionalProgramHeaderIndex = .none, | 171 | dynamic: OptionalProgramHeaderIndex = .none, |
| 172 | /// PT_GNU_EH_FRAME | 172 | /// PT.GNU_EH_FRAME |
| 173 | gnu_eh_frame: OptionalProgramHeaderIndex = .none, | 173 | gnu_eh_frame: OptionalProgramHeaderIndex = .none, |
| 174 | /// PT_GNU_STACK | 174 | /// PT.GNU_STACK |
| 175 | gnu_stack: OptionalProgramHeaderIndex = .none, | 175 | gnu_stack: OptionalProgramHeaderIndex = .none, |
| 176 | /// PT_TLS | 176 | /// PT.TLS |
| 177 | /// TODO I think ELF permits multiple TLS segments but for now, assume one per file. | 177 | /// TODO I think ELF permits multiple TLS segments but for now, assume one per file. |
| 178 | tls: OptionalProgramHeaderIndex = .none, | 178 | tls: OptionalProgramHeaderIndex = .none, |
| 179 | }; | 179 | }; |
| ... | @@ -334,7 +334,7 @@ pub fn createEmpty( | ... | @@ -334,7 +334,7 @@ pub fn createEmpty( |
| 334 | if (!is_obj_or_ar) { | 334 | if (!is_obj_or_ar) { |
| 335 | try self.dynstrtab.append(gpa, 0); | 335 | try self.dynstrtab.append(gpa, 0); |
| 336 | 336 | ||
| 337 | // Initialize PT_PHDR program header | 337 | // Initialize PT.PHDR program header |
| 338 | const p_align: u16 = switch (self.ptr_width) { | 338 | const p_align: u16 = switch (self.ptr_width) { |
| 339 | .p32 => @alignOf(elf.Elf32_Phdr), | 339 | .p32 => @alignOf(elf.Elf32_Phdr), |
| 340 | .p64 => @alignOf(elf.Elf64_Phdr), | 340 | .p64 => @alignOf(elf.Elf64_Phdr), |
| ... | @@ -350,7 +350,7 @@ pub fn createEmpty( | ... | @@ -350,7 +350,7 @@ pub fn createEmpty( |
| 350 | const max_nphdrs = comptime getMaxNumberOfPhdrs(); | 350 | const max_nphdrs = comptime getMaxNumberOfPhdrs(); |
| 351 | const reserved: u64 = mem.alignForward(u64, padToIdeal(max_nphdrs * phsize), self.page_size); | 351 | const reserved: u64 = mem.alignForward(u64, padToIdeal(max_nphdrs * phsize), self.page_size); |
| 352 | self.phdr_indexes.table = (try self.addPhdr(.{ | 352 | self.phdr_indexes.table = (try self.addPhdr(.{ |
| 353 | .type = elf.PT_PHDR, | 353 | .type = @backingInt(elf.PT.PHDR), |
| 354 | .flags = elf.PF_R, | 354 | .flags = elf.PF_R, |
| 355 | .@"align" = p_align, | 355 | .@"align" = p_align, |
| 356 | .addr = self.image_base + ehsize, | 356 | .addr = self.image_base + ehsize, |
| ... | @@ -359,7 +359,7 @@ pub fn createEmpty( | ... | @@ -359,7 +359,7 @@ pub fn createEmpty( |
| 359 | .memsz = reserved, | 359 | .memsz = reserved, |
| 360 | })).toOptional(); | 360 | })).toOptional(); |
| 361 | self.phdr_indexes.table_load = (try self.addPhdr(.{ | 361 | self.phdr_indexes.table_load = (try self.addPhdr(.{ |
| 362 | .type = elf.PT_LOAD, | 362 | .type = @backingInt(elf.PT.LOAD), |
| 363 | .flags = elf.PF_R, | 363 | .flags = elf.PF_R, |
| 364 | .@"align" = self.page_size, | 364 | .@"align" = self.page_size, |
| 365 | .addr = self.image_base, | 365 | .addr = self.image_base, |
| ... | @@ -514,7 +514,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { | ... | @@ -514,7 +514,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | for (self.phdrs.items) |phdr| { | 516 | for (self.phdrs.items) |phdr| { |
| 517 | if (phdr.p_type != elf.PT_LOAD) continue; | 517 | if (phdr.p_type != @backingInt(elf.PT.LOAD)) continue; |
| 518 | const increased_size = padToIdeal(phdr.p_filesz); | 518 | const increased_size = padToIdeal(phdr.p_filesz); |
| 519 | const test_end = phdr.p_offset +| increased_size; | 519 | const test_end = phdr.p_offset +| increased_size; |
| 520 | if (start < test_end) { | 520 | if (start < test_end) { |
| ... | @@ -2091,26 +2091,26 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -2091,26 +2091,26 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 2091 | 2091 | ||
| 2092 | if (self.section_indexes.interp != null and self.phdr_indexes.interp == .none) { | 2092 | if (self.section_indexes.interp != null and self.phdr_indexes.interp == .none) { |
| 2093 | self.phdr_indexes.interp = (try self.addPhdr(.{ | 2093 | self.phdr_indexes.interp = (try self.addPhdr(.{ |
| 2094 | .type = elf.PT_INTERP, | 2094 | .type = @backingInt(elf.PT.INTERP), |
| 2095 | .flags = elf.PF_R, | 2095 | .flags = elf.PF_R, |
| 2096 | .@"align" = 1, | 2096 | .@"align" = 1, |
| 2097 | })).toOptional(); | 2097 | })).toOptional(); |
| 2098 | } | 2098 | } |
| 2099 | if (self.section_indexes.dynamic != null and self.phdr_indexes.dynamic == .none) { | 2099 | if (self.section_indexes.dynamic != null and self.phdr_indexes.dynamic == .none) { |
| 2100 | self.phdr_indexes.dynamic = (try self.addPhdr(.{ | 2100 | self.phdr_indexes.dynamic = (try self.addPhdr(.{ |
| 2101 | .type = elf.PT_DYNAMIC, | 2101 | .type = @backingInt(elf.PT.DYNAMIC), |
| 2102 | .flags = elf.PF_R | elf.PF_W, | 2102 | .flags = elf.PF_R | elf.PF_W, |
| 2103 | })).toOptional(); | 2103 | })).toOptional(); |
| 2104 | } | 2104 | } |
| 2105 | if (self.section_indexes.eh_frame_hdr != null and self.phdr_indexes.gnu_eh_frame == .none) { | 2105 | if (self.section_indexes.eh_frame_hdr != null and self.phdr_indexes.gnu_eh_frame == .none) { |
| 2106 | self.phdr_indexes.gnu_eh_frame = (try self.addPhdr(.{ | 2106 | self.phdr_indexes.gnu_eh_frame = (try self.addPhdr(.{ |
| 2107 | .type = elf.PT_GNU_EH_FRAME, | 2107 | .type = @backingInt(elf.PT.GNU_EH_FRAME), |
| 2108 | .flags = elf.PF_R, | 2108 | .flags = elf.PF_R, |
| 2109 | })).toOptional(); | 2109 | })).toOptional(); |
| 2110 | } | 2110 | } |
| 2111 | if (self.phdr_indexes.gnu_stack == .none) { | 2111 | if (self.phdr_indexes.gnu_stack == .none) { |
| 2112 | self.phdr_indexes.gnu_stack = (try self.addPhdr(.{ | 2112 | self.phdr_indexes.gnu_stack = (try self.addPhdr(.{ |
| 2113 | .type = elf.PT_GNU_STACK, | 2113 | .type = @backingInt(elf.PT.GNU_STACK), |
| 2114 | .flags = elf.PF_W | elf.PF_R, | 2114 | .flags = elf.PF_W | elf.PF_R, |
| 2115 | .memsz = self.base.stack_size, | 2115 | .memsz = self.base.stack_size, |
| 2116 | .@"align" = 1, | 2116 | .@"align" = 1, |
| ... | @@ -2122,7 +2122,7 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -2122,7 +2122,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 2122 | } else false; | 2122 | } else false; |
| 2123 | if (has_tls and self.phdr_indexes.tls == .none) { | 2123 | if (has_tls and self.phdr_indexes.tls == .none) { |
| 2124 | self.phdr_indexes.tls = (try self.addPhdr(.{ | 2124 | self.phdr_indexes.tls = (try self.addPhdr(.{ |
| 2125 | .type = elf.PT_TLS, | 2125 | .type = @backingInt(elf.PT.TLS), |
| 2126 | .flags = elf.PF_R, | 2126 | .flags = elf.PF_R, |
| 2127 | .@"align" = 1, | 2127 | .@"align" = 1, |
| 2128 | })).toOptional(); | 2128 | })).toOptional(); |
| ... | @@ -2262,13 +2262,13 @@ fn setHashSections(self: *Elf) !void { | ... | @@ -2262,13 +2262,13 @@ fn setHashSections(self: *Elf) !void { |
| 2262 | 2262 | ||
| 2263 | fn phdrRank(phdr: elf.Elf64_Phdr) u8 { | 2263 | fn phdrRank(phdr: elf.Elf64_Phdr) u8 { |
| 2264 | return switch (phdr.p_type) { | 2264 | return switch (phdr.p_type) { |
| 2265 | elf.PT_NULL => 0, | 2265 | @backingInt(elf.PT.NULL) => 0, |
| 2266 | elf.PT_PHDR => 1, | 2266 | @backingInt(elf.PT.PHDR) => 1, |
| 2267 | elf.PT_INTERP => 2, | 2267 | @backingInt(elf.PT.INTERP) => 2, |
| 2268 | elf.PT_LOAD => 3, | 2268 | @backingInt(elf.PT.LOAD) => 3, |
| 2269 | elf.PT_DYNAMIC, elf.PT_TLS => 4, | 2269 | @backingInt(elf.PT.DYNAMIC), @backingInt(elf.PT.TLS) => 4, |
| 2270 | elf.PT_GNU_EH_FRAME => 5, | 2270 | @backingInt(elf.PT.GNU_EH_FRAME) => 5, |
| 2271 | elf.PT_GNU_STACK => 6, | 2271 | @backingInt(elf.PT.GNU_STACK) => 6, |
| 2272 | else => 7, | 2272 | else => 7, |
| 2273 | }; | 2273 | }; |
| 2274 | } | 2274 | } |
| ... | @@ -2655,8 +2655,8 @@ fn addLoadPhdrs(self: *Elf) error{OutOfMemory}!void { | ... | @@ -2655,8 +2655,8 @@ fn addLoadPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 2655 | if (shdr.sh_type == elf.SHT_NULL) continue; | 2655 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 2656 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 2656 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 2657 | const flags = shdrToPhdrFlags(shdr.sh_flags); | 2657 | const flags = shdrToPhdrFlags(shdr.sh_flags); |
| 2658 | if (self.getPhdr(.{ .flags = flags, .type = elf.PT_LOAD }) == .none) { | 2658 | if (self.getPhdr(.{ .flags = flags, .type = @backingInt(elf.PT.LOAD) }) == .none) { |
| 2659 | _ = try self.addPhdr(.{ .flags = flags, .type = elf.PT_LOAD }); | 2659 | _ = try self.addPhdr(.{ .flags = flags, .type = @backingInt(elf.PT.LOAD) }); |
| 2660 | } | 2660 | } |
| 2661 | } | 2661 | } |
| 2662 | } | 2662 | } |
| ... | @@ -2817,7 +2817,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -2817,7 +2817,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 2817 | } | 2817 | } |
| 2818 | 2818 | ||
| 2819 | const first = slice.items(.shdr)[cover.items[0]]; | 2819 | const first = slice.items(.shdr)[cover.items[0]]; |
| 2820 | const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).unwrap().?; | 2820 | const phndx = self.getPhdr(.{ .type = @backingInt(elf.PT.LOAD), .flags = shdrToPhdrFlags(first.sh_flags) }).unwrap().?; |
| 2821 | const phdr = &self.phdrs.items[phndx.int()]; | 2821 | const phdr = &self.phdrs.items[phndx.int()]; |
| 2822 | const allocated_size = self.allocatedSize(phdr.p_offset); | 2822 | const allocated_size = self.allocatedSize(phdr.p_offset); |
| 2823 | if (filesz > allocated_size) { | 2823 | if (filesz > allocated_size) { |
| ... | @@ -3906,15 +3906,15 @@ fn formatPhdr(ctx: FormatPhdr, writer: *std.Io.Writer) std.Io.Writer.Error!void | ... | @@ -3906,15 +3906,15 @@ fn formatPhdr(ctx: FormatPhdr, writer: *std.Io.Writer) std.Io.Writer.Error!void |
| 3906 | if (write) flags[1] = 'W'; | 3906 | if (write) flags[1] = 'W'; |
| 3907 | if (read) flags[2] = 'R'; | 3907 | if (read) flags[2] = 'R'; |
| 3908 | const p_type = switch (phdr.p_type) { | 3908 | const p_type = switch (phdr.p_type) { |
| 3909 | elf.PT_LOAD => "LOAD", | 3909 | @backingInt(elf.PT.LOAD) => "LOAD", |
| 3910 | elf.PT_TLS => "TLS", | 3910 | @backingInt(elf.PT.TLS) => "TLS", |
| 3911 | elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME", | 3911 | @backingInt(elf.PT.GNU_EH_FRAME) => "GNU_EH_FRAME", |
| 3912 | elf.PT_GNU_STACK => "GNU_STACK", | 3912 | @backingInt(elf.PT.GNU_STACK) => "GNU_STACK", |
| 3913 | elf.PT_DYNAMIC => "DYNAMIC", | 3913 | @backingInt(elf.PT.DYNAMIC) => "DYNAMIC", |
| 3914 | elf.PT_INTERP => "INTERP", | 3914 | @backingInt(elf.PT.INTERP) => "INTERP", |
| 3915 | elf.PT_NULL => "NULL", | 3915 | @backingInt(elf.PT.NULL) => "NULL", |
| 3916 | elf.PT_PHDR => "PHDR", | 3916 | @backingInt(elf.PT.PHDR) => "PHDR", |
| 3917 | elf.PT_NOTE => "NOTE", | 3917 | @backingInt(elf.PT.NOTE) => "NOTE", |
| 3918 | else => "UNKNOWN", | 3918 | else => "UNKNOWN", |
| 3919 | }; | 3919 | }; |
| 3920 | try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{ | 3920 | try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{ |
src/link/Lld.zig+2-2| ... | @@ -1021,8 +1021,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { | ... | @@ -1021,8 +1021,8 @@ fn elfLink(lld: *Lld, arena: Allocator) !void { |
| 1021 | } | 1021 | } |
| 1022 | 1022 | ||
| 1023 | if (is_exe_or_dyn_lib and target.os.tag == .netbsd) { | 1023 | if (is_exe_or_dyn_lib and target.os.tag == .netbsd) { |
| 1024 | // Add options to produce shared objects with only 2 PT_LOAD segments. | 1024 | // Add options to produce shared objects with only 2 PT.LOAD segments. |
| 1025 | // NetBSD expects 2 PT_LOAD segments in a shared object, otherwise | 1025 | // NetBSD expects 2 PT.LOAD segments in a shared object, otherwise |
| 1026 | // ld.elf_so fails loading dynamic libraries with "not found" error. | 1026 | // ld.elf_so fails loading dynamic libraries with "not found" error. |
| 1027 | // See https://github.com/ziglang/zig/issues/9109 . | 1027 | // See https://github.com/ziglang/zig/issues/9109 . |
| 1028 | try argv.append("--no-rosegment"); | 1028 | try argv.append("--no-rosegment"); |