| author | |
| committer | |
| log | a9d3885ac7529e3b1dde3def42ac3da2874dd774 |
| tree | 85be0fe31caf963c7d61c6c34c33514233558709 |
| parent | a6bf762a8ba3672c40e369f832d38f864d86fbd9 |
12 files changed, 336 insertions(+), 455 deletions(-)
src/link/Dwarf.zig+4-4| ... | @@ -317,7 +317,7 @@ pub const Section = struct { | ... | @@ -317,7 +317,7 @@ pub const Section = struct { |
| 317 | fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void { | 317 | fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void { |
| 318 | if (dwarf.bin_file.cast(.elf)) |elf_file| { | 318 | if (dwarf.bin_file.cast(.elf)) |elf_file| { |
| 319 | try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true); | 319 | try elf_file.growNonAllocSection(sec.index, len, @intCast(sec.alignment.toByteUnits().?), true); |
| 320 | const shdr = &elf_file.shdrs.items[sec.index]; | 320 | const shdr = &elf_file.sections.items(.shdr)[sec.index]; |
| 321 | sec.off = shdr.sh_offset; | 321 | sec.off = shdr.sh_offset; |
| 322 | sec.len = shdr.sh_size; | 322 | sec.len = shdr.sh_size; |
| 323 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { | 323 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { |
| ... | @@ -340,7 +340,7 @@ pub const Section = struct { | ... | @@ -340,7 +340,7 @@ pub const Section = struct { |
| 340 | sec.off += len; | 340 | sec.off += len; |
| 341 | sec.len -= len; | 341 | sec.len -= len; |
| 342 | if (dwarf.bin_file.cast(.elf)) |elf_file| { | 342 | if (dwarf.bin_file.cast(.elf)) |elf_file| { |
| 343 | const shdr = &elf_file.shdrs.items[sec.index]; | 343 | const shdr = &elf_file.sections.items(.shdr)[sec.index]; |
| 344 | shdr.sh_offset = sec.off; | 344 | shdr.sh_offset = sec.off; |
| 345 | shdr.sh_size = sec.len; | 345 | shdr.sh_size = sec.len; |
| 346 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { | 346 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { |
| ... | @@ -771,7 +771,7 @@ const Entry = struct { | ... | @@ -771,7 +771,7 @@ const Entry = struct { |
| 771 | log.err("missing {} from {s}", .{ | 771 | log.err("missing {} from {s}", .{ |
| 772 | @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)), | 772 | @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)), |
| 773 | std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file| | 773 | std.mem.sliceTo(if (dwarf.bin_file.cast(.elf)) |elf_file| |
| 774 | elf_file.shstrtab.items[elf_file.shdrs.items[sec.index].sh_name..] | 774 | elf_file.shstrtab.items[elf_file.sections.items(.shdr)[sec.index].sh_name..] |
| 775 | else if (dwarf.bin_file.cast(.macho)) |macho_file| | 775 | else if (dwarf.bin_file.cast(.macho)) |macho_file| |
| 776 | if (macho_file.d_sym) |*d_sym| | 776 | if (macho_file.d_sym) |*d_sym| |
| 777 | &d_sym.sections.items[sec.index].segname | 777 | &d_sym.sections.items[sec.index].segname |
| ... | @@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { | ... | @@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { |
| 1529 | elf_file.debug_rnglists_section_index.?, | 1529 | elf_file.debug_rnglists_section_index.?, |
| 1530 | elf_file.debug_str_section_index.?, | 1530 | elf_file.debug_str_section_index.?, |
| 1531 | }) |sec, section_index| { | 1531 | }) |sec, section_index| { |
| 1532 | const shdr = &elf_file.shdrs.items[section_index]; | 1532 | const shdr = &elf_file.sections.items(.shdr)[section_index]; |
| 1533 | sec.index = section_index; | 1533 | sec.index = section_index; |
| 1534 | sec.off = shdr.sh_offset; | 1534 | sec.off = shdr.sh_offset; |
| 1535 | sec.len = shdr.sh_size; | 1535 | sec.len = shdr.sh_size; |
src/link/Elf.zig+168-256| ... | @@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null, | ... | @@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null, |
| 45 | objects: std.ArrayListUnmanaged(File.Index) = .{}, | 45 | objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| 46 | shared_objects: std.ArrayListUnmanaged(File.Index) = .{}, | 46 | shared_objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| 47 | 47 | ||
| 48 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. | 48 | /// List of all output sections and their associated metadata. |
| 49 | /// Same order as in the file. | 49 | sections: std.MultiArrayList(Section) = .{}, |
| 50 | shdrs: std.ArrayListUnmanaged(elf.Elf64_Shdr) = .{}, | ||
| 51 | /// Given index to a section, pulls index of containing phdr if any. | ||
| 52 | phdr_to_shdr_table: std.AutoHashMapUnmanaged(u32, u32) = .{}, | ||
| 53 | /// File offset into the shdr table. | 50 | /// File offset into the shdr table. |
| 54 | shdr_table_offset: ?u64 = null, | 51 | shdr_table_offset: ?u64 = null, |
| 55 | /// Table of lists of atoms per output section. | ||
| 56 | /// This table is not used to track incrementally generated atoms. | ||
| 57 | output_sections: std.AutoArrayHashMapUnmanaged(u32, std.ArrayListUnmanaged(Ref)) = .{}, | ||
| 58 | output_rela_sections: std.AutoArrayHashMapUnmanaged(u32, RelaSection) = .{}, | ||
| 59 | 52 | ||
| 60 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. | 53 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 61 | /// Same order as in the file. | 54 | /// Same order as in the file. |
| ... | @@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{}, | ... | @@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{}, |
| 181 | /// List of output merge sections with deduped contents. | 174 | /// List of output merge sections with deduped contents. |
| 182 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .{}, | 175 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .{}, |
| 183 | 176 | ||
| 184 | /// Table of last atom index in a section and matching atom free list if any. | ||
| 185 | last_atom_and_free_list_table: LastAtomAndFreeListTable = .{}, | ||
| 186 | |||
| 187 | first_eflags: ?elf.Elf64_Word = null, | 177 | first_eflags: ?elf.Elf64_Word = null, |
| 188 | 178 | ||
| 189 | /// When allocating, the ideal_capacity is calculated by | 179 | /// When allocating, the ideal_capacity is calculated by |
| ... | @@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void { | ... | @@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void { |
| 429 | self.objects.deinit(gpa); | 419 | self.objects.deinit(gpa); |
| 430 | self.shared_objects.deinit(gpa); | 420 | self.shared_objects.deinit(gpa); |
| 431 | 421 | ||
| 432 | self.shdrs.deinit(gpa); | 422 | for (self.sections.items(.atom_list), self.sections.items(.free_list)) |*atoms, *free_list| { |
| 433 | self.phdr_to_shdr_table.deinit(gpa); | 423 | atoms.deinit(gpa); |
| 434 | self.phdrs.deinit(gpa); | 424 | free_list.deinit(gpa); |
| 435 | for (self.output_sections.values()) |*list| { | ||
| 436 | list.deinit(gpa); | ||
| 437 | } | 425 | } |
| 438 | self.output_sections.deinit(gpa); | 426 | self.sections.deinit(gpa); |
| 439 | for (self.output_rela_sections.values()) |*sec| { | 427 | self.phdrs.deinit(gpa); |
| 440 | sec.atom_list.deinit(gpa); | ||
| 441 | } | ||
| 442 | self.output_rela_sections.deinit(gpa); | ||
| 443 | self.shstrtab.deinit(gpa); | 428 | self.shstrtab.deinit(gpa); |
| 444 | self.symtab.deinit(gpa); | 429 | self.symtab.deinit(gpa); |
| 445 | self.strtab.deinit(gpa); | 430 | self.strtab.deinit(gpa); |
| ... | @@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void { | ... | @@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void { |
| 453 | sect.deinit(gpa); | 438 | sect.deinit(gpa); |
| 454 | } | 439 | } |
| 455 | self.merge_sections.deinit(gpa); | 440 | self.merge_sections.deinit(gpa); |
| 456 | for (self.last_atom_and_free_list_table.values()) |*value| { | ||
| 457 | value.free_list.deinit(gpa); | ||
| 458 | } | ||
| 459 | self.last_atom_and_free_list_table.deinit(gpa); | ||
| 460 | 441 | ||
| 461 | self.got.deinit(gpa); | 442 | self.got.deinit(gpa); |
| 462 | self.plt.deinit(gpa); | 443 | self.plt.deinit(gpa); |
| ... | @@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { | ... | @@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { |
| 505 | 486 | ||
| 506 | if (self.shdr_table_offset) |off| { | 487 | if (self.shdr_table_offset) |off| { |
| 507 | const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); | 488 | const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); |
| 508 | const tight_size = self.shdrs.items.len * shdr_size; | 489 | const tight_size = self.sections.items(.shdr).len * shdr_size; |
| 509 | const increased_size = padToIdeal(tight_size); | 490 | const increased_size = padToIdeal(tight_size); |
| 510 | const test_end = off +| increased_size; | 491 | const test_end = off +| increased_size; |
| 511 | if (start < test_end) { | 492 | if (start < test_end) { |
| ... | @@ -514,7 +495,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { | ... | @@ -514,7 +495,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { |
| 514 | } | 495 | } |
| 515 | } | 496 | } |
| 516 | 497 | ||
| 517 | for (self.shdrs.items) |shdr| { | 498 | for (self.sections.items(.shdr)) |shdr| { |
| 518 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 499 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 519 | const increased_size = padToIdeal(shdr.sh_size); | 500 | const increased_size = padToIdeal(shdr.sh_size); |
| 520 | const test_end = shdr.sh_offset +| increased_size; | 501 | const test_end = shdr.sh_offset +| increased_size; |
| ... | @@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { | ... | @@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { |
| 544 | if (self.shdr_table_offset) |off| { | 525 | if (self.shdr_table_offset) |off| { |
| 545 | if (off > start and off < min_pos) min_pos = off; | 526 | if (off > start and off < min_pos) min_pos = off; |
| 546 | } | 527 | } |
| 547 | for (self.shdrs.items) |section| { | 528 | for (self.sections.items(.shdr)) |section| { |
| 548 | if (section.sh_offset <= start) continue; | 529 | if (section.sh_offset <= start) continue; |
| 549 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; | 530 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; |
| 550 | } | 531 | } |
| ... | @@ -574,8 +555,12 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { | ... | @@ -574,8 +555,12 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { |
| 574 | } | 555 | } |
| 575 | 556 | ||
| 576 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | 557 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 577 | const shdr = &self.shdrs.items[shdr_index]; | 558 | const slice = self.sections.slice(); |
| 578 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; | 559 | const shdr = &slice.items(.shdr)[shdr_index]; |
| 560 | assert(shdr.sh_flags & elf.SHF_ALLOC != 0); | ||
| 561 | const phndx = slice.items(.phndx)[shdr_index]; | ||
| 562 | const phdr = &self.phdrs.items[phndx]; | ||
| 563 | |||
| 579 | log.debug("allocated size {x} of {s}, needed size {x}", .{ | 564 | log.debug("allocated size {x} of {s}, needed size {x}", .{ |
| 580 | self.allocatedSize(shdr.sh_offset), | 565 | self.allocatedSize(shdr.sh_offset), |
| 581 | self.getShString(shdr.sh_name), | 566 | self.getShString(shdr.sh_name), |
| ... | @@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | ... | @@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 590 | const existing_size = shdr.sh_size; | 575 | const existing_size = shdr.sh_size; |
| 591 | shdr.sh_size = 0; | 576 | shdr.sh_size = 0; |
| 592 | // Must move the entire section. | 577 | // Must move the entire section. |
| 593 | const alignment = if (maybe_phdr) |phdr| phdr.p_align else shdr.sh_addralign; | 578 | const alignment = if (phdr.p_type == elf.PT_NULL) shdr.sh_addralign else phdr.p_align; |
| 594 | const new_offset = try self.findFreeSpace(needed_size, alignment); | 579 | const new_offset = try self.findFreeSpace(needed_size, alignment); |
| 595 | 580 | ||
| 596 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ | 581 | log.debug("new '{s}' file offset 0x{x} to 0x{x}", .{ |
| ... | @@ -604,19 +589,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | ... | @@ -604,19 +589,17 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 604 | if (amt != existing_size) return error.InputOutput; | 589 | if (amt != existing_size) return error.InputOutput; |
| 605 | 590 | ||
| 606 | shdr.sh_offset = new_offset; | 591 | shdr.sh_offset = new_offset; |
| 607 | if (maybe_phdr) |phdr| phdr.p_offset = new_offset; | 592 | if (phdr.p_type != elf.PT_NULL) phdr.p_offset = new_offset; |
| 608 | } | 593 | } |
| 609 | if (maybe_phdr) |phdr| phdr.p_filesz = needed_size; | 594 | if (phdr.p_type != elf.PT_NULL) phdr.p_filesz = needed_size; |
| 610 | } | 595 | } |
| 611 | shdr.sh_size = needed_size; | 596 | shdr.sh_size = needed_size; |
| 612 | 597 | ||
| 613 | if (maybe_phdr) |phdr| { | 598 | if (phdr.p_type != elf.PT_NULL) { |
| 614 | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); | 599 | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); |
| 615 | if (needed_size > mem_capacity) { | 600 | if (needed_size > mem_capacity) { |
| 616 | var err = try self.base.addErrorWithNotes(2); | 601 | var err = try self.base.addErrorWithNotes(2); |
| 617 | try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{ | 602 | try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{phndx}); |
| 618 | self.phdr_to_shdr_table.get(shdr_index).?, | ||
| 619 | }); | ||
| 620 | try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{}); | 603 | try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{}); |
| 621 | try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{}); | 604 | try err.addNote("as a workaround, try increasing pre-allocated virtual memory of each segment", .{}); |
| 622 | } | 605 | } |
| ... | @@ -634,7 +617,8 @@ pub fn growNonAllocSection( | ... | @@ -634,7 +617,8 @@ pub fn growNonAllocSection( |
| 634 | min_alignment: u32, | 617 | min_alignment: u32, |
| 635 | requires_file_copy: bool, | 618 | requires_file_copy: bool, |
| 636 | ) !void { | 619 | ) !void { |
| 637 | const shdr = &self.shdrs.items[shdr_index]; | 620 | const shdr = &self.sections.items(.shdr)[shdr_index]; |
| 621 | assert(shdr.sh_flags & elf.SHF_ALLOC == 0); | ||
| 638 | 622 | ||
| 639 | const allocated_size = self.allocatedSize(shdr.sh_offset); | 623 | const allocated_size = self.allocatedSize(shdr.sh_offset); |
| 640 | if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { | 624 | if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) { |
| ... | @@ -1018,7 +1002,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod | ... | @@ -1018,7 +1002,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod |
| 1018 | const atom_ptr = zo.atom(atom_index) orelse continue; | 1002 | const atom_ptr = zo.atom(atom_index) orelse continue; |
| 1019 | if (!atom_ptr.alive) continue; | 1003 | if (!atom_ptr.alive) continue; |
| 1020 | const out_shndx = atom_ptr.output_section_index; | 1004 | const out_shndx = atom_ptr.output_section_index; |
| 1021 | const shdr = &self.shdrs.items[out_shndx]; | 1005 | const shdr = &self.sections.items(.shdr)[out_shndx]; |
| 1022 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 1006 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1023 | const code = try zo.codeAlloc(self, atom_index); | 1007 | const code = try zo.codeAlloc(self, atom_index); |
| 1024 | defer gpa.free(code); | 1008 | defer gpa.free(code); |
| ... | @@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void { | ... | @@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2382 | }; | 2366 | }; |
| 2383 | 2367 | ||
| 2384 | const shoff = self.shdr_table_offset orelse 0; | 2368 | const shoff = self.shdr_table_offset orelse 0; |
| 2385 | const needed_size = self.shdrs.items.len * shsize; | 2369 | const needed_size = self.sections.items(.shdr).len * shsize; |
| 2386 | 2370 | ||
| 2387 | if (needed_size > self.allocatedSize(shoff)) { | 2371 | if (needed_size > self.allocatedSize(shoff)) { |
| 2388 | self.shdr_table_offset = null; | 2372 | self.shdr_table_offset = null; |
| ... | @@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void { | ... | @@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2396 | 2380 | ||
| 2397 | switch (self.ptr_width) { | 2381 | switch (self.ptr_width) { |
| 2398 | .p32 => { | 2382 | .p32 => { |
| 2399 | const buf = try gpa.alloc(elf.Elf32_Shdr, self.shdrs.items.len); | 2383 | const buf = try gpa.alloc(elf.Elf32_Shdr, self.sections.items(.shdr).len); |
| 2400 | defer gpa.free(buf); | 2384 | defer gpa.free(buf); |
| 2401 | 2385 | ||
| 2402 | for (buf, 0..) |*shdr, i| { | 2386 | for (buf, 0..) |*shdr, i| { |
| 2403 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); | 2387 | assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64)); |
| 2404 | shdr.* = shdrTo32(self.shdrs.items[i]); | 2388 | shdr.* = shdrTo32(self.sections.items(.shdr)[i]); |
| 2405 | if (foreign_endian) { | 2389 | if (foreign_endian) { |
| 2406 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); | 2390 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| 2407 | } | 2391 | } |
| ... | @@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void { | ... | @@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2409 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); | 2393 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 2410 | }, | 2394 | }, |
| 2411 | .p64 => { | 2395 | .p64 => { |
| 2412 | const buf = try gpa.alloc(elf.Elf64_Shdr, self.shdrs.items.len); | 2396 | const buf = try gpa.alloc(elf.Elf64_Shdr, self.sections.items(.shdr).len); |
| 2413 | defer gpa.free(buf); | 2397 | defer gpa.free(buf); |
| 2414 | 2398 | ||
| 2415 | for (buf, 0..) |*shdr, i| { | 2399 | for (buf, 0..) |*shdr, i| { |
| 2416 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); | 2400 | assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64)); |
| 2417 | shdr.* = self.shdrs.items[i]; | 2401 | shdr.* = self.sections.items(.shdr)[i]; |
| 2418 | if (foreign_endian) { | 2402 | if (foreign_endian) { |
| 2419 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); | 2403 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| 2420 | } | 2404 | } |
| ... | @@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void { | ... | @@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2582 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian); | 2566 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian); |
| 2583 | index += 2; | 2567 | index += 2; |
| 2584 | 2568 | ||
| 2585 | const e_shnum = @as(u16, @intCast(self.shdrs.items.len)); | 2569 | const e_shnum = @as(u16, @intCast(self.sections.items(.shdr).len)); |
| 2586 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); | 2570 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); |
| 2587 | index += 2; | 2571 | index += 2; |
| 2588 | 2572 | ||
| ... | @@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void { | ... | @@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void { |
| 2741 | msec.updateSize(); | 2725 | msec.updateSize(); |
| 2742 | } | 2726 | } |
| 2743 | for (self.merge_sections.items) |*msec| { | 2727 | for (self.merge_sections.items) |*msec| { |
| 2744 | const shdr = &self.shdrs.items[msec.output_section_index]; | 2728 | const shdr = &self.sections.items(.shdr)[msec.output_section_index]; |
| 2745 | const offset = msec.alignment.forward(shdr.sh_size); | 2729 | const offset = msec.alignment.forward(shdr.sh_size); |
| 2746 | const padding = offset - shdr.sh_size; | 2730 | const padding = offset - shdr.sh_size; |
| 2747 | msec.value = @intCast(offset); | 2731 | msec.value = @intCast(offset); |
| ... | @@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void { | ... | @@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void { |
| 2757 | defer buffer.deinit(); | 2741 | defer buffer.deinit(); |
| 2758 | 2742 | ||
| 2759 | for (self.merge_sections.items) |*msec| { | 2743 | for (self.merge_sections.items) |*msec| { |
| 2760 | const shdr = self.shdrs.items[msec.output_section_index]; | 2744 | const shdr = self.sections.items(.shdr)[msec.output_section_index]; |
| 2761 | const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow; | 2745 | const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow; |
| 2762 | const size = math.cast(usize, msec.size) orelse return error.Overflow; | 2746 | const size = math.cast(usize, msec.size) orelse return error.Overflow; |
| 2763 | try buffer.ensureTotalCapacity(size); | 2747 | try buffer.ensureTotalCapacity(size); |
| ... | @@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3045 | .@"align" = 1, | 3029 | .@"align" = 1, |
| 3046 | }); | 3030 | }); |
| 3047 | 3031 | ||
| 3048 | const has_tls = for (self.shdrs.items) |shdr| { | 3032 | const has_tls = for (self.sections.items(.shdr)) |shdr| { |
| 3049 | if (shdr.sh_flags & elf.SHF_TLS != 0) break true; | 3033 | if (shdr.sh_flags & elf.SHF_TLS != 0) break true; |
| 3050 | } else false; | 3034 | } else false; |
| 3051 | if (has_tls) { | 3035 | if (has_tls) { |
| ... | @@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void { | ... | @@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3074 | /// we are about to sort. | 3058 | /// we are about to sort. |
| 3075 | fn sortInitFini(self: *Elf) !void { | 3059 | fn sortInitFini(self: *Elf) !void { |
| 3076 | const gpa = self.base.comp.gpa; | 3060 | const gpa = self.base.comp.gpa; |
| 3061 | const slice = self.sections.slice(); | ||
| 3077 | 3062 | ||
| 3078 | const Entry = struct { | 3063 | const Entry = struct { |
| 3079 | priority: i32, | 3064 | priority: i32, |
| ... | @@ -3087,7 +3072,7 @@ fn sortInitFini(self: *Elf) !void { | ... | @@ -3087,7 +3072,7 @@ fn sortInitFini(self: *Elf) !void { |
| 3087 | } | 3072 | } |
| 3088 | }; | 3073 | }; |
| 3089 | 3074 | ||
| 3090 | for (self.shdrs.items, 0..) |shdr, shndx| { | 3075 | for (slice.items(.shdr), slice.items(.atom_list)) |shdr, *atom_list| { |
| 3091 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 3076 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3092 | 3077 | ||
| 3093 | var is_init_fini = false; | 3078 | var is_init_fini = false; |
| ... | @@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void { | ... | @@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void { |
| 3104 | } | 3089 | } |
| 3105 | 3090 | ||
| 3106 | if (!is_init_fini and !is_ctor_dtor) continue; | 3091 | if (!is_init_fini and !is_ctor_dtor) continue; |
| 3107 | |||
| 3108 | const atom_list = self.output_sections.getPtr(@intCast(shndx)).?; | ||
| 3109 | if (atom_list.items.len == 0) continue; | 3092 | if (atom_list.items.len == 0) continue; |
| 3110 | 3093 | ||
| 3111 | var entries = std.ArrayList(Entry).init(gpa); | 3094 | var entries = std.ArrayList(Entry).init(gpa); |
| ... | @@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void { | ... | @@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void { |
| 3173 | 3156 | ||
| 3174 | if (self.verneed_section_index) |shndx| { | 3157 | if (self.verneed_section_index) |shndx| { |
| 3175 | try self.verneed.generate(self); | 3158 | try self.verneed.generate(self); |
| 3176 | const shdr = &self.shdrs.items[shndx]; | 3159 | const shdr = &self.sections.items(.shdr)[shndx]; |
| 3177 | shdr.sh_info = @as(u32, @intCast(self.verneed.verneed.items.len)); | 3160 | shdr.sh_info = @as(u32, @intCast(self.verneed.verneed.items.len)); |
| 3178 | } | 3161 | } |
| 3179 | } | 3162 | } |
| ... | @@ -3252,17 +3235,10 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { | ... | @@ -3252,17 +3235,10 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 3252 | index.* = backlinks[index.*]; | 3235 | index.* = backlinks[index.*]; |
| 3253 | } | 3236 | } |
| 3254 | } | 3237 | } |
| 3255 | |||
| 3256 | { | ||
| 3257 | var it = self.phdr_to_shdr_table.iterator(); | ||
| 3258 | while (it.next()) |entry| { | ||
| 3259 | entry.value_ptr.* = backlinks[entry.value_ptr.*]; | ||
| 3260 | } | ||
| 3261 | } | ||
| 3262 | } | 3238 | } |
| 3263 | 3239 | ||
| 3264 | fn shdrRank(self: *Elf, shndx: u32) u8 { | 3240 | fn shdrRank(self: *Elf, shndx: u32) u8 { |
| 3265 | const shdr = self.shdrs.items[shndx]; | 3241 | const shdr = self.sections.items(.shdr)[shndx]; |
| 3266 | const name = self.getShString(shdr.sh_name); | 3242 | const name = self.getShString(shdr.sh_name); |
| 3267 | const flags = shdr.sh_flags; | 3243 | const flags = shdr.sh_flags; |
| 3268 | 3244 | ||
| ... | @@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void { | ... | @@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3319 | }; | 3295 | }; |
| 3320 | 3296 | ||
| 3321 | const gpa = self.base.comp.gpa; | 3297 | const gpa = self.base.comp.gpa; |
| 3322 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len); | 3298 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.sections.items(.shdr).len); |
| 3323 | defer entries.deinit(); | 3299 | defer entries.deinit(); |
| 3324 | for (0..self.shdrs.items.len) |shndx| { | 3300 | for (0..self.sections.items(.shdr).len) |shndx| { |
| 3325 | entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) }); | 3301 | entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) }); |
| 3326 | } | 3302 | } |
| 3327 | 3303 | ||
| ... | @@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void { | ... | @@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3333 | backlinks[entry.shndx] = @intCast(i); | 3309 | backlinks[entry.shndx] = @intCast(i); |
| 3334 | } | 3310 | } |
| 3335 | 3311 | ||
| 3336 | const slice = try self.shdrs.toOwnedSlice(gpa); | 3312 | var slice = self.sections.toOwnedSlice(); |
| 3337 | defer gpa.free(slice); | 3313 | defer slice.deinit(gpa); |
| 3338 | 3314 | ||
| 3339 | try self.shdrs.ensureTotalCapacityPrecise(gpa, slice.len); | 3315 | try self.sections.ensureTotalCapacity(gpa, slice.len); |
| 3340 | for (entries.items) |sorted| { | 3316 | for (entries.items) |sorted| { |
| 3341 | self.shdrs.appendAssumeCapacity(slice[sorted.shndx]); | 3317 | self.sections.appendAssumeCapacity(slice.get(sorted.shndx)); |
| 3342 | } | 3318 | } |
| 3343 | 3319 | ||
| 3344 | try self.resetShdrIndexes(backlinks); | 3320 | self.resetShdrIndexes(backlinks); |
| 3345 | } | 3321 | } |
| 3346 | 3322 | ||
| 3347 | fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | 3323 | fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void { |
| 3348 | const gpa = self.base.comp.gpa; | ||
| 3349 | |||
| 3350 | for (&[_]*?u32{ | 3324 | for (&[_]*?u32{ |
| 3351 | &self.eh_frame_section_index, | 3325 | &self.eh_frame_section_index, |
| 3352 | &self.eh_frame_rela_section_index, | 3326 | &self.eh_frame_rela_section_index, |
| ... | @@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | ... | @@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3388 | } | 3362 | } |
| 3389 | 3363 | ||
| 3390 | if (self.symtab_section_index) |index| { | 3364 | if (self.symtab_section_index) |index| { |
| 3391 | const shdr = &self.shdrs.items[index]; | 3365 | const shdr = &self.sections.items(.shdr)[index]; |
| 3392 | shdr.sh_link = self.strtab_section_index.?; | 3366 | shdr.sh_link = self.strtab_section_index.?; |
| 3393 | } | 3367 | } |
| 3394 | 3368 | ||
| 3395 | if (self.dynamic_section_index) |index| { | 3369 | if (self.dynamic_section_index) |index| { |
| 3396 | const shdr = &self.shdrs.items[index]; | 3370 | const shdr = &self.sections.items(.shdr)[index]; |
| 3397 | shdr.sh_link = self.dynstrtab_section_index.?; | 3371 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3398 | } | 3372 | } |
| 3399 | 3373 | ||
| 3400 | if (self.dynsymtab_section_index) |index| { | 3374 | if (self.dynsymtab_section_index) |index| { |
| 3401 | const shdr = &self.shdrs.items[index]; | 3375 | const shdr = &self.sections.items(.shdr)[index]; |
| 3402 | shdr.sh_link = self.dynstrtab_section_index.?; | 3376 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3403 | } | 3377 | } |
| 3404 | 3378 | ||
| 3405 | if (self.hash_section_index) |index| { | 3379 | if (self.hash_section_index) |index| { |
| 3406 | const shdr = &self.shdrs.items[index]; | 3380 | const shdr = &self.sections.items(.shdr)[index]; |
| 3407 | shdr.sh_link = self.dynsymtab_section_index.?; | 3381 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3408 | } | 3382 | } |
| 3409 | 3383 | ||
| 3410 | if (self.gnu_hash_section_index) |index| { | 3384 | if (self.gnu_hash_section_index) |index| { |
| 3411 | const shdr = &self.shdrs.items[index]; | 3385 | const shdr = &self.sections.items(.shdr)[index]; |
| 3412 | shdr.sh_link = self.dynsymtab_section_index.?; | 3386 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3413 | } | 3387 | } |
| 3414 | 3388 | ||
| 3415 | if (self.versym_section_index) |index| { | 3389 | if (self.versym_section_index) |index| { |
| 3416 | const shdr = &self.shdrs.items[index]; | 3390 | const shdr = &self.sections.items(.shdr)[index]; |
| 3417 | shdr.sh_link = self.dynsymtab_section_index.?; | 3391 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3418 | } | 3392 | } |
| 3419 | 3393 | ||
| 3420 | if (self.verneed_section_index) |index| { | 3394 | if (self.verneed_section_index) |index| { |
| 3421 | const shdr = &self.shdrs.items[index]; | 3395 | const shdr = &self.sections.items(.shdr)[index]; |
| 3422 | shdr.sh_link = self.dynstrtab_section_index.?; | 3396 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3423 | } | 3397 | } |
| 3424 | 3398 | ||
| 3425 | if (self.rela_dyn_section_index) |index| { | 3399 | if (self.rela_dyn_section_index) |index| { |
| 3426 | const shdr = &self.shdrs.items[index]; | 3400 | const shdr = &self.sections.items(.shdr)[index]; |
| 3427 | shdr.sh_link = self.dynsymtab_section_index orelse 0; | 3401 | shdr.sh_link = self.dynsymtab_section_index orelse 0; |
| 3428 | } | 3402 | } |
| 3429 | 3403 | ||
| 3430 | if (self.rela_plt_section_index) |index| { | 3404 | if (self.rela_plt_section_index) |index| { |
| 3431 | const shdr = &self.shdrs.items[index]; | 3405 | const shdr = &self.sections.items(.shdr)[index]; |
| 3432 | shdr.sh_link = self.dynsymtab_section_index.?; | 3406 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3433 | shdr.sh_info = self.plt_section_index.?; | 3407 | shdr.sh_info = self.plt_section_index.?; |
| 3434 | } | 3408 | } |
| 3435 | 3409 | ||
| 3436 | if (self.eh_frame_rela_section_index) |index| { | 3410 | if (self.eh_frame_rela_section_index) |index| { |
| 3437 | const shdr = &self.shdrs.items[index]; | 3411 | const shdr = &self.sections.items(.shdr)[index]; |
| 3438 | shdr.sh_link = self.symtab_section_index.?; | 3412 | shdr.sh_link = self.symtab_section_index.?; |
| 3439 | shdr.sh_info = self.eh_frame_section_index.?; | 3413 | shdr.sh_info = self.eh_frame_section_index.?; |
| 3440 | } | 3414 | } |
| 3441 | 3415 | ||
| 3442 | { | ||
| 3443 | var output_sections = try self.output_sections.clone(gpa); | ||
| 3444 | defer output_sections.deinit(gpa); | ||
| 3445 | |||
| 3446 | self.output_sections.clearRetainingCapacity(); | ||
| 3447 | |||
| 3448 | var it = output_sections.iterator(); | ||
| 3449 | while (it.next()) |entry| { | ||
| 3450 | const shndx = entry.key_ptr.*; | ||
| 3451 | const meta = entry.value_ptr.*; | ||
| 3452 | self.output_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta); | ||
| 3453 | } | ||
| 3454 | } | ||
| 3455 | |||
| 3456 | for (self.merge_sections.items) |*msec| { | 3416 | for (self.merge_sections.items) |*msec| { |
| 3457 | msec.output_section_index = backlinks[msec.output_section_index]; | 3417 | msec.output_section_index = backlinks[msec.output_section_index]; |
| 3458 | } | 3418 | } |
| 3459 | 3419 | ||
| 3460 | { | 3420 | for (self.sections.items(.shdr)) |*shdr| { |
| 3461 | var output_rela_sections = try self.output_rela_sections.clone(gpa); | 3421 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 3462 | defer output_rela_sections.deinit(gpa); | 3422 | shdr.sh_link = backlinks[shdr.sh_link]; |
| 3463 | 3423 | shdr.sh_info = backlinks[shdr.sh_info]; | |
| 3464 | self.output_rela_sections.clearRetainingCapacity(); | ||
| 3465 | |||
| 3466 | var it = output_rela_sections.iterator(); | ||
| 3467 | while (it.next()) |entry| { | ||
| 3468 | const shndx = entry.key_ptr.*; | ||
| 3469 | var meta = entry.value_ptr.*; | ||
| 3470 | meta.shndx = backlinks[meta.shndx]; | ||
| 3471 | self.output_rela_sections.putAssumeCapacityNoClobber(backlinks[shndx], meta); | ||
| 3472 | } | ||
| 3473 | } | ||
| 3474 | |||
| 3475 | { | ||
| 3476 | var last_atom_and_free_list_table = try self.last_atom_and_free_list_table.clone(gpa); | ||
| 3477 | defer last_atom_and_free_list_table.deinit(gpa); | ||
| 3478 | |||
| 3479 | self.last_atom_and_free_list_table.clearRetainingCapacity(); | ||
| 3480 | |||
| 3481 | var it = last_atom_and_free_list_table.iterator(); | ||
| 3482 | while (it.next()) |entry| { | ||
| 3483 | const shndx = entry.key_ptr.*; | ||
| 3484 | const meta = entry.value_ptr.*; | ||
| 3485 | self.last_atom_and_free_list_table.putAssumeCapacityNoClobber(backlinks[shndx], meta); | ||
| 3486 | } | ||
| 3487 | } | ||
| 3488 | |||
| 3489 | { | ||
| 3490 | var phdr_to_shdr_table = try self.phdr_to_shdr_table.clone(gpa); | ||
| 3491 | defer phdr_to_shdr_table.deinit(gpa); | ||
| 3492 | |||
| 3493 | self.phdr_to_shdr_table.clearRetainingCapacity(); | ||
| 3494 | |||
| 3495 | var it = phdr_to_shdr_table.iterator(); | ||
| 3496 | while (it.next()) |entry| { | ||
| 3497 | const shndx = entry.key_ptr.*; | ||
| 3498 | const phndx = entry.value_ptr.*; | ||
| 3499 | self.phdr_to_shdr_table.putAssumeCapacityNoClobber(backlinks[shndx], phndx); | ||
| 3500 | } | ||
| 3501 | } | 3424 | } |
| 3502 | 3425 | ||
| 3503 | if (self.zigObjectPtr()) |zo| { | 3426 | if (self.zigObjectPtr()) |zo| { |
| ... | @@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | ... | @@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3508 | if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata(); | 3431 | if (zo.dwarf) |*dwarf| dwarf.reloadSectionMetadata(); |
| 3509 | } | 3432 | } |
| 3510 | 3433 | ||
| 3511 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| { | ||
| 3512 | const shdr = &self.shdrs.items[sec.shndx]; | ||
| 3513 | shdr.sh_link = self.symtab_section_index.?; | ||
| 3514 | shdr.sh_info = shndx; | ||
| 3515 | } | ||
| 3516 | |||
| 3517 | for (self.comdat_group_sections.items) |*cg| { | 3434 | for (self.comdat_group_sections.items) |*cg| { |
| 3518 | cg.shndx = backlinks[cg.shndx]; | 3435 | cg.shndx = backlinks[cg.shndx]; |
| 3519 | } | 3436 | } |
| ... | @@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | ... | @@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3521 | 3438 | ||
| 3522 | fn updateSectionSizes(self: *Elf) !void { | 3439 | fn updateSectionSizes(self: *Elf) !void { |
| 3523 | const target = self.base.comp.root_mod.resolved_target.result; | 3440 | const target = self.base.comp.root_mod.resolved_target.result; |
| 3524 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { | 3441 | const slice = self.sections.slice(); |
| 3525 | const shdr = &self.shdrs.items[shndx]; | 3442 | for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| { |
| 3526 | if (atom_list.items.len == 0) continue; | 3443 | if (atom_list.items.len == 0) continue; |
| 3527 | if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue; | 3444 | if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue; |
| 3528 | for (atom_list.items) |ref| { | 3445 | for (atom_list.items) |ref| { |
| ... | @@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3537 | } | 3454 | } |
| 3538 | 3455 | ||
| 3539 | if (self.requiresThunks()) { | 3456 | if (self.requiresThunks()) { |
| 3540 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { | 3457 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| { |
| 3541 | const shdr = self.shdrs.items[shndx]; | ||
| 3542 | if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue; | 3458 | if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue; |
| 3543 | if (atom_list.items.len == 0) continue; | 3459 | if (atom_list.items.len == 0) continue; |
| 3544 | 3460 | ||
| 3545 | // Create jump/branch range extenders if needed. | 3461 | // Create jump/branch range extenders if needed. |
| 3546 | try thunks.createThunks(shndx, self); | 3462 | try thunks.createThunks(shdr, @intCast(shndx), self); |
| 3547 | } | 3463 | } |
| 3548 | } | 3464 | } |
| 3549 | 3465 | ||
| 3466 | const shdrs = slice.items(.shdr); | ||
| 3550 | if (self.eh_frame_section_index) |index| { | 3467 | if (self.eh_frame_section_index) |index| { |
| 3551 | self.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(self); | 3468 | shdrs[index].sh_size = try eh_frame.calcEhFrameSize(self); |
| 3552 | } | 3469 | } |
| 3553 | 3470 | ||
| 3554 | if (self.eh_frame_hdr_section_index) |index| { | 3471 | if (self.eh_frame_hdr_section_index) |index| { |
| 3555 | self.shdrs.items[index].sh_size = eh_frame.calcEhFrameHdrSize(self); | 3472 | shdrs[index].sh_size = eh_frame.calcEhFrameHdrSize(self); |
| 3556 | } | 3473 | } |
| 3557 | 3474 | ||
| 3558 | if (self.got_section_index) |index| { | 3475 | if (self.got_section_index) |index| { |
| 3559 | self.shdrs.items[index].sh_size = self.got.size(self); | 3476 | shdrs[index].sh_size = self.got.size(self); |
| 3560 | } | 3477 | } |
| 3561 | 3478 | ||
| 3562 | if (self.plt_section_index) |index| { | 3479 | if (self.plt_section_index) |index| { |
| 3563 | self.shdrs.items[index].sh_size = self.plt.size(self); | 3480 | shdrs[index].sh_size = self.plt.size(self); |
| 3564 | } | 3481 | } |
| 3565 | 3482 | ||
| 3566 | if (self.got_plt_section_index) |index| { | 3483 | if (self.got_plt_section_index) |index| { |
| 3567 | self.shdrs.items[index].sh_size = self.got_plt.size(self); | 3484 | shdrs[index].sh_size = self.got_plt.size(self); |
| 3568 | } | 3485 | } |
| 3569 | 3486 | ||
| 3570 | if (self.plt_got_section_index) |index| { | 3487 | if (self.plt_got_section_index) |index| { |
| 3571 | self.shdrs.items[index].sh_size = self.plt_got.size(self); | 3488 | shdrs[index].sh_size = self.plt_got.size(self); |
| 3572 | } | 3489 | } |
| 3573 | 3490 | ||
| 3574 | if (self.rela_dyn_section_index) |shndx| { | 3491 | if (self.rela_dyn_section_index) |shndx| { |
| ... | @@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3579 | for (self.objects.items) |index| { | 3496 | for (self.objects.items) |index| { |
| 3580 | num += self.file(index).?.object.num_dynrelocs; | 3497 | num += self.file(index).?.object.num_dynrelocs; |
| 3581 | } | 3498 | } |
| 3582 | self.shdrs.items[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela); | 3499 | shdrs[shndx].sh_size = num * @sizeOf(elf.Elf64_Rela); |
| 3583 | } | 3500 | } |
| 3584 | 3501 | ||
| 3585 | if (self.rela_plt_section_index) |index| { | 3502 | if (self.rela_plt_section_index) |index| { |
| 3586 | self.shdrs.items[index].sh_size = self.plt.numRela() * @sizeOf(elf.Elf64_Rela); | 3503 | shdrs[index].sh_size = self.plt.numRela() * @sizeOf(elf.Elf64_Rela); |
| 3587 | } | 3504 | } |
| 3588 | 3505 | ||
| 3589 | if (self.copy_rel_section_index) |index| { | 3506 | if (self.copy_rel_section_index) |index| { |
| ... | @@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3591 | } | 3508 | } |
| 3592 | 3509 | ||
| 3593 | if (self.interp_section_index) |index| { | 3510 | if (self.interp_section_index) |index| { |
| 3594 | self.shdrs.items[index].sh_size = target.dynamic_linker.get().?.len + 1; | 3511 | shdrs[index].sh_size = target.dynamic_linker.get().?.len + 1; |
| 3595 | } | 3512 | } |
| 3596 | 3513 | ||
| 3597 | if (self.hash_section_index) |index| { | 3514 | if (self.hash_section_index) |index| { |
| 3598 | self.shdrs.items[index].sh_size = self.hash.size(); | 3515 | shdrs[index].sh_size = self.hash.size(); |
| 3599 | } | 3516 | } |
| 3600 | 3517 | ||
| 3601 | if (self.gnu_hash_section_index) |index| { | 3518 | if (self.gnu_hash_section_index) |index| { |
| 3602 | self.shdrs.items[index].sh_size = self.gnu_hash.size(); | 3519 | shdrs[index].sh_size = self.gnu_hash.size(); |
| 3603 | } | 3520 | } |
| 3604 | 3521 | ||
| 3605 | if (self.dynamic_section_index) |index| { | 3522 | if (self.dynamic_section_index) |index| { |
| 3606 | self.shdrs.items[index].sh_size = self.dynamic.size(self); | 3523 | shdrs[index].sh_size = self.dynamic.size(self); |
| 3607 | } | 3524 | } |
| 3608 | 3525 | ||
| 3609 | if (self.dynsymtab_section_index) |index| { | 3526 | if (self.dynsymtab_section_index) |index| { |
| 3610 | self.shdrs.items[index].sh_size = self.dynsym.size(); | 3527 | shdrs[index].sh_size = self.dynsym.size(); |
| 3611 | } | 3528 | } |
| 3612 | 3529 | ||
| 3613 | if (self.dynstrtab_section_index) |index| { | 3530 | if (self.dynstrtab_section_index) |index| { |
| 3614 | self.shdrs.items[index].sh_size = self.dynstrtab.items.len; | 3531 | shdrs[index].sh_size = self.dynstrtab.items.len; |
| 3615 | } | 3532 | } |
| 3616 | 3533 | ||
| 3617 | if (self.versym_section_index) |index| { | 3534 | if (self.versym_section_index) |index| { |
| 3618 | self.shdrs.items[index].sh_size = self.versym.items.len * @sizeOf(elf.Elf64_Versym); | 3535 | shdrs[index].sh_size = self.versym.items.len * @sizeOf(elf.Elf64_Versym); |
| 3619 | } | 3536 | } |
| 3620 | 3537 | ||
| 3621 | if (self.verneed_section_index) |index| { | 3538 | if (self.verneed_section_index) |index| { |
| 3622 | self.shdrs.items[index].sh_size = self.verneed.size(); | 3539 | shdrs[index].sh_size = self.verneed.size(); |
| 3623 | } | 3540 | } |
| 3624 | 3541 | ||
| 3625 | try self.updateSymtabSize(); | 3542 | try self.updateSymtabSize(); |
| 3626 | self.updateShStrtabSize(); | 3543 | self.updateShStrtabSize(); |
| 3627 | } | 3544 | } |
| 3628 | 3545 | ||
| 3546 | // FIXME:JK this is very much obsolete, remove! | ||
| 3629 | pub fn updateShStrtabSize(self: *Elf) void { | 3547 | pub fn updateShStrtabSize(self: *Elf) void { |
| 3630 | if (self.shstrtab_section_index) |index| { | 3548 | if (self.shstrtab_section_index) |index| { |
| 3631 | self.shdrs.items[index].sh_size = self.shstrtab.items.len; | 3549 | self.sections.items(.shdr)[index].sh_size = self.shstrtab.items.len; |
| 3632 | } | 3550 | } |
| 3633 | } | 3551 | } |
| 3634 | 3552 | ||
| ... | @@ -3661,7 +3579,7 @@ fn getMaxNumberOfPhdrs() u64 { | ... | @@ -3661,7 +3579,7 @@ fn getMaxNumberOfPhdrs() u64 { |
| 3661 | /// We permit a maximum of 3**2 number of segments. | 3579 | /// We permit a maximum of 3**2 number of segments. |
| 3662 | fn calcNumberOfSegments(self: *Elf) usize { | 3580 | fn calcNumberOfSegments(self: *Elf) usize { |
| 3663 | var covers: [9]bool = [_]bool{false} ** 9; | 3581 | var covers: [9]bool = [_]bool{false} ** 9; |
| 3664 | for (self.shdrs.items, 0..) |shdr, shndx| { | 3582 | for (self.sections.items(.shdr), 0..) |shdr, shndx| { |
| 3665 | if (shdr.sh_type == elf.SHT_NULL) continue; | 3583 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3666 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 3584 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3667 | if (self.isZigSection(@intCast(shndx))) continue; | 3585 | if (self.isZigSection(@intCast(shndx))) continue; |
| ... | @@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3732 | } | 3650 | } |
| 3733 | }; | 3651 | }; |
| 3734 | 3652 | ||
| 3653 | const slice = self.sections.slice(); | ||
| 3735 | var alignment = Align{}; | 3654 | var alignment = Align{}; |
| 3736 | for (self.shdrs.items, 0..) |shdr, i| { | 3655 | for (slice.items(.shdr), 0..) |shdr, i| { |
| 3737 | if (shdr.sh_type == elf.SHT_NULL) continue; | 3656 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3738 | if (shdr.sh_flags & elf.SHF_TLS == 0) continue; | 3657 | if (shdr.sh_flags & elf.SHF_TLS == 0) continue; |
| 3739 | if (alignment.first_tls_index == null) alignment.first_tls_index = i; | 3658 | if (alignment.first_tls_index == null) alignment.first_tls_index = i; |
| ... | @@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3758 | cover.deinit(); | 3677 | cover.deinit(); |
| 3759 | }; | 3678 | }; |
| 3760 | 3679 | ||
| 3761 | for (self.shdrs.items, 0..) |shdr, shndx| { | 3680 | for (slice.items(.shdr), 0..) |shdr, shndx| { |
| 3762 | if (shdr.sh_type == elf.SHT_NULL) continue; | 3681 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3763 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 3682 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3764 | if (self.isZigSection(@intCast(shndx))) continue; | 3683 | if (self.isZigSection(@intCast(shndx))) continue; |
| ... | @@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3779 | 3698 | ||
| 3780 | var @"align": u64 = self.page_size; | 3699 | var @"align": u64 = self.page_size; |
| 3781 | for (cover.items) |shndx| { | 3700 | for (cover.items) |shndx| { |
| 3782 | const shdr = self.shdrs.items[shndx]; | 3701 | const shdr = slice.items(.shdr)[shndx]; |
| 3783 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue; | 3702 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue; |
| 3784 | @"align" = @max(@"align", shdr.sh_addralign); | 3703 | @"align" = @max(@"align", shdr.sh_addralign); |
| 3785 | } | 3704 | } |
| ... | @@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3791 | var i: usize = 0; | 3710 | var i: usize = 0; |
| 3792 | while (i < cover.items.len) : (i += 1) { | 3711 | while (i < cover.items.len) : (i += 1) { |
| 3793 | const shndx = cover.items[i]; | 3712 | const shndx = cover.items[i]; |
| 3794 | const shdr = &self.shdrs.items[shndx]; | 3713 | const shdr = &slice.items(.shdr)[shndx]; |
| 3795 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) { | 3714 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) { |
| 3796 | // .tbss is a little special as it's used only by the loader meaning it doesn't | 3715 | // .tbss is a little special as it's used only by the loader meaning it doesn't |
| 3797 | // need to be actually mmap'ed at runtime. We still need to correctly increment | 3716 | // need to be actually mmap'ed at runtime. We still need to correctly increment |
| ... | @@ -3807,11 +3726,11 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3807,11 +3726,11 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3807 | // ... | 3726 | // ... |
| 3808 | var tbss_addr = addr; | 3727 | var tbss_addr = addr; |
| 3809 | while (i < cover.items.len and | 3728 | while (i < cover.items.len and |
| 3810 | self.shdrs.items[cover.items[i]].sh_type == elf.SHT_NOBITS and | 3729 | slice.items(.shdr)[cover.items[i]].sh_type == elf.SHT_NOBITS and |
| 3811 | self.shdrs.items[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1) | 3730 | slice.items(.shdr)[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1) |
| 3812 | { | 3731 | { |
| 3813 | const tbss_shndx = cover.items[i]; | 3732 | const tbss_shndx = cover.items[i]; |
| 3814 | const tbss_shdr = &self.shdrs.items[tbss_shndx]; | 3733 | const tbss_shdr = &slice.items(.shdr)[tbss_shndx]; |
| 3815 | tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr); | 3734 | tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr); |
| 3816 | tbss_shdr.sh_addr = tbss_addr; | 3735 | tbss_shdr.sh_addr = tbss_addr; |
| 3817 | tbss_addr += tbss_shdr.sh_size; | 3736 | tbss_addr += tbss_shdr.sh_size; |
| ... | @@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3830 | addr += shdr.sh_size; | 3749 | addr += shdr.sh_size; |
| 3831 | } | 3750 | } |
| 3832 | 3751 | ||
| 3833 | const first = self.shdrs.items[cover.items[0]]; | 3752 | const first = slice.items(.shdr)[cover.items[0]]; |
| 3834 | var off = try self.findFreeSpace(filesz, @"align"); | 3753 | var off = try self.findFreeSpace(filesz, @"align"); |
| 3835 | const phndx = try self.addPhdr(.{ | 3754 | const phndx = try self.addPhdr(.{ |
| 3836 | .type = elf.PT_LOAD, | 3755 | .type = elf.PT_LOAD, |
| ... | @@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3843 | }); | 3762 | }); |
| 3844 | 3763 | ||
| 3845 | for (cover.items) |shndx| { | 3764 | for (cover.items) |shndx| { |
| 3846 | const shdr = &self.shdrs.items[shndx]; | 3765 | const shdr = &slice.items(.shdr)[shndx]; |
| 3847 | if (shdr.sh_type == elf.SHT_NOBITS) { | 3766 | if (shdr.sh_type == elf.SHT_NOBITS) { |
| 3848 | shdr.sh_offset = 0; | 3767 | shdr.sh_offset = 0; |
| 3849 | continue; | 3768 | continue; |
| ... | @@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3851 | off = alignment.@"align"(shndx, shdr.sh_addralign, off); | 3770 | off = alignment.@"align"(shndx, shdr.sh_addralign, off); |
| 3852 | shdr.sh_offset = off; | 3771 | shdr.sh_offset = off; |
| 3853 | off += shdr.sh_size; | 3772 | off += shdr.sh_size; |
| 3854 | try self.phdr_to_shdr_table.putNoClobber(gpa, shndx, phndx); | 3773 | slice.items(.phndx)[shndx] = phndx; |
| 3855 | } | 3774 | } |
| 3856 | 3775 | ||
| 3857 | addr = mem.alignForward(u64, addr, self.page_size); | 3776 | addr = mem.alignForward(u64, addr, self.page_size); |
| ... | @@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void { | ... | @@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3860 | 3779 | ||
| 3861 | /// Allocates non-alloc sections (debug info, symtabs, etc.). | 3780 | /// Allocates non-alloc sections (debug info, symtabs, etc.). |
| 3862 | pub fn allocateNonAllocSections(self: *Elf) !void { | 3781 | pub fn allocateNonAllocSections(self: *Elf) !void { |
| 3863 | for (self.shdrs.items, 0..) |*shdr, shndx| { | 3782 | for (self.sections.items(.shdr), 0..) |*shdr, shndx| { |
| 3864 | if (shdr.sh_type == elf.SHT_NULL) continue; | 3783 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3865 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue; | 3784 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue; |
| 3866 | const needed_size = shdr.sh_size; | 3785 | const needed_size = shdr.sh_size; |
| ... | @@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void { | ... | @@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void { |
| 3905 | } | 3824 | } |
| 3906 | 3825 | ||
| 3907 | fn allocateSpecialPhdrs(self: *Elf) void { | 3826 | fn allocateSpecialPhdrs(self: *Elf) void { |
| 3827 | const slice = self.sections.slice(); | ||
| 3828 | |||
| 3908 | for (&[_]struct { ?u16, ?u32 }{ | 3829 | for (&[_]struct { ?u16, ?u32 }{ |
| 3909 | .{ self.phdr_interp_index, self.interp_section_index }, | 3830 | .{ self.phdr_interp_index, self.interp_section_index }, |
| 3910 | .{ self.phdr_dynamic_index, self.dynamic_section_index }, | 3831 | .{ self.phdr_dynamic_index, self.dynamic_section_index }, |
| 3911 | .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index }, | 3832 | .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index }, |
| 3912 | }) |pair| { | 3833 | }) |pair| { |
| 3913 | if (pair[0]) |index| { | 3834 | if (pair[0]) |index| { |
| 3914 | const shdr = self.shdrs.items[pair[1].?]; | 3835 | const shdr = slice.items(.shdr)[pair[1].?]; |
| 3915 | const phdr = &self.phdrs.items[index]; | 3836 | const phdr = &self.phdrs.items[index]; |
| 3916 | phdr.p_align = shdr.sh_addralign; | 3837 | phdr.p_align = shdr.sh_addralign; |
| 3917 | phdr.p_offset = shdr.sh_offset; | 3838 | phdr.p_offset = shdr.sh_offset; |
| ... | @@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 3926 | // We assume TLS sections are laid out contiguously and that there is | 3847 | // We assume TLS sections are laid out contiguously and that there is |
| 3927 | // a single TLS segment. | 3848 | // a single TLS segment. |
| 3928 | if (self.phdr_tls_index) |index| { | 3849 | if (self.phdr_tls_index) |index| { |
| 3929 | const slice = self.shdrs.items; | 3850 | const shdrs = slice.items(.shdr); |
| 3930 | const phdr = &self.phdrs.items[index]; | 3851 | const phdr = &self.phdrs.items[index]; |
| 3931 | var shndx: u32 = 0; | 3852 | var shndx: u32 = 0; |
| 3932 | while (shndx < slice.len) { | 3853 | while (shndx < shdrs.len) { |
| 3933 | const shdr = slice[shndx]; | 3854 | const shdr = shdrs[shndx]; |
| 3934 | if (shdr.sh_flags & elf.SHF_TLS == 0) { | 3855 | if (shdr.sh_flags & elf.SHF_TLS == 0) { |
| 3935 | shndx += 1; | 3856 | shndx += 1; |
| 3936 | continue; | 3857 | continue; |
| ... | @@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 3946 | } | 3867 | } |
| 3947 | phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr; | 3868 | phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr; |
| 3948 | 3869 | ||
| 3949 | while (shndx < slice.len) : (shndx += 1) { | 3870 | while (shndx < shdrs.len) : (shndx += 1) { |
| 3950 | const next = slice[shndx]; | 3871 | const next = shdrs[shndx]; |
| 3951 | if (next.sh_flags & elf.SHF_TLS == 0) break; | 3872 | if (next.sh_flags & elf.SHF_TLS == 0) break; |
| 3952 | phdr.p_align = @max(phdr.p_align, next.sh_addralign); | 3873 | phdr.p_align = @max(phdr.p_align, next.sh_addralign); |
| 3953 | if (next.sh_type != elf.SHT_NOBITS) { | 3874 | if (next.sh_type != elf.SHT_NOBITS) { |
| ... | @@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void { |
| 3971 | } | 3892 | } |
| 3972 | 3893 | ||
| 3973 | var has_reloc_errors = false; | 3894 | var has_reloc_errors = false; |
| 3974 | 3895 | const slice = self.sections.slice(); | |
| 3975 | // TODO iterate over `output_sections` directly | 3896 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { |
| 3976 | for (self.shdrs.items, 0..) |shdr, shndx| { | ||
| 3977 | if (shdr.sh_type == elf.SHT_NULL) continue; | 3897 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3978 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 3898 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 3979 | |||
| 3980 | const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue; | ||
| 3981 | if (atom_list.items.len == 0) continue; | 3899 | if (atom_list.items.len == 0) continue; |
| 3982 | 3900 | ||
| 3983 | log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)}); | 3901 | log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)}); |
| ... | @@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4056 | for (self.thunks.items) |th| { | 3974 | for (self.thunks.items) |th| { |
| 4057 | const thunk_size = th.size(self); | 3975 | const thunk_size = th.size(self); |
| 4058 | try buffer.ensureUnusedCapacity(thunk_size); | 3976 | try buffer.ensureUnusedCapacity(thunk_size); |
| 4059 | const shdr = self.shdrs.items[th.output_section_index]; | 3977 | const shdr = slice.items(.shdr)[th.output_section_index]; |
| 4060 | const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset; | 3978 | const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset; |
| 4061 | try th.write(self, buffer.writer()); | 3979 | try th.write(self, buffer.writer()); |
| 4062 | assert(buffer.items.len == thunk_size); | 3980 | assert(buffer.items.len == thunk_size); |
| ... | @@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4086 | if (self.linker_defined_index) |index| files.appendAssumeCapacity(index); | 4004 | if (self.linker_defined_index) |index| files.appendAssumeCapacity(index); |
| 4087 | 4005 | ||
| 4088 | // Section symbols | 4006 | // Section symbols |
| 4089 | for (self.output_sections.keys()) |_| { | 4007 | nlocals += @intCast(self.sections.slice().len); |
| 4090 | nlocals += 1; | ||
| 4091 | } | ||
| 4092 | if (self.eh_frame_section_index) |_| { | ||
| 4093 | nlocals += 1; | ||
| 4094 | } | ||
| 4095 | 4008 | ||
| 4096 | if (self.requiresThunks()) for (self.thunks.items) |*th| { | 4009 | if (self.requiresThunks()) for (self.thunks.items) |*th| { |
| 4097 | th.output_symtab_ctx.ilocal = nlocals + 1; | 4010 | th.output_symtab_ctx.ilocal = nlocals + 1; |
| ... | @@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4142 | ctx.iglobal += nlocals; | 4055 | ctx.iglobal += nlocals; |
| 4143 | } | 4056 | } |
| 4144 | 4057 | ||
| 4145 | const symtab_shdr = &self.shdrs.items[self.symtab_section_index.?]; | 4058 | const slice = self.sections.slice(); |
| 4059 | const symtab_shdr = &slice.items(.shdr)[self.symtab_section_index.?]; | ||
| 4146 | symtab_shdr.sh_info = nlocals + 1; | 4060 | symtab_shdr.sh_info = nlocals + 1; |
| 4147 | symtab_shdr.sh_link = self.strtab_section_index.?; | 4061 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4148 | 4062 | ||
| ... | @@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4153 | const needed_size = (nlocals + nglobals + 1) * sym_size; | 4067 | const needed_size = (nlocals + nglobals + 1) * sym_size; |
| 4154 | symtab_shdr.sh_size = needed_size; | 4068 | symtab_shdr.sh_size = needed_size; |
| 4155 | 4069 | ||
| 4156 | const strtab = &self.shdrs.items[self.strtab_section_index.?]; | 4070 | const strtab = &slice.items(.shdr)[self.strtab_section_index.?]; |
| 4157 | strtab.sh_size = strsize + 1; | 4071 | strtab.sh_size = strsize + 1; |
| 4158 | } | 4072 | } |
| 4159 | 4073 | ||
| 4160 | fn writeSyntheticSections(self: *Elf) !void { | 4074 | fn writeSyntheticSections(self: *Elf) !void { |
| 4161 | const target = self.base.comp.root_mod.resolved_target.result; | ||
| 4162 | const gpa = self.base.comp.gpa; | 4075 | const gpa = self.base.comp.gpa; |
| 4076 | const target = self.getTarget(); | ||
| 4077 | const slice = self.sections.slice(); | ||
| 4163 | 4078 | ||
| 4164 | if (self.interp_section_index) |shndx| { | 4079 | if (self.interp_section_index) |shndx| { |
| 4165 | var buffer: [256]u8 = undefined; | 4080 | var buffer: [256]u8 = undefined; |
| ... | @@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4167 | @memcpy(buffer[0..interp.len], interp); | 4082 | @memcpy(buffer[0..interp.len], interp); |
| 4168 | buffer[interp.len] = 0; | 4083 | buffer[interp.len] = 0; |
| 4169 | const contents = buffer[0 .. interp.len + 1]; | 4084 | const contents = buffer[0 .. interp.len + 1]; |
| 4170 | const shdr = self.shdrs.items[shndx]; | 4085 | const shdr = slice.items(.shdr)[shndx]; |
| 4171 | assert(shdr.sh_size == contents.len); | 4086 | assert(shdr.sh_size == contents.len); |
| 4172 | try self.base.file.?.pwriteAll(contents, shdr.sh_offset); | 4087 | try self.base.file.?.pwriteAll(contents, shdr.sh_offset); |
| 4173 | } | 4088 | } |
| 4174 | 4089 | ||
| 4175 | if (self.hash_section_index) |shndx| { | 4090 | if (self.hash_section_index) |shndx| { |
| 4176 | const shdr = self.shdrs.items[shndx]; | 4091 | const shdr = slice.items(.shdr)[shndx]; |
| 4177 | try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset); | 4092 | try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset); |
| 4178 | } | 4093 | } |
| 4179 | 4094 | ||
| 4180 | if (self.gnu_hash_section_index) |shndx| { | 4095 | if (self.gnu_hash_section_index) |shndx| { |
| 4181 | const shdr = self.shdrs.items[shndx]; | 4096 | const shdr = slice.items(.shdr)[shndx]; |
| 4182 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size()); | 4097 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size()); |
| 4183 | defer buffer.deinit(); | 4098 | defer buffer.deinit(); |
| 4184 | try self.gnu_hash.write(self, buffer.writer()); | 4099 | try self.gnu_hash.write(self, buffer.writer()); |
| ... | @@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4186 | } | 4101 | } |
| 4187 | 4102 | ||
| 4188 | if (self.versym_section_index) |shndx| { | 4103 | if (self.versym_section_index) |shndx| { |
| 4189 | const shdr = self.shdrs.items[shndx]; | 4104 | const shdr = slice.items(.shdr)[shndx]; |
| 4190 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset); | 4105 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset); |
| 4191 | } | 4106 | } |
| 4192 | 4107 | ||
| 4193 | if (self.verneed_section_index) |shndx| { | 4108 | if (self.verneed_section_index) |shndx| { |
| 4194 | const shdr = self.shdrs.items[shndx]; | 4109 | const shdr = slice.items(.shdr)[shndx]; |
| 4195 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size()); | 4110 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size()); |
| 4196 | defer buffer.deinit(); | 4111 | defer buffer.deinit(); |
| 4197 | try self.verneed.write(buffer.writer()); | 4112 | try self.verneed.write(buffer.writer()); |
| ... | @@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4199 | } | 4114 | } |
| 4200 | 4115 | ||
| 4201 | if (self.dynamic_section_index) |shndx| { | 4116 | if (self.dynamic_section_index) |shndx| { |
| 4202 | const shdr = self.shdrs.items[shndx]; | 4117 | const shdr = slice.items(.shdr)[shndx]; |
| 4203 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self)); | 4118 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self)); |
| 4204 | defer buffer.deinit(); | 4119 | defer buffer.deinit(); |
| 4205 | try self.dynamic.write(self, buffer.writer()); | 4120 | try self.dynamic.write(self, buffer.writer()); |
| ... | @@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4207 | } | 4122 | } |
| 4208 | 4123 | ||
| 4209 | if (self.dynsymtab_section_index) |shndx| { | 4124 | if (self.dynsymtab_section_index) |shndx| { |
| 4210 | const shdr = self.shdrs.items[shndx]; | 4125 | const shdr = slice.items(.shdr)[shndx]; |
| 4211 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size()); | 4126 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size()); |
| 4212 | defer buffer.deinit(); | 4127 | defer buffer.deinit(); |
| 4213 | try self.dynsym.write(self, buffer.writer()); | 4128 | try self.dynsym.write(self, buffer.writer()); |
| ... | @@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4215 | } | 4130 | } |
| 4216 | 4131 | ||
| 4217 | if (self.dynstrtab_section_index) |shndx| { | 4132 | if (self.dynstrtab_section_index) |shndx| { |
| 4218 | const shdr = self.shdrs.items[shndx]; | 4133 | const shdr = slice.items(.shdr)[shndx]; |
| 4219 | try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset); | 4134 | try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset); |
| 4220 | } | 4135 | } |
| 4221 | 4136 | ||
| 4222 | if (self.eh_frame_section_index) |shndx| { | 4137 | if (self.eh_frame_section_index) |shndx| { |
| 4223 | const shdr = self.shdrs.items[shndx]; | 4138 | const shdr = slice.items(.shdr)[shndx]; |
| 4224 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 4139 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 4225 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 4140 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4226 | defer buffer.deinit(); | 4141 | defer buffer.deinit(); |
| ... | @@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4229 | } | 4144 | } |
| 4230 | 4145 | ||
| 4231 | if (self.eh_frame_hdr_section_index) |shndx| { | 4146 | if (self.eh_frame_hdr_section_index) |shndx| { |
| 4232 | const shdr = self.shdrs.items[shndx]; | 4147 | const shdr = slice.items(.shdr)[shndx]; |
| 4233 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 4148 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 4234 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 4149 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4235 | defer buffer.deinit(); | 4150 | defer buffer.deinit(); |
| ... | @@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4238 | } | 4153 | } |
| 4239 | 4154 | ||
| 4240 | if (self.got_section_index) |index| { | 4155 | if (self.got_section_index) |index| { |
| 4241 | const shdr = self.shdrs.items[index]; | 4156 | const shdr = slice.items(.shdr)[index]; |
| 4242 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self)); | 4157 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self)); |
| 4243 | defer buffer.deinit(); | 4158 | defer buffer.deinit(); |
| 4244 | try self.got.write(self, buffer.writer()); | 4159 | try self.got.write(self, buffer.writer()); |
| ... | @@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4246 | } | 4161 | } |
| 4247 | 4162 | ||
| 4248 | if (self.rela_dyn_section_index) |shndx| { | 4163 | if (self.rela_dyn_section_index) |shndx| { |
| 4249 | const shdr = self.shdrs.items[shndx]; | 4164 | const shdr = slice.items(.shdr)[shndx]; |
| 4250 | try self.got.addRela(self); | 4165 | try self.got.addRela(self); |
| 4251 | try self.copy_rel.addRela(self); | 4166 | try self.copy_rel.addRela(self); |
| 4252 | self.sortRelaDyn(); | 4167 | self.sortRelaDyn(); |
| ... | @@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4254 | } | 4169 | } |
| 4255 | 4170 | ||
| 4256 | if (self.plt_section_index) |shndx| { | 4171 | if (self.plt_section_index) |shndx| { |
| 4257 | const shdr = self.shdrs.items[shndx]; | 4172 | const shdr = slice.items(.shdr)[shndx]; |
| 4258 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self)); | 4173 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self)); |
| 4259 | defer buffer.deinit(); | 4174 | defer buffer.deinit(); |
| 4260 | try self.plt.write(self, buffer.writer()); | 4175 | try self.plt.write(self, buffer.writer()); |
| ... | @@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4262 | } | 4177 | } |
| 4263 | 4178 | ||
| 4264 | if (self.got_plt_section_index) |shndx| { | 4179 | if (self.got_plt_section_index) |shndx| { |
| 4265 | const shdr = self.shdrs.items[shndx]; | 4180 | const shdr = slice.items(.shdr)[shndx]; |
| 4266 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self)); | 4181 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self)); |
| 4267 | defer buffer.deinit(); | 4182 | defer buffer.deinit(); |
| 4268 | try self.got_plt.write(self, buffer.writer()); | 4183 | try self.got_plt.write(self, buffer.writer()); |
| ... | @@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4270 | } | 4185 | } |
| 4271 | 4186 | ||
| 4272 | if (self.plt_got_section_index) |shndx| { | 4187 | if (self.plt_got_section_index) |shndx| { |
| 4273 | const shdr = self.shdrs.items[shndx]; | 4188 | const shdr = slice.items(.shdr)[shndx]; |
| 4274 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self)); | 4189 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self)); |
| 4275 | defer buffer.deinit(); | 4190 | defer buffer.deinit(); |
| 4276 | try self.plt_got.write(self, buffer.writer()); | 4191 | try self.plt_got.write(self, buffer.writer()); |
| ... | @@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4278 | } | 4193 | } |
| 4279 | 4194 | ||
| 4280 | if (self.rela_plt_section_index) |shndx| { | 4195 | if (self.rela_plt_section_index) |shndx| { |
| 4281 | const shdr = self.shdrs.items[shndx]; | 4196 | const shdr = slice.items(.shdr)[shndx]; |
| 4282 | try self.plt.addRela(self); | 4197 | try self.plt.addRela(self); |
| 4283 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset); | 4198 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset); |
| 4284 | } | 4199 | } |
| ... | @@ -4287,19 +4202,21 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4287,19 +4202,21 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4287 | try self.writeShStrtab(); | 4202 | try self.writeShStrtab(); |
| 4288 | } | 4203 | } |
| 4289 | 4204 | ||
| 4205 | // FIXME:JK again, why is this needed? | ||
| 4290 | pub fn writeShStrtab(self: *Elf) !void { | 4206 | pub fn writeShStrtab(self: *Elf) !void { |
| 4291 | if (self.shstrtab_section_index) |index| { | 4207 | if (self.shstrtab_section_index) |index| { |
| 4292 | const shdr = self.shdrs.items[index]; | 4208 | const shdr = self.sections.items(.shdr)[index]; |
| 4293 | log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size }); | 4209 | log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size }); |
| 4294 | try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset); | 4210 | try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset); |
| 4295 | } | 4211 | } |
| 4296 | } | 4212 | } |
| 4297 | 4213 | ||
| 4298 | pub fn writeSymtab(self: *Elf) !void { | 4214 | pub fn writeSymtab(self: *Elf) !void { |
| 4299 | const target = self.base.comp.root_mod.resolved_target.result; | ||
| 4300 | const gpa = self.base.comp.gpa; | 4215 | const gpa = self.base.comp.gpa; |
| 4301 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; | 4216 | const target = self.getTarget(); |
| 4302 | const strtab_shdr = self.shdrs.items[self.strtab_section_index.?]; | 4217 | const slice = self.sections.slice(); |
| 4218 | const symtab_shdr = slice.items(.shdr)[self.symtab_section_index.?]; | ||
| 4219 | const strtab_shdr = slice.items(.shdr)[self.strtab_section_index.?]; | ||
| 4303 | const sym_size: u64 = switch (self.ptr_width) { | 4220 | const sym_size: u64 = switch (self.ptr_width) { |
| 4304 | .p32 => @sizeOf(elf.Elf32_Sym), | 4221 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4305 | .p64 => @sizeOf(elf.Elf64_Sym), | 4222 | .p64 => @sizeOf(elf.Elf64_Sym), |
| ... | @@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void { | ... | @@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4387 | } | 4304 | } |
| 4388 | 4305 | ||
| 4389 | fn writeSectionSymbols(self: *Elf) void { | 4306 | fn writeSectionSymbols(self: *Elf) void { |
| 4307 | const slice = self.sections.slice(); | ||
| 4390 | var ilocal: u32 = 1; | 4308 | var ilocal: u32 = 1; |
| 4391 | for (self.output_sections.keys()) |shndx| { | 4309 | for (slice.items(.shdr), 0..) |shdr, shndx| { |
| 4392 | const shdr = self.shdrs.items[shndx]; | ||
| 4393 | const out_sym = &self.symtab.items[ilocal]; | 4310 | const out_sym = &self.symtab.items[ilocal]; |
| 4394 | out_sym.* = .{ | 4311 | out_sym.* = .{ |
| 4395 | .st_name = 0, | 4312 | .st_name = 0, |
| ... | @@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void { | ... | @@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void { |
| 4403 | } | 4320 | } |
| 4404 | 4321 | ||
| 4405 | if (self.eh_frame_section_index) |shndx| { | 4322 | if (self.eh_frame_section_index) |shndx| { |
| 4406 | const shdr = self.shdrs.items[shndx]; | 4323 | const shdr = slice.items(.shdr)[shndx]; |
| 4407 | const out_sym = &self.symtab.items[ilocal]; | 4324 | const out_sym = &self.symtab.items[ilocal]; |
| 4408 | out_sym.* = .{ | 4325 | out_sym.* = .{ |
| 4409 | .st_name = 0, | 4326 | .st_name = 0, |
| ... | @@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void { | ... | @@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void { |
| 4418 | } | 4335 | } |
| 4419 | 4336 | ||
| 4420 | pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 { | 4337 | pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 { |
| 4421 | if (self.eh_frame_section_index) |index| { | 4338 | _ = self; |
| 4422 | if (index == shndx) return @intCast(self.output_sections.keys().len + 1); | 4339 | return shndx + 1; |
| 4423 | } | ||
| 4424 | return @intCast(self.output_sections.getIndex(shndx).? + 1); | ||
| 4425 | } | 4340 | } |
| 4426 | 4341 | ||
| 4427 | /// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF. | 4342 | /// Always 4 or 8 depending on whether this is 32-bit ELF or 64-bit ELF. |
| ... | @@ -4435,8 +4350,7 @@ pub fn ptrWidthBytes(self: Elf) u8 { | ... | @@ -4435,8 +4350,7 @@ pub fn ptrWidthBytes(self: Elf) u8 { |
| 4435 | /// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes | 4350 | /// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes |
| 4436 | /// in a 32-bit ELF file. | 4351 | /// in a 32-bit ELF file. |
| 4437 | pub fn archPtrWidthBytes(self: Elf) u8 { | 4352 | pub fn archPtrWidthBytes(self: Elf) u8 { |
| 4438 | const target = self.base.comp.root_mod.resolved_target.result; | 4353 | return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8)); |
| 4439 | return @intCast(@divExact(target.ptrBitWidth(), 8)); | ||
| 4440 | } | 4354 | } |
| 4441 | 4355 | ||
| 4442 | fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { | 4356 | fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { |
| ... | @@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct { | ... | @@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct { |
| 4816 | 4730 | ||
| 4817 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 { | 4731 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 { |
| 4818 | const gpa = self.base.comp.gpa; | 4732 | const gpa = self.base.comp.gpa; |
| 4819 | const index: u32 = @intCast(self.shdrs.items.len); | 4733 | const index: u32 = @intCast(try self.sections.addOne(gpa)); |
| 4820 | const shdr = try self.shdrs.addOne(gpa); | 4734 | self.sections.set(index, .{ |
| 4821 | shdr.* = .{ | 4735 | .shdr = .{ |
| 4822 | .sh_name = opts.name, | 4736 | .sh_name = opts.name, |
| 4823 | .sh_type = opts.type, | 4737 | .sh_type = opts.type, |
| 4824 | .sh_flags = opts.flags, | 4738 | .sh_flags = opts.flags, |
| 4825 | .sh_addr = 0, | 4739 | .sh_addr = 0, |
| 4826 | .sh_offset = opts.offset, | 4740 | .sh_offset = opts.offset, |
| 4827 | .sh_size = 0, | 4741 | .sh_size = 0, |
| 4828 | .sh_link = opts.link, | 4742 | .sh_link = opts.link, |
| 4829 | .sh_info = opts.info, | 4743 | .sh_info = opts.info, |
| 4830 | .sh_addralign = opts.addralign, | 4744 | .sh_addralign = opts.addralign, |
| 4831 | .sh_entsize = opts.entsize, | 4745 | .sh_entsize = opts.entsize, |
| 4832 | }; | 4746 | }, |
| 4747 | }); | ||
| 4833 | return index; | 4748 | return index; |
| 4834 | } | 4749 | } |
| 4835 | 4750 | ||
| 4836 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 { | 4751 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 { |
| 4837 | for (self.shdrs.items, 0..) |*shdr, i| { | 4752 | for (self.sections.items(.shdr), 0..) |*shdr, i| { |
| 4838 | const this_name = self.getShString(shdr.sh_name); | 4753 | const this_name = self.getShString(shdr.sh_name); |
| 4839 | if (mem.eql(u8, this_name, name)) return @intCast(i); | 4754 | if (mem.eql(u8, this_name, name)) return @intCast(i); |
| 4840 | } else return null; | 4755 | } else return null; |
| ... | @@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 { | ... | @@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 { |
| 5012 | break :blk self.got_plt_section_index.?; | 4927 | break :blk self.got_plt_section_index.?; |
| 5013 | break :blk if (self.got_section_index) |shndx| shndx else null; | 4928 | break :blk if (self.got_section_index) |shndx| shndx else null; |
| 5014 | }; | 4929 | }; |
| 5015 | return if (shndx) |index| @intCast(self.shdrs.items[index].sh_addr) else 0; | 4930 | return if (shndx) |index| @intCast(self.sections.items(.shdr)[index].sh_addr) else 0; |
| 5016 | } | 4931 | } |
| 5017 | 4932 | ||
| 5018 | pub fn tpAddress(self: *Elf) i64 { | 4933 | pub fn tpAddress(self: *Elf) i64 { |
| ... | @@ -5366,16 +5281,16 @@ fn fmtDumpState( | ... | @@ -5366,16 +5281,16 @@ fn fmtDumpState( |
| 5366 | } | 5281 | } |
| 5367 | 5282 | ||
| 5368 | try writer.writeAll("\nOutput shdrs\n"); | 5283 | try writer.writeAll("\nOutput shdrs\n"); |
| 5369 | for (self.shdrs.items, 0..) |shdr, shndx| { | 5284 | for (self.sections.items(.shdr), self.sections.items(.phndx), 0..) |shdr, phndx, shndx| { |
| 5370 | try writer.print(" shdr({d}) : phdr({?d}) : {}\n", .{ | 5285 | try writer.print(" shdr({d}) : phdr({d}) : {}\n", .{ |
| 5371 | shndx, | 5286 | shndx, |
| 5372 | self.phdr_to_shdr_table.get(@intCast(shndx)), | 5287 | phndx, |
| 5373 | self.fmtShdr(shdr), | 5288 | self.fmtShdr(shdr), |
| 5374 | }); | 5289 | }); |
| 5375 | } | 5290 | } |
| 5376 | try writer.writeAll("\nOutput phdrs\n"); | 5291 | try writer.writeAll("\nOutput phdrs\n"); |
| 5377 | for (self.phdrs.items, 0..) |phdr, phndx| { | 5292 | for (self.phdrs.items, 0..) |phdr, phndx| { |
| 5378 | try writer.print(" phdr{d} : {}\n", .{ phndx, self.fmtPhdr(phdr) }); | 5293 | try writer.print(" phdr({d}) : {}\n", .{ phndx, self.fmtPhdr(phdr) }); |
| 5379 | } | 5294 | } |
| 5380 | } | 5295 | } |
| 5381 | 5296 | ||
| ... | @@ -5613,7 +5528,11 @@ pub const SymbolResolver = struct { | ... | @@ -5613,7 +5528,11 @@ pub const SymbolResolver = struct { |
| 5613 | pub const Index = u32; | 5528 | pub const Index = u32; |
| 5614 | }; | 5529 | }; |
| 5615 | 5530 | ||
| 5616 | const LastAtomAndFreeList = struct { | 5531 | const Section = struct { |
| 5532 | shdr: elf.Elf64_Shdr, | ||
| 5533 | phndx: u32 = 0, | ||
| 5534 | atom_list: std.ArrayListUnmanaged(Ref) = .{}, | ||
| 5535 | |||
| 5617 | /// Index of the last allocated atom in this section. | 5536 | /// Index of the last allocated atom in this section. |
| 5618 | last_atom_index: Atom.Index = 0, | 5537 | last_atom_index: Atom.Index = 0, |
| 5619 | 5538 | ||
| ... | @@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct { | ... | @@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct { |
| 5634 | /// by 1 byte. It will then have -1 overcapacity. | 5553 | /// by 1 byte. It will then have -1 overcapacity. |
| 5635 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, | 5554 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 5636 | }; | 5555 | }; |
| 5637 | const LastAtomAndFreeListTable = std.AutoArrayHashMapUnmanaged(u32, LastAtomAndFreeList); | ||
| 5638 | |||
| 5639 | const RelaSection = struct { | ||
| 5640 | shndx: u32, | ||
| 5641 | atom_list: std.ArrayListUnmanaged(Ref) = .{}, | ||
| 5642 | }; | ||
| 5643 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); | ||
| 5644 | 5556 | ||
| 5645 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { | 5557 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { |
| 5646 | return switch (cpu_arch) { | 5558 | return switch (cpu_arch) { |
src/link/Elf/Atom.zig+8-8| ... | @@ -48,7 +48,7 @@ pub fn name(self: Atom, elf_file: *Elf) [:0]const u8 { | ... | @@ -48,7 +48,7 @@ pub fn name(self: Atom, elf_file: *Elf) [:0]const u8 { |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | pub fn address(self: Atom, elf_file: *Elf) i64 { | 50 | pub fn address(self: Atom, elf_file: *Elf) i64 { |
| 51 | const shdr = elf_file.shdrs.items[self.output_section_index]; | 51 | const shdr = elf_file.sections.items(.shdr)[self.output_section_index]; |
| 52 | return @as(i64, @intCast(shdr.sh_addr)) + self.value; | 52 | return @as(i64, @intCast(shdr.sh_addr)) + self.value; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| ... | @@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { | ... | @@ -116,10 +116,10 @@ pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { |
| 116 | 116 | ||
| 117 | pub fn allocate(self: *Atom, elf_file: *Elf) !void { | 117 | pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 118 | const zo = elf_file.zigObjectPtr().?; | 118 | const zo = elf_file.zigObjectPtr().?; |
| 119 | const shdr = &elf_file.shdrs.items[self.output_section_index]; | 119 | const slice = elf_file.sections.slice(); |
| 120 | const meta = elf_file.last_atom_and_free_list_table.getPtr(self.output_section_index).?; | 120 | const shdr = &slice.items(.shdr)[self.output_section_index]; |
| 121 | const free_list = &meta.free_list; | 121 | const free_list = &slice.items(.free_list)[self.output_section_index]; |
| 122 | const last_atom_index = &meta.last_atom_index; | 122 | const last_atom_index = &slice.items(.last_atom_index)[self.output_section_index]; |
| 123 | const new_atom_ideal_capacity = Elf.padToIdeal(self.size); | 123 | const new_atom_ideal_capacity = Elf.padToIdeal(self.size); |
| 124 | 124 | ||
| 125 | // We use these to indicate our intention to update metadata, placing the new atom, | 125 | // We use these to indicate our intention to update metadata, placing the new atom, |
| ... | @@ -254,9 +254,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void { | ... | @@ -254,9 +254,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 254 | const comp = elf_file.base.comp; | 254 | const comp = elf_file.base.comp; |
| 255 | const gpa = comp.gpa; | 255 | const gpa = comp.gpa; |
| 256 | const shndx = self.output_section_index; | 256 | const shndx = self.output_section_index; |
| 257 | const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; | 257 | const slice = elf_file.sections.slice(); |
| 258 | const free_list = &meta.free_list; | 258 | const free_list = &slice.items(.free_list)[shndx]; |
| 259 | const last_atom_index = &meta.last_atom_index; | 259 | const last_atom_index = &slice.items(.last_atom_index)[shndx]; |
| 260 | var already_have_free_list_node = false; | 260 | var already_have_free_list_node = false; |
| 261 | { | 261 | { |
| 262 | var i: usize = 0; | 262 | var i: usize = 0; |
src/link/Elf/LinkerDefined.zig+17-15| ... | @@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | ... | @@ -129,9 +129,10 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 129 | 129 | ||
| 130 | pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | 130 | pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 131 | const gpa = elf_file.base.comp.gpa; | 131 | const gpa = elf_file.base.comp.gpa; |
| 132 | const slice = elf_file.sections.slice(); | ||
| 132 | 133 | ||
| 133 | var nsyms: usize = 0; | 134 | var nsyms: usize = 0; |
| 134 | for (elf_file.shdrs.items) |shdr| { | 135 | for (slice.items(.shdr)) |shdr| { |
| 135 | if (elf_file.getStartStopBasename(shdr)) |_| { | 136 | if (elf_file.getStartStopBasename(shdr)) |_| { |
| 136 | nsyms += 2; // __start_, __stop_ | 137 | nsyms += 2; // __start_, __stop_ |
| 137 | } | 138 | } |
| ... | @@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | ... | @@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 143 | try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra)); | 144 | try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra)); |
| 144 | try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms); | 145 | try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms); |
| 145 | 146 | ||
| 146 | for (elf_file.shdrs.items) |shdr| { | 147 | for (slice.items(.shdr)) |shdr| { |
| 147 | if (elf_file.getStartStopBasename(shdr)) |name| { | 148 | if (elf_file.getStartStopBasename(shdr)) |name| { |
| 148 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); | 149 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 149 | defer gpa.free(start_name); | 150 | defer gpa.free(start_name); |
| ... | @@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void { | ... | @@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 193 | pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | 194 | pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 194 | const comp = elf_file.base.comp; | 195 | const comp = elf_file.base.comp; |
| 195 | const link_mode = comp.config.link_mode; | 196 | const link_mode = comp.config.link_mode; |
| 197 | const shdrs = elf_file.sections.items(.shdr); | ||
| 196 | 198 | ||
| 197 | const allocSymbol = struct { | 199 | const allocSymbol = struct { |
| 198 | fn allocSymbol(ld: *LinkerDefined, index: Symbol.Index, value: u64, osec: u32, ef: *Elf) void { | 200 | fn allocSymbol(ld: *LinkerDefined, index: Symbol.Index, value: u64, osec: u32, ef: *Elf) void { |
| ... | @@ -204,7 +206,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -204,7 +206,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 204 | 206 | ||
| 205 | // _DYNAMIC | 207 | // _DYNAMIC |
| 206 | if (elf_file.dynamic_section_index) |shndx| { | 208 | if (elf_file.dynamic_section_index) |shndx| { |
| 207 | const shdr = &elf_file.shdrs.items[shndx]; | 209 | const shdr = shdrs[shndx]; |
| 208 | allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file); | 210 | allocSymbol(self, self.dynamic_index.?, shdr.sh_addr, shndx, elf_file); |
| 209 | } | 211 | } |
| 210 | 212 | ||
| ... | @@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -213,21 +215,21 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 213 | 215 | ||
| 214 | // __init_array_start, __init_array_end | 216 | // __init_array_start, __init_array_end |
| 215 | if (elf_file.sectionByName(".init_array")) |shndx| { | 217 | if (elf_file.sectionByName(".init_array")) |shndx| { |
| 216 | const shdr = &elf_file.shdrs.items[shndx]; | 218 | const shdr = shdrs[shndx]; |
| 217 | allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file); | 219 | allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 218 | allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); | 220 | allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); |
| 219 | } | 221 | } |
| 220 | 222 | ||
| 221 | // __fini_array_start, __fini_array_end | 223 | // __fini_array_start, __fini_array_end |
| 222 | if (elf_file.sectionByName(".fini_array")) |shndx| { | 224 | if (elf_file.sectionByName(".fini_array")) |shndx| { |
| 223 | const shdr = &elf_file.shdrs.items[shndx]; | 225 | const shdr = shdrs[shndx]; |
| 224 | allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file); | 226 | allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 225 | allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); | 227 | allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); |
| 226 | } | 228 | } |
| 227 | 229 | ||
| 228 | // __preinit_array_start, __preinit_array_end | 230 | // __preinit_array_start, __preinit_array_end |
| 229 | if (elf_file.sectionByName(".preinit_array")) |shndx| { | 231 | if (elf_file.sectionByName(".preinit_array")) |shndx| { |
| 230 | const shdr = &elf_file.shdrs.items[shndx]; | 232 | const shdr = shdrs[shndx]; |
| 231 | allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file); | 233 | allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 232 | allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); | 234 | allocSymbol(self, self.preinit_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); |
| 233 | } | 235 | } |
| ... | @@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -235,38 +237,38 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 235 | // _GLOBAL_OFFSET_TABLE_ | 237 | // _GLOBAL_OFFSET_TABLE_ |
| 236 | if (elf_file.getTarget().cpu.arch == .x86_64) { | 238 | if (elf_file.getTarget().cpu.arch == .x86_64) { |
| 237 | if (elf_file.got_plt_section_index) |shndx| { | 239 | if (elf_file.got_plt_section_index) |shndx| { |
| 238 | const shdr = elf_file.shdrs.items[shndx]; | 240 | const shdr = shdrs[shndx]; |
| 239 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); | 241 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); |
| 240 | } | 242 | } |
| 241 | } else { | 243 | } else { |
| 242 | if (elf_file.got_section_index) |shndx| { | 244 | if (elf_file.got_section_index) |shndx| { |
| 243 | const shdr = elf_file.shdrs.items[shndx]; | 245 | const shdr = shdrs[shndx]; |
| 244 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); | 246 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); |
| 245 | } | 247 | } |
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | // _PROCEDURE_LINKAGE_TABLE_ | 250 | // _PROCEDURE_LINKAGE_TABLE_ |
| 249 | if (elf_file.plt_section_index) |shndx| { | 251 | if (elf_file.plt_section_index) |shndx| { |
| 250 | const shdr = &elf_file.shdrs.items[shndx]; | 252 | const shdr = shdrs[shndx]; |
| 251 | allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file); | 253 | allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file); |
| 252 | } | 254 | } |
| 253 | 255 | ||
| 254 | // __dso_handle | 256 | // __dso_handle |
| 255 | if (self.dso_handle_index) |index| { | 257 | if (self.dso_handle_index) |index| { |
| 256 | const shdr = &elf_file.shdrs.items[1]; | 258 | const shdr = shdrs[1]; |
| 257 | allocSymbol(self, index, shdr.sh_addr, 0, elf_file); | 259 | allocSymbol(self, index, shdr.sh_addr, 0, elf_file); |
| 258 | } | 260 | } |
| 259 | 261 | ||
| 260 | // __GNU_EH_FRAME_HDR | 262 | // __GNU_EH_FRAME_HDR |
| 261 | if (elf_file.eh_frame_hdr_section_index) |shndx| { | 263 | if (elf_file.eh_frame_hdr_section_index) |shndx| { |
| 262 | const shdr = &elf_file.shdrs.items[shndx]; | 264 | const shdr = shdrs[shndx]; |
| 263 | allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file); | 265 | allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file); |
| 264 | } | 266 | } |
| 265 | 267 | ||
| 266 | // __rela_iplt_start, __rela_iplt_end | 268 | // __rela_iplt_start, __rela_iplt_end |
| 267 | if (elf_file.rela_dyn_section_index) |shndx| blk: { | 269 | if (elf_file.rela_dyn_section_index) |shndx| blk: { |
| 268 | if (link_mode != .static or comp.config.pie) break :blk; | 270 | if (link_mode != .static or comp.config.pie) break :blk; |
| 269 | const shdr = &elf_file.shdrs.items[shndx]; | 271 | const shdr = shdrs[shndx]; |
| 270 | const end_addr = shdr.sh_addr + shdr.sh_size; | 272 | const end_addr = shdr.sh_addr + shdr.sh_size; |
| 271 | const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); | 273 | const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); |
| 272 | allocSymbol(self, self.rela_iplt_start_index.?, start_addr, shndx, elf_file); | 274 | allocSymbol(self, self.rela_iplt_start_index.?, start_addr, shndx, elf_file); |
| ... | @@ -277,7 +279,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -277,7 +279,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 277 | { | 279 | { |
| 278 | var value: u64 = 0; | 280 | var value: u64 = 0; |
| 279 | var osec: u32 = 0; | 281 | var osec: u32 = 0; |
| 280 | for (elf_file.shdrs.items, 0..) |shdr, shndx| { | 282 | for (shdrs, 0..) |shdr, shndx| { |
| 281 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) { | 283 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) { |
| 282 | value = shdr.sh_addr + shdr.sh_size; | 284 | value = shdr.sh_addr + shdr.sh_size; |
| 283 | osec = @intCast(shndx); | 285 | osec = @intCast(shndx); |
| ... | @@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 289 | // __global_pointer$ | 291 | // __global_pointer$ |
| 290 | if (self.global_pointer_index) |index| { | 292 | if (self.global_pointer_index) |index| { |
| 291 | const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{ | 293 | const value, const osec = if (elf_file.sectionByName(".sdata")) |shndx| .{ |
| 292 | elf_file.shdrs.items[shndx].sh_addr + 0x800, | 294 | shdrs[shndx].sh_addr + 0x800, |
| 293 | shndx, | 295 | shndx, |
| 294 | } else .{ 0, 0 }; | 296 | } else .{ 0, 0 }; |
| 295 | allocSymbol(self, index, value, osec, elf_file); | 297 | allocSymbol(self, index, value, osec, elf_file); |
| ... | @@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 305 | const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file); | 307 | const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file); |
| 306 | const stop = elf_file.symbol(stop_ref).?; | 308 | const stop = elf_file.symbol(stop_ref).?; |
| 307 | const shndx = elf_file.sectionByName(name["__start_".len..]).?; | 309 | const shndx = elf_file.sectionByName(name["__start_".len..]).?; |
| 308 | const shdr = &elf_file.shdrs.items[shndx]; | 310 | const shdr = shdrs[shndx]; |
| 309 | start.value = @intCast(shdr.sh_addr); | 311 | start.value = @intCast(shdr.sh_addr); |
| 310 | start.output_section_index = shndx; | 312 | start.output_section_index = shndx; |
| 311 | stop.value = @intCast(shdr.sh_addr + shdr.sh_size); | 313 | stop.value = @intCast(shdr.sh_addr + shdr.sh_size); |
src/link/Elf/Object.zig+7-12| ... | @@ -998,9 +998,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -998,9 +998,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { |
| 998 | 998 | ||
| 999 | const comp = elf_file.base.comp; | 999 | const comp = elf_file.base.comp; |
| 1000 | const gpa = comp.gpa; | 1000 | const gpa = comp.gpa; |
| 1001 | const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index); | 1001 | const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index]; |
| 1002 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 1002 | try atom_list.append(gpa, .{ .index = atom_index, .file = self.index }); |
| 1003 | try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index }); | ||
| 1004 | } | 1003 | } |
| 1005 | } | 1004 | } |
| 1006 | 1005 | ||
| ... | @@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -1011,14 +1010,15 @@ pub fn initRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1011 | const shndx = atom_ptr.relocsShndx() orelse continue; | 1010 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1012 | const shdr = self.shdrs.items[shndx]; | 1011 | const shdr = self.shdrs.items[shndx]; |
| 1013 | const out_shndx = try self.initOutputSection(elf_file, shdr); | 1012 | const out_shndx = try self.initOutputSection(elf_file, shdr); |
| 1014 | const out_shdr = &elf_file.shdrs.items[out_shndx]; | 1013 | const out_shdr = &elf_file.sections.items(.shdr)[out_shndx]; |
| 1014 | out_shdr.sh_type = elf.SHT_RELA; | ||
| 1015 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); | 1015 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); |
| 1016 | out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela); | 1016 | out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela); |
| 1017 | out_shdr.sh_flags |= elf.SHF_INFO_LINK; | 1017 | out_shdr.sh_flags |= elf.SHF_INFO_LINK; |
| 1018 | } | 1018 | } |
| 1019 | } | 1019 | } |
| 1020 | 1020 | ||
| 1021 | pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { | 1021 | pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) void { |
| 1022 | for (self.atoms_indexes.items) |atom_index| { | 1022 | for (self.atoms_indexes.items) |atom_index| { |
| 1023 | const atom_ptr = self.atom(atom_index) orelse continue; | 1023 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1024 | if (!atom_ptr.alive) continue; | 1024 | if (!atom_ptr.alive) continue; |
| ... | @@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1027 | const shdr = self.shdrs.items[shndx]; | 1027 | const shdr = self.shdrs.items[shndx]; |
| 1028 | break :blk self.initOutputSection(elf_file, shdr) catch unreachable; | 1028 | break :blk self.initOutputSection(elf_file, shdr) catch unreachable; |
| 1029 | }; | 1029 | }; |
| 1030 | const shdr = &elf_file.shdrs.items[shndx]; | 1030 | const slice = elf_file.sections.slice(); |
| 1031 | const shdr = &slice.items(.shdr)[shndx]; | ||
| 1031 | shdr.sh_info = atom_ptr.output_section_index; | 1032 | shdr.sh_info = atom_ptr.output_section_index; |
| 1032 | shdr.sh_link = elf_file.symtab_section_index.?; | 1033 | shdr.sh_link = elf_file.symtab_section_index.?; |
| 1033 | |||
| 1034 | const comp = elf_file.base.comp; | ||
| 1035 | const gpa = comp.gpa; | ||
| 1036 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom_ptr.output_section_index); | ||
| 1037 | if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx }; | ||
| 1038 | try gop.value_ptr.atom_list.append(gpa, .{ .index = atom_index, .file = self.index }); | ||
| 1039 | } | 1034 | } |
| 1040 | } | 1035 | } |
| 1041 | 1036 |
src/link/Elf/Symbol.zig+6-6| ... | @@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool | ... | @@ -126,7 +126,7 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true, trampoline: bool |
| 126 | const sym_name = symbol.name(elf_file); | 126 | const sym_name = symbol.name(elf_file); |
| 127 | const sh_addr, const sh_size = blk: { | 127 | const sh_addr, const sh_size = blk: { |
| 128 | const shndx = elf_file.eh_frame_section_index orelse break :blk .{ 0, 0 }; | 128 | const shndx = elf_file.eh_frame_section_index orelse break :blk .{ 0, 0 }; |
| 129 | const shdr = elf_file.shdrs.items[shndx]; | 129 | const shdr = elf_file.sections.items(.shdr)[shndx]; |
| 130 | break :blk .{ shdr.sh_addr, shdr.sh_size }; | 130 | break :blk .{ shdr.sh_addr, shdr.sh_size }; |
| 131 | }; | 131 | }; |
| 132 | if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or | 132 | if (mem.startsWith(u8, sym_name, "__EH_FRAME_BEGIN__") or |
| ... | @@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 { | ... | @@ -173,7 +173,7 @@ pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 173 | pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { | 173 | pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 174 | if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; | 174 | if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; |
| 175 | const extras = symbol.extra(elf_file); | 175 | const extras = symbol.extra(elf_file); |
| 176 | const shdr = elf_file.shdrs.items[elf_file.plt_got_section_index.?]; | 176 | const shdr = elf_file.sections.items(.shdr)[elf_file.plt_got_section_index.?]; |
| 177 | const cpu_arch = elf_file.getTarget().cpu.arch; | 177 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 178 | return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch)); | 178 | return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch)); |
| 179 | } | 179 | } |
| ... | @@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { | ... | @@ -181,7 +181,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 181 | pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { | 181 | pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 182 | if (!symbol.flags.has_plt) return 0; | 182 | if (!symbol.flags.has_plt) return 0; |
| 183 | const extras = symbol.extra(elf_file); | 183 | const extras = symbol.extra(elf_file); |
| 184 | const shdr = elf_file.shdrs.items[elf_file.plt_section_index.?]; | 184 | const shdr = elf_file.sections.items(.shdr)[elf_file.plt_section_index.?]; |
| 185 | const cpu_arch = elf_file.getTarget().cpu.arch; | 185 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 186 | return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch)); | 186 | return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch)); |
| 187 | } | 187 | } |
| ... | @@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { | ... | @@ -189,13 +189,13 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 189 | pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 { | 189 | pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 190 | if (!symbol.flags.has_plt) return 0; | 190 | if (!symbol.flags.has_plt) return 0; |
| 191 | const extras = symbol.extra(elf_file); | 191 | const extras = symbol.extra(elf_file); |
| 192 | const shdr = elf_file.shdrs.items[elf_file.got_plt_section_index.?]; | 192 | const shdr = elf_file.sections.items(.shdr)[elf_file.got_plt_section_index.?]; |
| 193 | return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size); | 193 | return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size); |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 { | 196 | pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 197 | if (!symbol.flags.has_copy_rel) return 0; | 197 | if (!symbol.flags.has_copy_rel) return 0; |
| 198 | const shdr = elf_file.shdrs.items[elf_file.copy_rel_section_index.?]; | 198 | const shdr = elf_file.sections.items(.shdr)[elf_file.copy_rel_section_index.?]; |
| 199 | return @as(i64, @intCast(shdr.sh_addr)) + symbol.value; | 199 | return @as(i64, @intCast(shdr.sh_addr)) + symbol.value; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| ... | @@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { | ... | @@ -300,7 +300,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 300 | break :blk 0; | 300 | break :blk 0; |
| 301 | } | 301 | } |
| 302 | if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file); | 302 | if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file); |
| 303 | const shdr = elf_file.shdrs.items[st_shndx]; | 303 | const shdr = elf_file.sections.items(.shdr)[st_shndx]; |
| 304 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) | 304 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) |
| 305 | break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); | 305 | break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); |
| 306 | break :blk symbol.address(.{ .plt = false, .trampoline = false }, elf_file); | 306 | break :blk symbol.address(.{ .plt = false, .trampoline = false }, elf_file); |
src/link/Elf/ZigObject.zig+41-81| ... | @@ -170,25 +170,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -170,25 +170,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 170 | .addralign = 1, | 170 | .addralign = 1, |
| 171 | .offset = std.math.maxInt(u64), | 171 | .offset = std.math.maxInt(u64), |
| 172 | }); | 172 | }); |
| 173 | const shdr = &elf_file.shdrs.items[elf_file.zig_text_section_index.?]; | 173 | const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_text_section_index.?]; |
| 174 | const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_text_section_index.?]; | ||
| 174 | try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index); | 175 | try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index); |
| 175 | if (elf_file.base.isRelocatable()) { | 176 | if (elf_file.base.isRelocatable()) { |
| 176 | const rela_shndx = try elf_file.addRelaShdr( | 177 | _ = try elf_file.addRelaShdr( |
| 177 | try elf_file.insertShString(".rela.text.zig"), | 178 | try elf_file.insertShString(".rela.text.zig"), |
| 178 | elf_file.zig_text_section_index.?, | 179 | elf_file.zig_text_section_index.?, |
| 179 | ); | 180 | ); |
| 180 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{ | ||
| 181 | .shndx = rela_shndx, | ||
| 182 | }); | ||
| 183 | } else { | 181 | } else { |
| 184 | try elf_file.phdr_to_shdr_table.putNoClobber( | 182 | phndx.* = elf_file.phdr_zig_load_re_index.?; |
| 185 | gpa, | ||
| 186 | elf_file.zig_text_section_index.?, | ||
| 187 | elf_file.phdr_zig_load_re_index.?, | ||
| 188 | ); | ||
| 189 | } | 183 | } |
| 190 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{}); | ||
| 191 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{}); | ||
| 192 | } | 184 | } |
| 193 | 185 | ||
| 194 | if (elf_file.zig_data_rel_ro_section_index == null) { | 186 | if (elf_file.zig_data_rel_ro_section_index == null) { |
| ... | @@ -199,25 +191,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -199,25 +191,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 199 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 191 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 200 | .offset = std.math.maxInt(u64), | 192 | .offset = std.math.maxInt(u64), |
| 201 | }); | 193 | }); |
| 202 | const shdr = &elf_file.shdrs.items[elf_file.zig_data_rel_ro_section_index.?]; | 194 | const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_rel_ro_section_index.?]; |
| 195 | const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_rel_ro_section_index.?]; | ||
| 203 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index); | 196 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index); |
| 204 | if (elf_file.base.isRelocatable()) { | 197 | if (elf_file.base.isRelocatable()) { |
| 205 | const rela_shndx = try elf_file.addRelaShdr( | 198 | _ = try elf_file.addRelaShdr( |
| 206 | try elf_file.insertShString(".rela.data.rel.ro.zig"), | 199 | try elf_file.insertShString(".rela.data.rel.ro.zig"), |
| 207 | elf_file.zig_data_rel_ro_section_index.?, | 200 | elf_file.zig_data_rel_ro_section_index.?, |
| 208 | ); | 201 | ); |
| 209 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{ | ||
| 210 | .shndx = rela_shndx, | ||
| 211 | }); | ||
| 212 | } else { | 202 | } else { |
| 213 | try elf_file.phdr_to_shdr_table.putNoClobber( | 203 | phndx.* = elf_file.phdr_zig_load_ro_index.?; |
| 214 | gpa, | ||
| 215 | elf_file.zig_data_rel_ro_section_index.?, | ||
| 216 | elf_file.phdr_zig_load_ro_index.?, | ||
| 217 | ); | ||
| 218 | } | 204 | } |
| 219 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{}); | ||
| 220 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{}); | ||
| 221 | } | 205 | } |
| 222 | 206 | ||
| 223 | if (elf_file.zig_data_section_index == null) { | 207 | if (elf_file.zig_data_section_index == null) { |
| ... | @@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -228,25 +212,17 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 228 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 212 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 229 | .offset = std.math.maxInt(u64), | 213 | .offset = std.math.maxInt(u64), |
| 230 | }); | 214 | }); |
| 231 | const shdr = &elf_file.shdrs.items[elf_file.zig_data_section_index.?]; | 215 | const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_data_section_index.?]; |
| 216 | const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_data_section_index.?]; | ||
| 232 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index); | 217 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index); |
| 233 | if (elf_file.base.isRelocatable()) { | 218 | if (elf_file.base.isRelocatable()) { |
| 234 | const rela_shndx = try elf_file.addRelaShdr( | 219 | _ = try elf_file.addRelaShdr( |
| 235 | try elf_file.insertShString(".rela.data.zig"), | 220 | try elf_file.insertShString(".rela.data.zig"), |
| 236 | elf_file.zig_data_section_index.?, | 221 | elf_file.zig_data_section_index.?, |
| 237 | ); | 222 | ); |
| 238 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{ | ||
| 239 | .shndx = rela_shndx, | ||
| 240 | }); | ||
| 241 | } else { | 223 | } else { |
| 242 | try elf_file.phdr_to_shdr_table.putNoClobber( | 224 | phndx.* = elf_file.phdr_zig_load_rw_index.?; |
| 243 | gpa, | ||
| 244 | elf_file.zig_data_section_index.?, | ||
| 245 | elf_file.phdr_zig_load_rw_index.?, | ||
| 246 | ); | ||
| 247 | } | 225 | } |
| 248 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{}); | ||
| 249 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{}); | ||
| 250 | } | 226 | } |
| 251 | 227 | ||
| 252 | if (elf_file.zig_bss_section_index == null) { | 228 | if (elf_file.zig_bss_section_index == null) { |
| ... | @@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -257,17 +233,16 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 257 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 233 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 258 | .offset = 0, | 234 | .offset = 0, |
| 259 | }); | 235 | }); |
| 260 | const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?]; | 236 | const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_bss_section_index.?]; |
| 261 | if (elf_file.phdr_zig_load_zerofill_index) |phndx| { | 237 | const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_bss_section_index.?]; |
| 262 | const phdr = elf_file.phdrs.items[phndx]; | 238 | if (elf_file.base.isRelocatable()) { |
| 239 | shdr.sh_size = 1024; | ||
| 240 | } else { | ||
| 241 | phndx.* = elf_file.phdr_zig_load_zerofill_index.?; | ||
| 242 | const phdr = elf_file.phdrs.items[phndx.*]; | ||
| 263 | shdr.sh_addr = phdr.p_vaddr; | 243 | shdr.sh_addr = phdr.p_vaddr; |
| 264 | shdr.sh_size = phdr.p_memsz; | 244 | shdr.sh_size = phdr.p_memsz; |
| 265 | try elf_file.phdr_to_shdr_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, phndx); | ||
| 266 | } else { | ||
| 267 | shdr.sh_size = 1024; | ||
| 268 | } | 245 | } |
| 269 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{}); | ||
| 270 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{}); | ||
| 271 | } | 246 | } |
| 272 | 247 | ||
| 273 | switch (comp.config.debug_format) { | 248 | switch (comp.config.debug_format) { |
| ... | @@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 305 | }); | 280 | }); |
| 306 | self.debug_str_section_dirty = true; | 281 | self.debug_str_section_dirty = true; |
| 307 | self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?); | 282 | self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?); |
| 308 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_str_section_index.?, .{}); | ||
| 309 | } | 283 | } |
| 310 | 284 | ||
| 311 | if (elf_file.debug_info_section_index == null) { | 285 | if (elf_file.debug_info_section_index == null) { |
| ... | @@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -316,7 +290,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 316 | }); | 290 | }); |
| 317 | self.debug_info_section_dirty = true; | 291 | self.debug_info_section_dirty = true; |
| 318 | self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?); | 292 | self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?); |
| 319 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_info_section_index.?, .{}); | ||
| 320 | } | 293 | } |
| 321 | 294 | ||
| 322 | if (elf_file.debug_abbrev_section_index == null) { | 295 | if (elf_file.debug_abbrev_section_index == null) { |
| ... | @@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -327,7 +300,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 327 | }); | 300 | }); |
| 328 | self.debug_abbrev_section_dirty = true; | 301 | self.debug_abbrev_section_dirty = true; |
| 329 | self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?); | 302 | self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?); |
| 330 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_abbrev_section_index.?, .{}); | ||
| 331 | } | 303 | } |
| 332 | 304 | ||
| 333 | if (elf_file.debug_aranges_section_index == null) { | 305 | if (elf_file.debug_aranges_section_index == null) { |
| ... | @@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -338,7 +310,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 338 | }); | 310 | }); |
| 339 | self.debug_aranges_section_dirty = true; | 311 | self.debug_aranges_section_dirty = true; |
| 340 | self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?); | 312 | self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?); |
| 341 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_aranges_section_index.?, .{}); | ||
| 342 | } | 313 | } |
| 343 | 314 | ||
| 344 | if (elf_file.debug_line_section_index == null) { | 315 | if (elf_file.debug_line_section_index == null) { |
| ... | @@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -349,7 +320,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 349 | }); | 320 | }); |
| 350 | self.debug_line_section_dirty = true; | 321 | self.debug_line_section_dirty = true; |
| 351 | self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?); | 322 | self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?); |
| 352 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_section_index.?, .{}); | ||
| 353 | } | 323 | } |
| 354 | 324 | ||
| 355 | if (elf_file.debug_line_str_section_index == null) { | 325 | if (elf_file.debug_line_str_section_index == null) { |
| ... | @@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -362,7 +332,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 362 | }); | 332 | }); |
| 363 | self.debug_line_str_section_dirty = true; | 333 | self.debug_line_str_section_dirty = true; |
| 364 | self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?); | 334 | self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?); |
| 365 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_str_section_index.?, .{}); | ||
| 366 | } | 335 | } |
| 367 | 336 | ||
| 368 | if (elf_file.debug_loclists_section_index == null) { | 337 | if (elf_file.debug_loclists_section_index == null) { |
| ... | @@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -373,7 +342,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 373 | }); | 342 | }); |
| 374 | self.debug_loclists_section_dirty = true; | 343 | self.debug_loclists_section_dirty = true; |
| 375 | self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?); | 344 | self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?); |
| 376 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_loclists_section_index.?, .{}); | ||
| 377 | } | 345 | } |
| 378 | 346 | ||
| 379 | if (elf_file.debug_rnglists_section_index == null) { | 347 | if (elf_file.debug_rnglists_section_index == null) { |
| ... | @@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ... | @@ -384,7 +352,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 384 | }); | 352 | }); |
| 385 | self.debug_rnglists_section_dirty = true; | 353 | self.debug_rnglists_section_dirty = true; |
| 386 | self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?); | 354 | self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?); |
| 387 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_rnglists_section_index.?, .{}); | ||
| 388 | } | 355 | } |
| 389 | 356 | ||
| 390 | try dwarf.initMetadata(); | 357 | try dwarf.initMetadata(); |
| ... | @@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi | ... | @@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi |
| 507 | const atom_ptr = self.atom(sym.ref.index).?; | 474 | const atom_ptr = self.atom(sym.ref.index).?; |
| 508 | if (!atom_ptr.alive) continue; | 475 | if (!atom_ptr.alive) continue; |
| 509 | const shndx = sym.outputShndx(elf_file).?; | 476 | const shndx = sym.outputShndx(elf_file).?; |
| 510 | const shdr = elf_file.shdrs.items[shndx]; | 477 | const shdr = elf_file.sections.items(.shdr)[shndx]; |
| 511 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; | 478 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; |
| 512 | esym.st_size = shdr.sh_size; | 479 | esym.st_size = shdr.sh_size; |
| 513 | atom_ptr.size = shdr.sh_size; | 480 | atom_ptr.size = shdr.sh_size; |
| ... | @@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi | ... | @@ -667,13 +634,10 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi |
| 667 | } | 634 | } |
| 668 | 635 | ||
| 669 | if (elf_file.base.isRelocatable() and relocs.items.len > 0) { | 636 | if (elf_file.base.isRelocatable() and relocs.items.len > 0) { |
| 670 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx); | 637 | const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)}); |
| 671 | if (!gop.found_existing) { | 638 | defer gpa.free(rela_sect_name); |
| 672 | const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)}); | 639 | if (elf_file.sectionByName(rela_sect_name) == null) { |
| 673 | defer gpa.free(rela_sect_name); | 640 | _ = try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), shndx); |
| 674 | const rela_sh_name = try elf_file.insertShString(rela_sect_name); | ||
| 675 | const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx); | ||
| 676 | gop.value_ptr.* = .{ .shndx = rela_shndx }; | ||
| 677 | } | 641 | } |
| 678 | } | 642 | } |
| 679 | } | 643 | } |
| ... | @@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym | ... | @@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym |
| 769 | pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr { | 733 | pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr { |
| 770 | const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr; | 734 | const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr; |
| 771 | const shndx = atom_ptr.output_section_index; | 735 | const shndx = atom_ptr.output_section_index; |
| 772 | var shdr = elf_file.shdrs.items[shndx]; | 736 | var shdr = elf_file.sections.items(.shdr)[shndx]; |
| 773 | shdr.sh_addr = 0; | 737 | shdr.sh_addr = 0; |
| 774 | shdr.sh_offset = 0; | 738 | shdr.sh_offset = 0; |
| 775 | shdr.sh_size = atom_ptr.size; | 739 | shdr.sh_size = atom_ptr.size; |
| ... | @@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { |
| 947 | .p32 => @sizeOf(elf.Elf32_Shdr), | 911 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| 948 | .p64 => @sizeOf(elf.Elf64_Shdr), | 912 | .p64 => @sizeOf(elf.Elf64_Shdr), |
| 949 | }; | 913 | }; |
| 950 | var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.shdrs.items.len * shsize; | 914 | var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.sections.items(.shdr).len * shsize; |
| 951 | for (elf_file.shdrs.items) |shdr| { | 915 | for (elf_file.sections.items(.shdr)) |shdr| { |
| 952 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 916 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 953 | end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size); | 917 | end_pos = @max(end_pos, shdr.sh_offset + shdr.sh_size); |
| 954 | } | 918 | } |
| ... | @@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -1001,12 +965,11 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void { |
| 1001 | // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level | 965 | // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level |
| 1002 | if (self.relocs.items[rela_shndx].items.len == 0) continue; | 966 | if (self.relocs.items[rela_shndx].items.len == 0) continue; |
| 1003 | const out_shndx = atom_ptr.output_section_index; | 967 | const out_shndx = atom_ptr.output_section_index; |
| 1004 | const out_shdr = elf_file.shdrs.items[out_shndx]; | 968 | const out_shdr = elf_file.sections.items(.shdr)[out_shndx]; |
| 1005 | if (out_shdr.sh_type == elf.SHT_NOBITS) continue; | 969 | if (out_shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1006 | 970 | const atom_list = &elf_file.sections.items(.atom_list)[out_shndx]; | |
| 1007 | const gpa = elf_file.base.comp.gpa; | 971 | const gpa = elf_file.base.comp.gpa; |
| 1008 | const sec = elf_file.output_rela_sections.getPtr(out_shndx).?; | 972 | try atom_list.append(gpa, .{ .index = atom_index, .file = self.index }); |
| 1009 | try sec.atom_list.append(gpa, .{ .index = atom_index, .file = self.index }); | ||
| 1010 | } | 973 | } |
| 1011 | } | 974 | } |
| 1012 | 975 | ||
| ... | @@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { | ... | @@ -1076,7 +1039,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { |
| 1076 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { | 1039 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { |
| 1077 | const gpa = elf_file.base.comp.gpa; | 1040 | const gpa = elf_file.base.comp.gpa; |
| 1078 | const atom_ptr = self.atom(atom_index).?; | 1041 | const atom_ptr = self.atom(atom_index).?; |
| 1079 | const shdr = &elf_file.shdrs.items[atom_ptr.output_section_index]; | 1042 | const shdr = &elf_file.sections.items(.shdr)[atom_ptr.output_section_index]; |
| 1080 | 1043 | ||
| 1081 | if (shdr.sh_flags & elf.SHF_TLS != 0) { | 1044 | if (shdr.sh_flags & elf.SHF_TLS != 0) { |
| 1082 | const tlv = self.tls_variables.get(atom_index).?; | 1045 | const tlv = self.tls_variables.get(atom_index).?; |
| ... | @@ -1403,7 +1366,7 @@ fn updateNavCode( | ... | @@ -1403,7 +1366,7 @@ fn updateNavCode( |
| 1403 | } | 1366 | } |
| 1404 | } | 1367 | } |
| 1405 | 1368 | ||
| 1406 | const shdr = elf_file.shdrs.items[shdr_index]; | 1369 | const shdr = elf_file.sections.items(.shdr)[shdr_index]; |
| 1407 | if (shdr.sh_type != elf.SHT_NOBITS) { | 1370 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 1408 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1371 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1409 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1372 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| ... | @@ -1458,16 +1421,13 @@ fn updateTlv( | ... | @@ -1458,16 +1421,13 @@ fn updateTlv( |
| 1458 | gop.value_ptr.* = .{ .symbol_index = sym_index }; | 1421 | gop.value_ptr.* = .{ .symbol_index = sym_index }; |
| 1459 | 1422 | ||
| 1460 | // We only store the data for the TLV if it's non-zerofill. | 1423 | // We only store the data for the TLV if it's non-zerofill. |
| 1461 | if (elf_file.shdrs.items[shndx].sh_type != elf.SHT_NOBITS) { | 1424 | if (elf_file.sections.items(.shdr)[shndx].sh_type != elf.SHT_NOBITS) { |
| 1462 | gop.value_ptr.code = try gpa.dupe(u8, code); | 1425 | gop.value_ptr.code = try gpa.dupe(u8, code); |
| 1463 | } | 1426 | } |
| 1464 | } | 1427 | } |
| 1465 | 1428 | ||
| 1466 | { | 1429 | const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index]; |
| 1467 | const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index); | 1430 | try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index }); |
| 1468 | if (!gop.found_existing) gop.value_ptr.* = .{}; | ||
| 1469 | try gop.value_ptr.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index }); | ||
| 1470 | } | ||
| 1471 | } | 1431 | } |
| 1472 | 1432 | ||
| 1473 | pub fn updateFunc( | 1433 | pub fn updateFunc( |
| ... | @@ -1519,7 +1479,7 @@ pub fn updateFunc( | ... | @@ -1519,7 +1479,7 @@ pub fn updateFunc( |
| 1519 | const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code); | 1479 | const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code); |
| 1520 | log.debug("setting shdr({x},{s}) for {}", .{ | 1480 | log.debug("setting shdr({x},{s}) for {}", .{ |
| 1521 | shndx, | 1481 | shndx, |
| 1522 | elf_file.getShString(elf_file.shdrs.items[shndx].sh_name), | 1482 | elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name), |
| 1523 | ip.getNav(func.owner_nav).fqn.fmt(ip), | 1483 | ip.getNav(func.owner_nav).fqn.fmt(ip), |
| 1524 | }); | 1484 | }); |
| 1525 | const old_rva, const old_alignment = blk: { | 1485 | const old_rva, const old_alignment = blk: { |
| ... | @@ -1647,10 +1607,10 @@ pub fn updateNav( | ... | @@ -1647,10 +1607,10 @@ pub fn updateNav( |
| 1647 | const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code); | 1607 | const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code); |
| 1648 | log.debug("setting shdr({x},{s}) for {}", .{ | 1608 | log.debug("setting shdr({x},{s}) for {}", .{ |
| 1649 | shndx, | 1609 | shndx, |
| 1650 | elf_file.getShString(elf_file.shdrs.items[shndx].sh_name), | 1610 | elf_file.getShString(elf_file.sections.items(.shdr)[shndx].sh_name), |
| 1651 | nav.fqn.fmt(ip), | 1611 | nav.fqn.fmt(ip), |
| 1652 | }); | 1612 | }); |
| 1653 | if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0) | 1613 | if (elf_file.sections.items(.shdr)[shndx].sh_flags & elf.SHF_TLS != 0) |
| 1654 | try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code) | 1614 | try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code) |
| 1655 | else | 1615 | else |
| 1656 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); | 1616 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); |
| ... | @@ -1749,7 +1709,7 @@ fn updateLazySymbol( | ... | @@ -1749,7 +1709,7 @@ fn updateLazySymbol( |
| 1749 | local_sym.value = 0; | 1709 | local_sym.value = 0; |
| 1750 | local_esym.st_value = 0; | 1710 | local_esym.st_value = 0; |
| 1751 | 1711 | ||
| 1752 | const shdr = elf_file.shdrs.items[output_section_index]; | 1712 | const shdr = elf_file.sections.items(.shdr)[output_section_index]; |
| 1753 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1713 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1754 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1714 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1755 | } | 1715 | } |
| ... | @@ -1805,7 +1765,7 @@ fn lowerConst( | ... | @@ -1805,7 +1765,7 @@ fn lowerConst( |
| 1805 | // TODO rename and re-audit this method | 1765 | // TODO rename and re-audit this method |
| 1806 | errdefer self.freeNavMetadata(elf_file, sym_index); | 1766 | errdefer self.freeNavMetadata(elf_file, sym_index); |
| 1807 | 1767 | ||
| 1808 | const shdr = elf_file.shdrs.items[output_section_index]; | 1768 | const shdr = elf_file.sections.items(.shdr)[output_section_index]; |
| 1809 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1769 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1810 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1770 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1811 | 1771 | ||
| ... | @@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 { | ... | @@ -1969,7 +1929,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 { |
| 1969 | 1929 | ||
| 1970 | fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { | 1930 | fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { |
| 1971 | const atom_ptr = tr_sym.atom(elf_file).?; | 1931 | const atom_ptr = tr_sym.atom(elf_file).?; |
| 1972 | const shdr = elf_file.shdrs.items[atom_ptr.output_section_index]; | 1932 | const shdr = elf_file.sections.items(.shdr)[atom_ptr.output_section_index]; |
| 1973 | const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1933 | const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1974 | const source_addr = tr_sym.address(.{}, elf_file); | 1934 | const source_addr = tr_sym.address(.{}, elf_file); |
| 1975 | const target_addr = target.address(.{ .trampoline = false }, elf_file); | 1935 | const target_addr = target.address(.{ .trampoline = false }, elf_file); |
src/link/Elf/eh_frame.zig+11-6| ... | @@ -13,7 +13,7 @@ pub const Fde = struct { | ... | @@ -13,7 +13,7 @@ pub const Fde = struct { |
| 13 | 13 | ||
| 14 | pub fn address(fde: Fde, elf_file: *Elf) u64 { | 14 | pub fn address(fde: Fde, elf_file: *Elf) u64 { |
| 15 | const base: u64 = if (elf_file.eh_frame_section_index) |shndx| | 15 | const base: u64 = if (elf_file.eh_frame_section_index) |shndx| |
| 16 | elf_file.shdrs.items[shndx].sh_addr | 16 | elf_file.sections.items(.shdr)[shndx].sh_addr |
| 17 | else | 17 | else |
| 18 | 0; | 18 | 0; |
| 19 | return base + fde.out_offset; | 19 | return base + fde.out_offset; |
| ... | @@ -112,7 +112,7 @@ pub const Cie = struct { | ... | @@ -112,7 +112,7 @@ pub const Cie = struct { |
| 112 | 112 | ||
| 113 | pub fn address(cie: Cie, elf_file: *Elf) u64 { | 113 | pub fn address(cie: Cie, elf_file: *Elf) u64 { |
| 114 | const base: u64 = if (elf_file.eh_frame_section_index) |shndx| | 114 | const base: u64 = if (elf_file.eh_frame_section_index) |shndx| |
| 115 | elf_file.shdrs.items[shndx].sh_addr | 115 | elf_file.sections.items(.shdr)[shndx].sh_addr |
| 116 | else | 116 | else |
| 117 | 0; | 117 | 0; |
| 118 | return base + cie.out_offset; | 118 | return base + cie.out_offset; |
| ... | @@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: | ... | @@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { | 328 | pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 329 | relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr}); | 329 | relocs_log.debug("{x}: .eh_frame", .{ |
| 330 | elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr, | ||
| 331 | }); | ||
| 330 | 332 | ||
| 331 | var has_reloc_errors = false; | 333 | var has_reloc_errors = false; |
| 332 | 334 | ||
| ... | @@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re | ... | @@ -446,7 +448,9 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re |
| 446 | } | 448 | } |
| 447 | 449 | ||
| 448 | pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { | 450 | pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void { |
| 449 | relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr}); | 451 | relocs_log.debug("{x}: .eh_frame", .{ |
| 452 | elf_file.sections.items(.shdr)[elf_file.eh_frame_section_index.?].sh_addr, | ||
| 453 | }); | ||
| 450 | 454 | ||
| 451 | for (elf_file.objects.items) |index| { | 455 | for (elf_file.objects.items) |index| { |
| 452 | const object = elf_file.file(index).?.object; | 456 | const object = elf_file.file(index).?.object; |
| ... | @@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { | ... | @@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 482 | try writer.writeByte(EH_PE.udata4); | 486 | try writer.writeByte(EH_PE.udata4); |
| 483 | try writer.writeByte(EH_PE.datarel | EH_PE.sdata4); | 487 | try writer.writeByte(EH_PE.datarel | EH_PE.sdata4); |
| 484 | 488 | ||
| 485 | const eh_frame_shdr = elf_file.shdrs.items[elf_file.eh_frame_section_index.?]; | 489 | const shdrs = elf_file.sections.items(.shdr); |
| 486 | const eh_frame_hdr_shdr = elf_file.shdrs.items[elf_file.eh_frame_hdr_section_index.?]; | 490 | const eh_frame_shdr = shdrs[elf_file.eh_frame_section_index.?]; |
| 491 | const eh_frame_hdr_shdr = shdrs[elf_file.eh_frame_hdr_section_index.?]; | ||
| 487 | const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8))); | 492 | const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8))); |
| 488 | try writer.writeInt( | 493 | try writer.writeInt( |
| 489 | u32, | 494 | u32, |
src/link/Elf/merge_section.zig+2-4| ... | @@ -29,7 +29,7 @@ pub const MergeSection = struct { | ... | @@ -29,7 +29,7 @@ pub const MergeSection = struct { |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub fn address(msec: MergeSection, elf_file: *Elf) i64 { | 31 | pub fn address(msec: MergeSection, elf_file: *Elf) i64 { |
| 32 | const shdr = elf_file.shdrs.items[msec.output_section_index]; | 32 | const shdr = elf_file.sections.items(.shdr)[msec.output_section_index]; |
| 33 | return @intCast(shdr.sh_addr + msec.value); | 33 | return @intCast(shdr.sh_addr + msec.value); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| ... | @@ -108,13 +108,11 @@ pub const MergeSection = struct { | ... | @@ -108,13 +108,11 @@ pub const MergeSection = struct { |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void { | 110 | pub fn initOutputSection(msec: *MergeSection, elf_file: *Elf) !void { |
| 111 | const shndx = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{ | 111 | msec.output_section_index = elf_file.sectionByName(msec.name(elf_file)) orelse try elf_file.addSection(.{ |
| 112 | .name = msec.name_offset, | 112 | .name = msec.name_offset, |
| 113 | .type = msec.type, | 113 | .type = msec.type, |
| 114 | .flags = msec.flags, | 114 | .flags = msec.flags, |
| 115 | }); | 115 | }); |
| 116 | try elf_file.output_sections.put(elf_file.base.comp.gpa, shndx, .{}); | ||
| 117 | msec.output_section_index = shndx; | ||
| 118 | } | 116 | } |
| 119 | 117 | ||
| 120 | pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index { | 118 | pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index { |
src/link/Elf/relocatable.zig+39-37| ... | @@ -209,7 +209,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const | ... | @@ -209,7 +209,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 209 | for (elf_file.objects.items) |index| { | 209 | for (elf_file.objects.items) |index| { |
| 210 | const object = elf_file.file(index).?.object; | 210 | const object = elf_file.file(index).?.object; |
| 211 | try object.addAtomsToOutputSections(elf_file); | 211 | try object.addAtomsToOutputSections(elf_file); |
| 212 | try object.addAtomsToRelaSections(elf_file); | 212 | object.addAtomsToRelaSections(elf_file); |
| 213 | } | 213 | } |
| 214 | try elf_file.updateMergeSectionSizes(); | 214 | try elf_file.updateMergeSectionSizes(); |
| 215 | try updateSectionSizes(elf_file); | 215 | try updateSectionSizes(elf_file); |
| ... | @@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void { | ... | @@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void { |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | fn updateSectionSizes(elf_file: *Elf) !void { | 349 | fn updateSectionSizes(elf_file: *Elf) !void { |
| 350 | for (elf_file.output_sections.keys(), elf_file.output_sections.values()) |shndx, atom_list| { | 350 | const slice = elf_file.sections.slice(); |
| 351 | const shdr = &elf_file.shdrs.items[shndx]; | 351 | for (slice.items(.shdr), 0..) |*shdr, shndx| { |
| 352 | for (atom_list.items) |ref| { | 352 | if (shdr.sh_type != elf.SHT_RELA) { |
| 353 | const atom_ptr = elf_file.atom(ref) orelse continue; | 353 | const atom_list = slice.items(.atom_list)[shndx]; |
| 354 | if (!atom_ptr.alive) continue; | 354 | for (atom_list.items) |ref| { |
| 355 | const offset = atom_ptr.alignment.forward(shdr.sh_size); | 355 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 356 | const padding = offset - shdr.sh_size; | 356 | if (!atom_ptr.alive) continue; |
| 357 | atom_ptr.value = @intCast(offset); | 357 | const offset = atom_ptr.alignment.forward(shdr.sh_size); |
| 358 | shdr.sh_size += padding + atom_ptr.size; | 358 | const padding = offset - shdr.sh_size; |
| 359 | shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1); | 359 | atom_ptr.value = @intCast(offset); |
| 360 | } | 360 | shdr.sh_size += padding + atom_ptr.size; |
| 361 | } | 361 | shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1); |
| 362 | } | ||
| 363 | } else { | ||
| 364 | const atom_list = slice.items(.atom_list)[shdr.sh_info]; | ||
| 365 | for (atom_list.items) |ref| { | ||
| 366 | const atom_ptr = elf_file.atom(ref) orelse continue; | ||
| 367 | if (!atom_ptr.alive) continue; | ||
| 368 | const relocs = atom_ptr.relocs(elf_file); | ||
| 369 | shdr.sh_size += shdr.sh_entsize * relocs.len; | ||
| 370 | } | ||
| 362 | 371 | ||
| 363 | for (elf_file.output_rela_sections.values()) |sec| { | 372 | if (shdr.sh_size == 0) shdr.sh_offset = 0; |
| 364 | const shdr = &elf_file.shdrs.items[sec.shndx]; | ||
| 365 | for (sec.atom_list.items) |ref| { | ||
| 366 | const atom_ptr = elf_file.atom(ref) orelse continue; | ||
| 367 | if (!atom_ptr.alive) continue; | ||
| 368 | const relocs = atom_ptr.relocs(elf_file); | ||
| 369 | shdr.sh_size += shdr.sh_entsize * relocs.len; | ||
| 370 | } | 373 | } |
| 371 | |||
| 372 | if (shdr.sh_size == 0) shdr.sh_offset = 0; | ||
| 373 | } | 374 | } |
| 374 | 375 | ||
| 375 | if (elf_file.eh_frame_section_index) |index| { | 376 | if (elf_file.eh_frame_section_index) |index| { |
| 376 | elf_file.shdrs.items[index].sh_size = try eh_frame.calcEhFrameSize(elf_file); | 377 | slice.items(.shdr)[index].sh_size = try eh_frame.calcEhFrameSize(elf_file); |
| 377 | } | 378 | } |
| 378 | if (elf_file.eh_frame_rela_section_index) |index| { | 379 | if (elf_file.eh_frame_rela_section_index) |index| { |
| 379 | const shdr = &elf_file.shdrs.items[index]; | 380 | const shdr = &slice.items(.shdr)[index]; |
| 380 | shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize; | 381 | shdr.sh_size = eh_frame.calcEhFrameRelocs(elf_file) * shdr.sh_entsize; |
| 381 | } | 382 | } |
| 382 | 383 | ||
| ... | @@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void { | ... | @@ -387,7 +388,7 @@ fn updateSectionSizes(elf_file: *Elf) !void { |
| 387 | 388 | ||
| 388 | fn updateComdatGroupsSizes(elf_file: *Elf) void { | 389 | fn updateComdatGroupsSizes(elf_file: *Elf) void { |
| 389 | for (elf_file.comdat_group_sections.items) |cg| { | 390 | for (elf_file.comdat_group_sections.items) |cg| { |
| 390 | const shdr = &elf_file.shdrs.items[cg.shndx]; | 391 | const shdr = &elf_file.sections.items(.shdr)[cg.shndx]; |
| 391 | shdr.sh_size = cg.size(elf_file); | 392 | shdr.sh_size = cg.size(elf_file); |
| 392 | shdr.sh_link = elf_file.symtab_section_index.?; | 393 | shdr.sh_link = elf_file.symtab_section_index.?; |
| 393 | 394 | ||
| ... | @@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void { | ... | @@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void { |
| 399 | 400 | ||
| 400 | /// Allocates alloc sections when merging relocatable objects files together. | 401 | /// Allocates alloc sections when merging relocatable objects files together. |
| 401 | fn allocateAllocSections(elf_file: *Elf) !void { | 402 | fn allocateAllocSections(elf_file: *Elf) !void { |
| 402 | for (elf_file.shdrs.items) |*shdr| { | 403 | for (elf_file.sections.items(.shdr)) |*shdr| { |
| 403 | if (shdr.sh_type == elf.SHT_NULL) continue; | 404 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 404 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 405 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 405 | if (shdr.sh_type == elf.SHT_NOBITS) { | 406 | if (shdr.sh_type == elf.SHT_NOBITS) { |
| ... | @@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void { | ... | @@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void { |
| 418 | 419 | ||
| 419 | fn writeAtoms(elf_file: *Elf) !void { | 420 | fn writeAtoms(elf_file: *Elf) !void { |
| 420 | const gpa = elf_file.base.comp.gpa; | 421 | const gpa = elf_file.base.comp.gpa; |
| 422 | const slice = elf_file.sections.slice(); | ||
| 421 | 423 | ||
| 422 | // TODO iterate over `output_sections` directly | 424 | // TODO iterate over `output_sections` directly |
| 423 | for (elf_file.shdrs.items, 0..) |shdr, shndx| { | 425 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { |
| 424 | if (shdr.sh_type == elf.SHT_NULL) continue; | 426 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 425 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 427 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 426 | 428 | if (shdr.sh_type == elf.SHT_RELA) continue; | |
| 427 | const atom_list = elf_file.output_sections.get(@intCast(shndx)) orelse continue; | ||
| 428 | if (atom_list.items.len == 0) continue; | 429 | if (atom_list.items.len == 0) continue; |
| 429 | 430 | ||
| 430 | log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)}); | 431 | log.debug("writing atoms in '{s}' section", .{elf_file.getShString(shdr.sh_name)}); |
| ... | @@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void { | ... | @@ -490,18 +491,19 @@ fn writeAtoms(elf_file: *Elf) !void { |
| 490 | 491 | ||
| 491 | fn writeSyntheticSections(elf_file: *Elf) !void { | 492 | fn writeSyntheticSections(elf_file: *Elf) !void { |
| 492 | const gpa = elf_file.base.comp.gpa; | 493 | const gpa = elf_file.base.comp.gpa; |
| 494 | const slice = elf_file.sections.slice(); | ||
| 493 | 495 | ||
| 494 | for (elf_file.output_rela_sections.values()) |sec| { | 496 | for (slice.items(.shdr)) |shdr| { |
| 495 | if (sec.atom_list.items.len == 0) continue; | 497 | if (shdr.sh_type != elf.SHT_RELA) continue; |
| 496 | 498 | const atom_list = slice.items(.atom_list)[shdr.sh_info]; | |
| 497 | const shdr = elf_file.shdrs.items[sec.shndx]; | 499 | if (atom_list.items.len == 0) continue; |
| 498 | 500 | ||
| 499 | const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse | 501 | const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse |
| 500 | return error.Overflow; | 502 | return error.Overflow; |
| 501 | var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs); | 503 | var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs); |
| 502 | defer relocs.deinit(); | 504 | defer relocs.deinit(); |
| 503 | 505 | ||
| 504 | for (sec.atom_list.items) |ref| { | 506 | for (atom_list.items) |ref| { |
| 505 | const atom_ptr = elf_file.atom(ref) orelse continue; | 507 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 506 | if (!atom_ptr.alive) continue; | 508 | if (!atom_ptr.alive) continue; |
| 507 | try atom_ptr.writeRelocs(elf_file, &relocs); | 509 | try atom_ptr.writeRelocs(elf_file, &relocs); |
| ... | @@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { | ... | @@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 527 | } | 529 | } |
| 528 | 530 | ||
| 529 | if (elf_file.eh_frame_section_index) |shndx| { | 531 | if (elf_file.eh_frame_section_index) |shndx| { |
| 530 | const shdr = elf_file.shdrs.items[shndx]; | 532 | const shdr = slice.items(.shdr)[shndx]; |
| 531 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 533 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 532 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 534 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 533 | defer buffer.deinit(); | 535 | defer buffer.deinit(); |
| ... | @@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { | ... | @@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 540 | try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 542 | try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 541 | } | 543 | } |
| 542 | if (elf_file.eh_frame_rela_section_index) |shndx| { | 544 | if (elf_file.eh_frame_rela_section_index) |shndx| { |
| 543 | const shdr = elf_file.shdrs.items[shndx]; | 545 | const shdr = slice.items(.shdr)[shndx]; |
| 544 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 546 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 545 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 547 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 546 | defer buffer.deinit(); | 548 | defer buffer.deinit(); |
| ... | @@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { | ... | @@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 561 | fn writeComdatGroups(elf_file: *Elf) !void { | 563 | fn writeComdatGroups(elf_file: *Elf) !void { |
| 562 | const gpa = elf_file.base.comp.gpa; | 564 | const gpa = elf_file.base.comp.gpa; |
| 563 | for (elf_file.comdat_group_sections.items) |cgs| { | 565 | for (elf_file.comdat_group_sections.items) |cgs| { |
| 564 | const shdr = elf_file.shdrs.items[cgs.shndx]; | 566 | const shdr = elf_file.sections.items(.shdr)[cgs.shndx]; |
| 565 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 567 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 566 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 568 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 567 | defer buffer.deinit(); | 569 | defer buffer.deinit(); |
src/link/Elf/synthetic_sections.zig+30-22| ... | @@ -95,6 +95,8 @@ pub const DynamicSection = struct { | ... | @@ -95,6 +95,8 @@ pub const DynamicSection = struct { |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void { | 97 | pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void { |
| 98 | const shdrs = elf_file.sections.items(.shdr); | ||
| 99 | |||
| 98 | // NEEDED | 100 | // NEEDED |
| 99 | for (dt.needed.items) |off| { | 101 | for (dt.needed.items) |off| { |
| 100 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off }); | 102 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off }); |
| ... | @@ -112,33 +114,33 @@ pub const DynamicSection = struct { | ... | @@ -112,33 +114,33 @@ pub const DynamicSection = struct { |
| 112 | 114 | ||
| 113 | // INIT | 115 | // INIT |
| 114 | if (elf_file.sectionByName(".init")) |shndx| { | 116 | if (elf_file.sectionByName(".init")) |shndx| { |
| 115 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 117 | const addr = shdrs[shndx].sh_addr; |
| 116 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr }); | 118 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr }); |
| 117 | } | 119 | } |
| 118 | 120 | ||
| 119 | // FINI | 121 | // FINI |
| 120 | if (elf_file.sectionByName(".fini")) |shndx| { | 122 | if (elf_file.sectionByName(".fini")) |shndx| { |
| 121 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 123 | const addr = shdrs[shndx].sh_addr; |
| 122 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr }); | 124 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr }); |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | // INIT_ARRAY | 127 | // INIT_ARRAY |
| 126 | if (elf_file.sectionByName(".init_array")) |shndx| { | 128 | if (elf_file.sectionByName(".init_array")) |shndx| { |
| 127 | const shdr = elf_file.shdrs.items[shndx]; | 129 | const shdr = shdrs[shndx]; |
| 128 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr }); | 130 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr }); |
| 129 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size }); | 131 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size }); |
| 130 | } | 132 | } |
| 131 | 133 | ||
| 132 | // FINI_ARRAY | 134 | // FINI_ARRAY |
| 133 | if (elf_file.sectionByName(".fini_array")) |shndx| { | 135 | if (elf_file.sectionByName(".fini_array")) |shndx| { |
| 134 | const shdr = elf_file.shdrs.items[shndx]; | 136 | const shdr = shdrs[shndx]; |
| 135 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr }); | 137 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr }); |
| 136 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size }); | 138 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size }); |
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | // RELA | 141 | // RELA |
| 140 | if (elf_file.rela_dyn_section_index) |shndx| { | 142 | if (elf_file.rela_dyn_section_index) |shndx| { |
| 141 | const shdr = elf_file.shdrs.items[shndx]; | 143 | const shdr = shdrs[shndx]; |
| 142 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr }); | 144 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr }); |
| 143 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size }); | 145 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size }); |
| 144 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize }); | 146 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELAENT, .d_val = shdr.sh_entsize }); |
| ... | @@ -146,7 +148,7 @@ pub const DynamicSection = struct { | ... | @@ -146,7 +148,7 @@ pub const DynamicSection = struct { |
| 146 | 148 | ||
| 147 | // JMPREL | 149 | // JMPREL |
| 148 | if (elf_file.rela_plt_section_index) |shndx| { | 150 | if (elf_file.rela_plt_section_index) |shndx| { |
| 149 | const shdr = elf_file.shdrs.items[shndx]; | 151 | const shdr = shdrs[shndx]; |
| 150 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr }); | 152 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr }); |
| 151 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size }); | 153 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size }); |
| 152 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA }); | 154 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTREL, .d_val = elf.DT_RELA }); |
| ... | @@ -154,18 +156,18 @@ pub const DynamicSection = struct { | ... | @@ -154,18 +156,18 @@ pub const DynamicSection = struct { |
| 154 | 156 | ||
| 155 | // PLTGOT | 157 | // PLTGOT |
| 156 | if (elf_file.got_plt_section_index) |shndx| { | 158 | if (elf_file.got_plt_section_index) |shndx| { |
| 157 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 159 | const addr = shdrs[shndx].sh_addr; |
| 158 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr }); | 160 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr }); |
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | { | 163 | { |
| 162 | assert(elf_file.hash_section_index != null); | 164 | assert(elf_file.hash_section_index != null); |
| 163 | const addr = elf_file.shdrs.items[elf_file.hash_section_index.?].sh_addr; | 165 | const addr = shdrs[elf_file.hash_section_index.?].sh_addr; |
| 164 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr }); | 166 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr }); |
| 165 | } | 167 | } |
| 166 | 168 | ||
| 167 | if (elf_file.gnu_hash_section_index) |shndx| { | 169 | if (elf_file.gnu_hash_section_index) |shndx| { |
| 168 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 170 | const addr = shdrs[shndx].sh_addr; |
| 169 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr }); | 171 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr }); |
| 170 | } | 172 | } |
| 171 | 173 | ||
| ... | @@ -177,7 +179,7 @@ pub const DynamicSection = struct { | ... | @@ -177,7 +179,7 @@ pub const DynamicSection = struct { |
| 177 | // SYMTAB + SYMENT | 179 | // SYMTAB + SYMENT |
| 178 | { | 180 | { |
| 179 | assert(elf_file.dynsymtab_section_index != null); | 181 | assert(elf_file.dynsymtab_section_index != null); |
| 180 | const shdr = elf_file.shdrs.items[elf_file.dynsymtab_section_index.?]; | 182 | const shdr = shdrs[elf_file.dynsymtab_section_index.?]; |
| 181 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr }); | 183 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr }); |
| 182 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize }); | 184 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMENT, .d_val = shdr.sh_entsize }); |
| 183 | } | 185 | } |
| ... | @@ -185,20 +187,20 @@ pub const DynamicSection = struct { | ... | @@ -185,20 +187,20 @@ pub const DynamicSection = struct { |
| 185 | // STRTAB + STRSZ | 187 | // STRTAB + STRSZ |
| 186 | { | 188 | { |
| 187 | assert(elf_file.dynstrtab_section_index != null); | 189 | assert(elf_file.dynstrtab_section_index != null); |
| 188 | const shdr = elf_file.shdrs.items[elf_file.dynstrtab_section_index.?]; | 190 | const shdr = shdrs[elf_file.dynstrtab_section_index.?]; |
| 189 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr }); | 191 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr }); |
| 190 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size }); | 192 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size }); |
| 191 | } | 193 | } |
| 192 | 194 | ||
| 193 | // VERSYM | 195 | // VERSYM |
| 194 | if (elf_file.versym_section_index) |shndx| { | 196 | if (elf_file.versym_section_index) |shndx| { |
| 195 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 197 | const addr = shdrs[shndx].sh_addr; |
| 196 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr }); | 198 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr }); |
| 197 | } | 199 | } |
| 198 | 200 | ||
| 199 | // VERNEED + VERNEEDNUM | 201 | // VERNEED + VERNEEDNUM |
| 200 | if (elf_file.verneed_section_index) |shndx| { | 202 | if (elf_file.verneed_section_index) |shndx| { |
| 201 | const addr = elf_file.shdrs.items[shndx].sh_addr; | 203 | const addr = shdrs[shndx].sh_addr; |
| 202 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr }); | 204 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr }); |
| 203 | try writer.writeStruct(elf.Elf64_Dyn{ | 205 | try writer.writeStruct(elf.Elf64_Dyn{ |
| 204 | .d_tag = elf.DT_VERNEEDNUM, | 206 | .d_tag = elf.DT_VERNEEDNUM, |
| ... | @@ -259,7 +261,7 @@ pub const GotSection = struct { | ... | @@ -259,7 +261,7 @@ pub const GotSection = struct { |
| 259 | 261 | ||
| 260 | pub fn address(entry: Entry, elf_file: *Elf) i64 { | 262 | pub fn address(entry: Entry, elf_file: *Elf) i64 { |
| 261 | const ptr_bytes = elf_file.archPtrWidthBytes(); | 263 | const ptr_bytes = elf_file.archPtrWidthBytes(); |
| 262 | const shdr = &elf_file.shdrs.items[elf_file.got_section_index.?]; | 264 | const shdr = &elf_file.sections.items(.shdr)[elf_file.got_section_index.?]; |
| 263 | return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes; | 265 | return @as(i64, @intCast(shdr.sh_addr)) + entry.cell_index * ptr_bytes; |
| 264 | } | 266 | } |
| 265 | }; | 267 | }; |
| ... | @@ -759,8 +761,9 @@ pub const PltSection = struct { | ... | @@ -759,8 +761,9 @@ pub const PltSection = struct { |
| 759 | 761 | ||
| 760 | const x86_64 = struct { | 762 | const x86_64 = struct { |
| 761 | fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void { | 763 | fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void { |
| 762 | const plt_addr = elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr; | 764 | const shdrs = elf_file.sections.items(.shdr); |
| 763 | const got_plt_addr = elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr; | 765 | const plt_addr = shdrs[elf_file.plt_section_index.?].sh_addr; |
| 766 | const got_plt_addr = shdrs[elf_file.got_plt_section_index.?].sh_addr; | ||
| 764 | var preamble = [_]u8{ | 767 | var preamble = [_]u8{ |
| 765 | 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 | 768 | 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 |
| 766 | 0x41, 0x53, // push r11 | 769 | 0x41, 0x53, // push r11 |
| ... | @@ -794,8 +797,9 @@ pub const PltSection = struct { | ... | @@ -794,8 +797,9 @@ pub const PltSection = struct { |
| 794 | const aarch64 = struct { | 797 | const aarch64 = struct { |
| 795 | fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void { | 798 | fn write(plt: PltSection, elf_file: *Elf, writer: anytype) !void { |
| 796 | { | 799 | { |
| 797 | const plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.plt_section_index.?].sh_addr); | 800 | const shdrs = elf_file.sections.items(.shdr); |
| 798 | const got_plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr); | 801 | const plt_addr: i64 = @intCast(shdrs[elf_file.plt_section_index.?].sh_addr); |
| 802 | const got_plt_addr: i64 = @intCast(shdrs[elf_file.got_plt_section_index.?].sh_addr); | ||
| 799 | // TODO: relax if possible | 803 | // TODO: relax if possible |
| 800 | // .got.plt[2] | 804 | // .got.plt[2] |
| 801 | const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16); | 805 | const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16); |
| ... | @@ -869,7 +873,7 @@ pub const GotPltSection = struct { | ... | @@ -869,7 +873,7 @@ pub const GotPltSection = struct { |
| 869 | try writer.writeInt(u64, 0x0, .little); | 873 | try writer.writeInt(u64, 0x0, .little); |
| 870 | try writer.writeInt(u64, 0x0, .little); | 874 | try writer.writeInt(u64, 0x0, .little); |
| 871 | if (elf_file.plt_section_index) |shndx| { | 875 | if (elf_file.plt_section_index) |shndx| { |
| 872 | const plt_addr = elf_file.shdrs.items[shndx].sh_addr; | 876 | const plt_addr = elf_file.sections.items(.shdr)[shndx].sh_addr; |
| 873 | for (0..elf_file.plt.symbols.items.len) |_| { | 877 | for (0..elf_file.plt.symbols.items.len) |_| { |
| 874 | // [N]: .plt | 878 | // [N]: .plt |
| 875 | try writer.writeInt(u64, plt_addr, .little); | 879 | try writer.writeInt(u64, plt_addr, .little); |
| ... | @@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct { | ... | @@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct { |
| 1027 | } | 1031 | } |
| 1028 | 1032 | ||
| 1029 | pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void { | 1033 | pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void { |
| 1030 | const shdr = &elf_file.shdrs.items[shndx]; | 1034 | const shdr = &elf_file.sections.items(.shdr)[shndx]; |
| 1031 | for (copy_rel.symbols.items) |ref| { | 1035 | for (copy_rel.symbols.items) |ref| { |
| 1032 | const symbol = elf_file.symbol(ref).?; | 1036 | const symbol = elf_file.symbol(ref).?; |
| 1033 | const shared_object = symbol.file(elf_file).?.shared_object; | 1037 | const shared_object = symbol.file(elf_file).?.shared_object; |
| ... | @@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct { | ... | @@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct { |
| 1487 | elf.SHT_RELA => { | 1491 | elf.SHT_RELA => { |
| 1488 | const atom_index = object.atoms_indexes.items[shdr.sh_info]; | 1492 | const atom_index = object.atoms_indexes.items[shdr.sh_info]; |
| 1489 | const atom = object.atom(atom_index).?; | 1493 | const atom = object.atom(atom_index).?; |
| 1490 | const rela = elf_file.output_rela_sections.get(atom.output_section_index).?; | 1494 | const rela_shndx = for (elf_file.sections.items(.shdr), 0..) |rela_shdr, rela_shndx| { |
| 1491 | try writer.writeInt(u32, rela.shndx, .little); | 1495 | if (rela_shdr.sh_type == elf.SHT_RELA and |
| 1496 | atom.output_section_index == rela_shdr.sh_info) | ||
| 1497 | break rela_shndx; | ||
| 1498 | } else unreachable; | ||
| 1499 | try writer.writeInt(u32, @intCast(rela_shndx), .little); | ||
| 1492 | }, | 1500 | }, |
| 1493 | else => { | 1501 | else => { |
| 1494 | const atom_index = object.atoms_indexes.items[shndx]; | 1502 | const atom_index = object.atoms_indexes.items[shndx]; |
src/link/Elf/thunks.zig+3-4| ... | @@ -1,9 +1,8 @@ | ... | @@ -1,9 +1,8 @@ |
| 1 | pub fn createThunks(shndx: u32, elf_file: *Elf) !void { | 1 | pub fn createThunks(shdr: *elf.Elf64_Shdr, shndx: u32, elf_file: *Elf) !void { |
| 2 | const gpa = elf_file.base.comp.gpa; | 2 | const gpa = elf_file.base.comp.gpa; |
| 3 | const cpu_arch = elf_file.getTarget().cpu.arch; | 3 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 4 | const max_distance = maxAllowedDistance(cpu_arch); | 4 | const max_distance = maxAllowedDistance(cpu_arch); |
| 5 | const shdr = &elf_file.shdrs.items[shndx]; | 5 | const atoms = elf_file.sections.items(.atom_list)[shndx].items; |
| 6 | const atoms = elf_file.output_sections.get(shndx).?.items; | ||
| 7 | assert(atoms.len > 0); | 6 | assert(atoms.len > 0); |
| 8 | 7 | ||
| 9 | for (atoms) |ref| { | 8 | for (atoms) |ref| { |
| ... | @@ -89,7 +88,7 @@ pub const Thunk = struct { | ... | @@ -89,7 +88,7 @@ pub const Thunk = struct { |
| 89 | } | 88 | } |
| 90 | 89 | ||
| 91 | pub fn address(thunk: Thunk, elf_file: *Elf) i64 { | 90 | pub fn address(thunk: Thunk, elf_file: *Elf) i64 { |
| 92 | const shdr = elf_file.shdrs.items[thunk.output_section_index]; | 91 | const shdr = elf_file.sections.items(.shdr)[thunk.output_section_index]; |
| 93 | return @as(i64, @intCast(shdr.sh_addr)) + thunk.value; | 92 | return @as(i64, @intCast(shdr.sh_addr)) + thunk.value; |
| 94 | } | 93 | } |
| 95 | 94 |