| 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 | 317 | fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void { |
| 318 | 318 | if (dwarf.bin_file.cast(.elf)) |elf_file| { |
| 319 | 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 | 321 | sec.off = shdr.sh_offset; |
| 322 | 322 | sec.len = shdr.sh_size; |
| 323 | 323 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { |
| ... | ... | @@ -340,7 +340,7 @@ pub const Section = struct { |
| 340 | 340 | sec.off += len; |
| 341 | 341 | sec.len -= len; |
| 342 | 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 | 344 | shdr.sh_offset = sec.off; |
| 345 | 345 | shdr.sh_size = sec.len; |
| 346 | 346 | } else if (dwarf.bin_file.cast(.macho)) |macho_file| { |
| ... | ... | @@ -771,7 +771,7 @@ const Entry = struct { |
| 771 | 771 | log.err("missing {} from {s}", .{ |
| 772 | 772 | @as(Entry.Index, @enumFromInt(entry - unit.entries.items.ptr)), |
| 773 | 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 | 775 | else if (dwarf.bin_file.cast(.macho)) |macho_file| |
| 776 | 776 | if (macho_file.d_sym) |*d_sym| |
| 777 | 777 | &d_sym.sections.items[sec.index].segname |
| ... | ... | @@ -1529,7 +1529,7 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { |
| 1529 | 1529 | elf_file.debug_rnglists_section_index.?, |
| 1530 | 1530 | elf_file.debug_str_section_index.?, |
| 1531 | 1531 | }) |sec, section_index| { |
| 1532 | const shdr = &elf_file.shdrs.items[section_index]; | |
| 1532 | const shdr = &elf_file.sections.items(.shdr)[section_index]; | |
| 1533 | 1533 | sec.index = section_index; |
| 1534 | 1534 | sec.off = shdr.sh_offset; |
| 1535 | 1535 | sec.len = shdr.sh_size; |
src/link/Elf.zig+168-256| ... | ... | @@ -45,17 +45,10 @@ linker_defined_index: ?File.Index = null, |
| 45 | 45 | objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| 46 | 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. | |
| 49 | /// Same order as in the file. | |
| 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) = .{}, | |
| 48 | /// List of all output sections and their associated metadata. | |
| 49 | sections: std.MultiArrayList(Section) = .{}, | |
| 53 | 50 | /// File offset into the shdr table. |
| 54 | 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 | 53 | /// Stored in native-endian format, depending on target endianness needs to be bswapped on read/write. |
| 61 | 54 | /// Same order as in the file. |
| ... | ... | @@ -181,9 +174,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{}, |
| 181 | 174 | /// List of output merge sections with deduped contents. |
| 182 | 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 | 177 | first_eflags: ?elf.Elf64_Word = null, |
| 188 | 178 | |
| 189 | 179 | /// When allocating, the ideal_capacity is calculated by |
| ... | ... | @@ -429,17 +419,12 @@ pub fn deinit(self: *Elf) void { |
| 429 | 419 | self.objects.deinit(gpa); |
| 430 | 420 | self.shared_objects.deinit(gpa); |
| 431 | 421 | |
| 432 | self.shdrs.deinit(gpa); | |
| 433 | self.phdr_to_shdr_table.deinit(gpa); | |
| 434 | self.phdrs.deinit(gpa); | |
| 435 | for (self.output_sections.values()) |*list| { | |
| 436 | list.deinit(gpa); | |
| 422 | for (self.sections.items(.atom_list), self.sections.items(.free_list)) |*atoms, *free_list| { | |
| 423 | atoms.deinit(gpa); | |
| 424 | free_list.deinit(gpa); | |
| 437 | 425 | } |
| 438 | self.output_sections.deinit(gpa); | |
| 439 | for (self.output_rela_sections.values()) |*sec| { | |
| 440 | sec.atom_list.deinit(gpa); | |
| 441 | } | |
| 442 | self.output_rela_sections.deinit(gpa); | |
| 426 | self.sections.deinit(gpa); | |
| 427 | self.phdrs.deinit(gpa); | |
| 443 | 428 | self.shstrtab.deinit(gpa); |
| 444 | 429 | self.symtab.deinit(gpa); |
| 445 | 430 | self.strtab.deinit(gpa); |
| ... | ... | @@ -453,10 +438,6 @@ pub fn deinit(self: *Elf) void { |
| 453 | 438 | sect.deinit(gpa); |
| 454 | 439 | } |
| 455 | 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 | 442 | self.got.deinit(gpa); |
| 462 | 443 | self.plt.deinit(gpa); |
| ... | ... | @@ -505,7 +486,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 { |
| 505 | 486 | |
| 506 | 487 | if (self.shdr_table_offset) |off| { |
| 507 | 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 | 490 | const increased_size = padToIdeal(tight_size); |
| 510 | 491 | const test_end = off +| increased_size; |
| 511 | 492 | if (start < test_end) { |
| ... | ... | @@ -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 | 499 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 519 | 500 | const increased_size = padToIdeal(shdr.sh_size); |
| 520 | 501 | const test_end = shdr.sh_offset +| increased_size; |
| ... | ... | @@ -544,7 +525,7 @@ pub fn allocatedSize(self: *Elf, start: u64) u64 { |
| 544 | 525 | if (self.shdr_table_offset) |off| { |
| 545 | 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 | 529 | if (section.sh_offset <= start) continue; |
| 549 | 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 | 555 | } |
| 575 | 556 | |
| 576 | 557 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 577 | const shdr = &self.shdrs.items[shdr_index]; | |
| 578 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; | |
| 558 | const slice = self.sections.slice(); | |
| 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 | 564 | log.debug("allocated size {x} of {s}, needed size {x}", .{ |
| 580 | 565 | self.allocatedSize(shdr.sh_offset), |
| 581 | 566 | self.getShString(shdr.sh_name), |
| ... | ... | @@ -590,7 +575,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 590 | 575 | const existing_size = shdr.sh_size; |
| 591 | 576 | shdr.sh_size = 0; |
| 592 | 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 | 579 | const new_offset = try self.findFreeSpace(needed_size, alignment); |
| 595 | 580 | |
| 596 | 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 | 589 | if (amt != existing_size) return error.InputOutput; |
| 605 | 590 | |
| 606 | 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 | 596 | shdr.sh_size = needed_size; |
| 612 | 597 | |
| 613 | if (maybe_phdr) |phdr| { | |
| 598 | if (phdr.p_type != elf.PT_NULL) { | |
| 614 | 599 | const mem_capacity = self.allocatedVirtualSize(phdr.p_vaddr); |
| 615 | 600 | if (needed_size > mem_capacity) { |
| 616 | 601 | var err = try self.base.addErrorWithNotes(2); |
| 617 | try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{ | |
| 618 | self.phdr_to_shdr_table.get(shdr_index).?, | |
| 619 | }); | |
| 602 | try err.addMsg("fatal linker error: cannot expand load segment phdr({d}) in virtual memory", .{phndx}); | |
| 620 | 603 | try err.addNote("TODO: emit relocations to memory locations in self-hosted backends", .{}); |
| 621 | 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 | 617 | min_alignment: u32, |
| 635 | 618 | requires_file_copy: bool, |
| 636 | 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 | 623 | const allocated_size = self.allocatedSize(shdr.sh_offset); |
| 640 | 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 | 1002 | const atom_ptr = zo.atom(atom_index) orelse continue; |
| 1019 | 1003 | if (!atom_ptr.alive) continue; |
| 1020 | 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 | 1006 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1023 | 1007 | const code = try zo.codeAlloc(self, atom_index); |
| 1024 | 1008 | defer gpa.free(code); |
| ... | ... | @@ -2382,7 +2366,7 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2382 | 2366 | }; |
| 2383 | 2367 | |
| 2384 | 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 | 2371 | if (needed_size > self.allocatedSize(shoff)) { |
| 2388 | 2372 | self.shdr_table_offset = null; |
| ... | ... | @@ -2396,12 +2380,12 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2396 | 2380 | |
| 2397 | 2381 | switch (self.ptr_width) { |
| 2398 | 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 | 2384 | defer gpa.free(buf); |
| 2401 | 2385 | |
| 2402 | 2386 | for (buf, 0..) |*shdr, i| { |
| 2403 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); | |
| 2404 | shdr.* = shdrTo32(self.shdrs.items[i]); | |
| 2387 | assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64)); | |
| 2388 | shdr.* = shdrTo32(self.sections.items(.shdr)[i]); | |
| 2405 | 2389 | if (foreign_endian) { |
| 2406 | 2390 | mem.byteSwapAllFields(elf.Elf32_Shdr, shdr); |
| 2407 | 2391 | } |
| ... | ... | @@ -2409,12 +2393,12 @@ pub fn writeShdrTable(self: *Elf) !void { |
| 2409 | 2393 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); |
| 2410 | 2394 | }, |
| 2411 | 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 | 2397 | defer gpa.free(buf); |
| 2414 | 2398 | |
| 2415 | 2399 | for (buf, 0..) |*shdr, i| { |
| 2416 | assert(self.shdrs.items[i].sh_offset != math.maxInt(u64)); | |
| 2417 | shdr.* = self.shdrs.items[i]; | |
| 2400 | assert(self.sections.items(.shdr)[i].sh_offset != math.maxInt(u64)); | |
| 2401 | shdr.* = self.sections.items(.shdr)[i]; | |
| 2418 | 2402 | if (foreign_endian) { |
| 2419 | 2403 | mem.byteSwapAllFields(elf.Elf64_Shdr, shdr); |
| 2420 | 2404 | } |
| ... | ... | @@ -2582,7 +2566,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2582 | 2566 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shentsize, endian); |
| 2583 | 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 | 2570 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); |
| 2587 | 2571 | index += 2; |
| 2588 | 2572 | |
| ... | ... | @@ -2741,7 +2725,7 @@ pub fn updateMergeSectionSizes(self: *Elf) !void { |
| 2741 | 2725 | msec.updateSize(); |
| 2742 | 2726 | } |
| 2743 | 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 | 2729 | const offset = msec.alignment.forward(shdr.sh_size); |
| 2746 | 2730 | const padding = offset - shdr.sh_size; |
| 2747 | 2731 | msec.value = @intCast(offset); |
| ... | ... | @@ -2757,7 +2741,7 @@ pub fn writeMergeSections(self: *Elf) !void { |
| 2757 | 2741 | defer buffer.deinit(); |
| 2758 | 2742 | |
| 2759 | 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 | 2745 | const fileoff = math.cast(usize, msec.value + shdr.sh_offset) orelse return error.Overflow; |
| 2762 | 2746 | const size = math.cast(usize, msec.size) orelse return error.Overflow; |
| 2763 | 2747 | try buffer.ensureTotalCapacity(size); |
| ... | ... | @@ -3045,7 +3029,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3045 | 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 | 3033 | if (shdr.sh_flags & elf.SHF_TLS != 0) break true; |
| 3050 | 3034 | } else false; |
| 3051 | 3035 | if (has_tls) { |
| ... | ... | @@ -3074,6 +3058,7 @@ fn initSpecialPhdrs(self: *Elf) !void { |
| 3074 | 3058 | /// we are about to sort. |
| 3075 | 3059 | fn sortInitFini(self: *Elf) !void { |
| 3076 | 3060 | const gpa = self.base.comp.gpa; |
| 3061 | const slice = self.sections.slice(); | |
| 3077 | 3062 | |
| 3078 | 3063 | const Entry = struct { |
| 3079 | 3064 | priority: i32, |
| ... | ... | @@ -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 | 3076 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3092 | 3077 | |
| 3093 | 3078 | var is_init_fini = false; |
| ... | ... | @@ -3104,8 +3089,6 @@ fn sortInitFini(self: *Elf) !void { |
| 3104 | 3089 | } |
| 3105 | 3090 | |
| 3106 | 3091 | if (!is_init_fini and !is_ctor_dtor) continue; |
| 3107 | ||
| 3108 | const atom_list = self.output_sections.getPtr(@intCast(shndx)).?; | |
| 3109 | 3092 | if (atom_list.items.len == 0) continue; |
| 3110 | 3093 | |
| 3111 | 3094 | var entries = std.ArrayList(Entry).init(gpa); |
| ... | ... | @@ -3173,7 +3156,7 @@ fn setVersionSymtab(self: *Elf) !void { |
| 3173 | 3156 | |
| 3174 | 3157 | if (self.verneed_section_index) |shndx| { |
| 3175 | 3158 | try self.verneed.generate(self); |
| 3176 | const shdr = &self.shdrs.items[shndx]; | |
| 3159 | const shdr = &self.sections.items(.shdr)[shndx]; | |
| 3177 | 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 | 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 | 3240 | fn shdrRank(self: *Elf, shndx: u32) u8 { |
| 3265 | const shdr = self.shdrs.items[shndx]; | |
| 3241 | const shdr = self.sections.items(.shdr)[shndx]; | |
| 3266 | 3242 | const name = self.getShString(shdr.sh_name); |
| 3267 | 3243 | const flags = shdr.sh_flags; |
| 3268 | 3244 | |
| ... | ... | @@ -3319,9 +3295,9 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3319 | 3295 | }; |
| 3320 | 3296 | |
| 3321 | 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 | 3299 | defer entries.deinit(); |
| 3324 | for (0..self.shdrs.items.len) |shndx| { | |
| 3300 | for (0..self.sections.items(.shdr).len) |shndx| { | |
| 3325 | 3301 | entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) }); |
| 3326 | 3302 | } |
| 3327 | 3303 | |
| ... | ... | @@ -3333,20 +3309,18 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3333 | 3309 | backlinks[entry.shndx] = @intCast(i); |
| 3334 | 3310 | } |
| 3335 | 3311 | |
| 3336 | const slice = try self.shdrs.toOwnedSlice(gpa); | |
| 3337 | defer gpa.free(slice); | |
| 3312 | var slice = self.sections.toOwnedSlice(); | |
| 3313 | defer slice.deinit(gpa); | |
| 3338 | 3314 | |
| 3339 | try self.shdrs.ensureTotalCapacityPrecise(gpa, slice.len); | |
| 3315 | try self.sections.ensureTotalCapacity(gpa, slice.len); | |
| 3340 | 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 { | |
| 3348 | const gpa = self.base.comp.gpa; | |
| 3349 | ||
| 3323 | fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void { | |
| 3350 | 3324 | for (&[_]*?u32{ |
| 3351 | 3325 | &self.eh_frame_section_index, |
| 3352 | 3326 | &self.eh_frame_rela_section_index, |
| ... | ... | @@ -3388,116 +3362,65 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3388 | 3362 | } |
| 3389 | 3363 | |
| 3390 | 3364 | if (self.symtab_section_index) |index| { |
| 3391 | const shdr = &self.shdrs.items[index]; | |
| 3365 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3392 | 3366 | shdr.sh_link = self.strtab_section_index.?; |
| 3393 | 3367 | } |
| 3394 | 3368 | |
| 3395 | 3369 | if (self.dynamic_section_index) |index| { |
| 3396 | const shdr = &self.shdrs.items[index]; | |
| 3370 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3397 | 3371 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3398 | 3372 | } |
| 3399 | 3373 | |
| 3400 | 3374 | if (self.dynsymtab_section_index) |index| { |
| 3401 | const shdr = &self.shdrs.items[index]; | |
| 3375 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3402 | 3376 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3403 | 3377 | } |
| 3404 | 3378 | |
| 3405 | 3379 | if (self.hash_section_index) |index| { |
| 3406 | const shdr = &self.shdrs.items[index]; | |
| 3380 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3407 | 3381 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3408 | 3382 | } |
| 3409 | 3383 | |
| 3410 | 3384 | if (self.gnu_hash_section_index) |index| { |
| 3411 | const shdr = &self.shdrs.items[index]; | |
| 3385 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3412 | 3386 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3413 | 3387 | } |
| 3414 | 3388 | |
| 3415 | 3389 | if (self.versym_section_index) |index| { |
| 3416 | const shdr = &self.shdrs.items[index]; | |
| 3390 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3417 | 3391 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3418 | 3392 | } |
| 3419 | 3393 | |
| 3420 | 3394 | if (self.verneed_section_index) |index| { |
| 3421 | const shdr = &self.shdrs.items[index]; | |
| 3395 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3422 | 3396 | shdr.sh_link = self.dynstrtab_section_index.?; |
| 3423 | 3397 | } |
| 3424 | 3398 | |
| 3425 | 3399 | if (self.rela_dyn_section_index) |index| { |
| 3426 | const shdr = &self.shdrs.items[index]; | |
| 3400 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3427 | 3401 | shdr.sh_link = self.dynsymtab_section_index orelse 0; |
| 3428 | 3402 | } |
| 3429 | 3403 | |
| 3430 | 3404 | if (self.rela_plt_section_index) |index| { |
| 3431 | const shdr = &self.shdrs.items[index]; | |
| 3405 | const shdr = &self.sections.items(.shdr)[index]; | |
| 3432 | 3406 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 3433 | 3407 | shdr.sh_info = self.plt_section_index.?; |
| 3434 | 3408 | } |
| 3435 | 3409 | |
| 3436 | 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 | 3412 | shdr.sh_link = self.symtab_section_index.?; |
| 3439 | 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 | 3416 | for (self.merge_sections.items) |*msec| { |
| 3457 | 3417 | msec.output_section_index = backlinks[msec.output_section_index]; |
| 3458 | 3418 | } |
| 3459 | 3419 | |
| 3460 | { | |
| 3461 | var output_rela_sections = try self.output_rela_sections.clone(gpa); | |
| 3462 | defer output_rela_sections.deinit(gpa); | |
| 3463 | ||
| 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 | } | |
| 3420 | for (self.sections.items(.shdr)) |*shdr| { | |
| 3421 | if (shdr.sh_type != elf.SHT_RELA) continue; | |
| 3422 | shdr.sh_link = backlinks[shdr.sh_link]; | |
| 3423 | shdr.sh_info = backlinks[shdr.sh_info]; | |
| 3501 | 3424 | } |
| 3502 | 3425 | |
| 3503 | 3426 | if (self.zigObjectPtr()) |zo| { |
| ... | ... | @@ -3508,12 +3431,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3508 | 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 | 3434 | for (self.comdat_group_sections.items) |*cg| { |
| 3518 | 3435 | cg.shndx = backlinks[cg.shndx]; |
| 3519 | 3436 | } |
| ... | ... | @@ -3521,8 +3438,8 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3521 | 3438 | |
| 3522 | 3439 | fn updateSectionSizes(self: *Elf) !void { |
| 3523 | 3440 | const target = self.base.comp.root_mod.resolved_target.result; |
| 3524 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { | |
| 3525 | const shdr = &self.shdrs.items[shndx]; | |
| 3441 | const slice = self.sections.slice(); | |
| 3442 | for (slice.items(.shdr), slice.items(.atom_list)) |*shdr, atom_list| { | |
| 3526 | 3443 | if (atom_list.items.len == 0) continue; |
| 3527 | 3444 | if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue; |
| 3528 | 3445 | for (atom_list.items) |ref| { |
| ... | ... | @@ -3537,38 +3454,38 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3537 | 3454 | } |
| 3538 | 3455 | |
| 3539 | 3456 | if (self.requiresThunks()) { |
| 3540 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { | |
| 3541 | const shdr = self.shdrs.items[shndx]; | |
| 3457 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |*shdr, atom_list, shndx| { | |
| 3542 | 3458 | if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue; |
| 3543 | 3459 | if (atom_list.items.len == 0) continue; |
| 3544 | 3460 | |
| 3545 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 3491 | if (self.rela_dyn_section_index) |shndx| { |
| ... | ... | @@ -3579,11 +3496,11 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3579 | 3496 | for (self.objects.items) |index| { |
| 3580 | 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 | 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 | 3506 | if (self.copy_rel_section_index) |index| { |
| ... | ... | @@ -3591,44 +3508,45 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3591 | 3508 | } |
| 3592 | 3509 | |
| 3593 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 3542 | try self.updateSymtabSize(); |
| 3626 | 3543 | self.updateShStrtabSize(); |
| 3627 | 3544 | } |
| 3628 | 3545 | |
| 3546 | // FIXME:JK this is very much obsolete, remove! | |
| 3629 | 3547 | pub fn updateShStrtabSize(self: *Elf) void { |
| 3630 | 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 | 3579 | /// We permit a maximum of 3**2 number of segments. |
| 3662 | 3580 | fn calcNumberOfSegments(self: *Elf) usize { |
| 3663 | 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 | 3583 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3666 | 3584 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3667 | 3585 | if (self.isZigSection(@intCast(shndx))) continue; |
| ... | ... | @@ -3732,8 +3650,9 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3732 | 3650 | } |
| 3733 | 3651 | }; |
| 3734 | 3652 | |
| 3653 | const slice = self.sections.slice(); | |
| 3735 | 3654 | var alignment = Align{}; |
| 3736 | for (self.shdrs.items, 0..) |shdr, i| { | |
| 3655 | for (slice.items(.shdr), 0..) |shdr, i| { | |
| 3737 | 3656 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3738 | 3657 | if (shdr.sh_flags & elf.SHF_TLS == 0) continue; |
| 3739 | 3658 | if (alignment.first_tls_index == null) alignment.first_tls_index = i; |
| ... | ... | @@ -3758,7 +3677,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3758 | 3677 | cover.deinit(); |
| 3759 | 3678 | }; |
| 3760 | 3679 | |
| 3761 | for (self.shdrs.items, 0..) |shdr, shndx| { | |
| 3680 | for (slice.items(.shdr), 0..) |shdr, shndx| { | |
| 3762 | 3681 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3763 | 3682 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 3764 | 3683 | if (self.isZigSection(@intCast(shndx))) continue; |
| ... | ... | @@ -3779,7 +3698,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3779 | 3698 | |
| 3780 | 3699 | var @"align": u64 = self.page_size; |
| 3781 | 3700 | for (cover.items) |shndx| { |
| 3782 | const shdr = self.shdrs.items[shndx]; | |
| 3701 | const shdr = slice.items(.shdr)[shndx]; | |
| 3783 | 3702 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) continue; |
| 3784 | 3703 | @"align" = @max(@"align", shdr.sh_addralign); |
| 3785 | 3704 | } |
| ... | ... | @@ -3791,7 +3710,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3791 | 3710 | var i: usize = 0; |
| 3792 | 3711 | while (i < cover.items.len) : (i += 1) { |
| 3793 | 3712 | const shndx = cover.items[i]; |
| 3794 | const shdr = &self.shdrs.items[shndx]; | |
| 3713 | const shdr = &slice.items(.shdr)[shndx]; | |
| 3795 | 3714 | if (shdr.sh_type == elf.SHT_NOBITS and shdr.sh_flags & elf.SHF_TLS != 0) { |
| 3796 | 3715 | // .tbss is a little special as it's used only by the loader meaning it doesn't |
| 3797 | 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 | 3726 | // ... |
| 3808 | 3727 | var tbss_addr = addr; |
| 3809 | 3728 | while (i < cover.items.len and |
| 3810 | self.shdrs.items[cover.items[i]].sh_type == elf.SHT_NOBITS and | |
| 3811 | self.shdrs.items[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1) | |
| 3729 | slice.items(.shdr)[cover.items[i]].sh_type == elf.SHT_NOBITS and | |
| 3730 | slice.items(.shdr)[cover.items[i]].sh_flags & elf.SHF_TLS != 0) : (i += 1) | |
| 3812 | 3731 | { |
| 3813 | 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 | 3734 | tbss_addr = alignment.@"align"(tbss_shndx, tbss_shdr.sh_addralign, tbss_addr); |
| 3816 | 3735 | tbss_shdr.sh_addr = tbss_addr; |
| 3817 | 3736 | tbss_addr += tbss_shdr.sh_size; |
| ... | ... | @@ -3830,7 +3749,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3830 | 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 | 3753 | var off = try self.findFreeSpace(filesz, @"align"); |
| 3835 | 3754 | const phndx = try self.addPhdr(.{ |
| 3836 | 3755 | .type = elf.PT_LOAD, |
| ... | ... | @@ -3843,7 +3762,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3843 | 3762 | }); |
| 3844 | 3763 | |
| 3845 | 3764 | for (cover.items) |shndx| { |
| 3846 | const shdr = &self.shdrs.items[shndx]; | |
| 3765 | const shdr = &slice.items(.shdr)[shndx]; | |
| 3847 | 3766 | if (shdr.sh_type == elf.SHT_NOBITS) { |
| 3848 | 3767 | shdr.sh_offset = 0; |
| 3849 | 3768 | continue; |
| ... | ... | @@ -3851,7 +3770,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3851 | 3770 | off = alignment.@"align"(shndx, shdr.sh_addralign, off); |
| 3852 | 3771 | shdr.sh_offset = off; |
| 3853 | 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 | 3776 | addr = mem.alignForward(u64, addr, self.page_size); |
| ... | ... | @@ -3860,7 +3779,7 @@ pub fn allocateAllocSections(self: *Elf) !void { |
| 3860 | 3779 | |
| 3861 | 3780 | /// Allocates non-alloc sections (debug info, symtabs, etc.). |
| 3862 | 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 | 3783 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3865 | 3784 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue; |
| 3866 | 3785 | const needed_size = shdr.sh_size; |
| ... | ... | @@ -3905,13 +3824,15 @@ pub fn allocateNonAllocSections(self: *Elf) !void { |
| 3905 | 3824 | } |
| 3906 | 3825 | |
| 3907 | 3826 | fn allocateSpecialPhdrs(self: *Elf) void { |
| 3827 | const slice = self.sections.slice(); | |
| 3828 | ||
| 3908 | 3829 | for (&[_]struct { ?u16, ?u32 }{ |
| 3909 | 3830 | .{ self.phdr_interp_index, self.interp_section_index }, |
| 3910 | 3831 | .{ self.phdr_dynamic_index, self.dynamic_section_index }, |
| 3911 | 3832 | .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index }, |
| 3912 | 3833 | }) |pair| { |
| 3913 | 3834 | if (pair[0]) |index| { |
| 3914 | const shdr = self.shdrs.items[pair[1].?]; | |
| 3835 | const shdr = slice.items(.shdr)[pair[1].?]; | |
| 3915 | 3836 | const phdr = &self.phdrs.items[index]; |
| 3916 | 3837 | phdr.p_align = shdr.sh_addralign; |
| 3917 | 3838 | phdr.p_offset = shdr.sh_offset; |
| ... | ... | @@ -3926,11 +3847,11 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 3926 | 3847 | // We assume TLS sections are laid out contiguously and that there is |
| 3927 | 3848 | // a single TLS segment. |
| 3928 | 3849 | if (self.phdr_tls_index) |index| { |
| 3929 | const slice = self.shdrs.items; | |
| 3850 | const shdrs = slice.items(.shdr); | |
| 3930 | 3851 | const phdr = &self.phdrs.items[index]; |
| 3931 | 3852 | var shndx: u32 = 0; |
| 3932 | while (shndx < slice.len) { | |
| 3933 | const shdr = slice[shndx]; | |
| 3853 | while (shndx < shdrs.len) { | |
| 3854 | const shdr = shdrs[shndx]; | |
| 3934 | 3855 | if (shdr.sh_flags & elf.SHF_TLS == 0) { |
| 3935 | 3856 | shndx += 1; |
| 3936 | 3857 | continue; |
| ... | ... | @@ -3946,8 +3867,8 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 3946 | 3867 | } |
| 3947 | 3868 | phdr.p_memsz = shdr.sh_addr + shdr.sh_size - phdr.p_vaddr; |
| 3948 | 3869 | |
| 3949 | while (shndx < slice.len) : (shndx += 1) { | |
| 3950 | const next = slice[shndx]; | |
| 3870 | while (shndx < shdrs.len) : (shndx += 1) { | |
| 3871 | const next = shdrs[shndx]; | |
| 3951 | 3872 | if (next.sh_flags & elf.SHF_TLS == 0) break; |
| 3952 | 3873 | phdr.p_align = @max(phdr.p_align, next.sh_addralign); |
| 3953 | 3874 | if (next.sh_type != elf.SHT_NOBITS) { |
| ... | ... | @@ -3971,13 +3892,10 @@ fn writeAtoms(self: *Elf) !void { |
| 3971 | 3892 | } |
| 3972 | 3893 | |
| 3973 | 3894 | var has_reloc_errors = false; |
| 3974 | ||
| 3975 | // TODO iterate over `output_sections` directly | |
| 3976 | for (self.shdrs.items, 0..) |shdr, shndx| { | |
| 3895 | const slice = self.sections.slice(); | |
| 3896 | for (slice.items(.shdr), slice.items(.atom_list), 0..) |shdr, atom_list, shndx| { | |
| 3977 | 3897 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 3978 | 3898 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 3979 | ||
| 3980 | const atom_list = self.output_sections.get(@intCast(shndx)) orelse continue; | |
| 3981 | 3899 | if (atom_list.items.len == 0) continue; |
| 3982 | 3900 | |
| 3983 | 3901 | log.debug("writing atoms in '{s}' section", .{self.getShString(shdr.sh_name)}); |
| ... | ... | @@ -4056,7 +3974,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4056 | 3974 | for (self.thunks.items) |th| { |
| 4057 | 3975 | const thunk_size = th.size(self); |
| 4058 | 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 | 3978 | const offset = @as(u64, @intCast(th.value)) + shdr.sh_offset; |
| 4061 | 3979 | try th.write(self, buffer.writer()); |
| 4062 | 3980 | assert(buffer.items.len == thunk_size); |
| ... | ... | @@ -4086,12 +4004,7 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4086 | 4004 | if (self.linker_defined_index) |index| files.appendAssumeCapacity(index); |
| 4087 | 4005 | |
| 4088 | 4006 | // Section symbols |
| 4089 | for (self.output_sections.keys()) |_| { | |
| 4090 | nlocals += 1; | |
| 4091 | } | |
| 4092 | if (self.eh_frame_section_index) |_| { | |
| 4093 | nlocals += 1; | |
| 4094 | } | |
| 4007 | nlocals += @intCast(self.sections.slice().len); | |
| 4095 | 4008 | |
| 4096 | 4009 | if (self.requiresThunks()) for (self.thunks.items) |*th| { |
| 4097 | 4010 | th.output_symtab_ctx.ilocal = nlocals + 1; |
| ... | ... | @@ -4142,7 +4055,8 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4142 | 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 | 4060 | symtab_shdr.sh_info = nlocals + 1; |
| 4147 | 4061 | symtab_shdr.sh_link = self.strtab_section_index.?; |
| 4148 | 4062 | |
| ... | ... | @@ -4153,13 +4067,14 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4153 | 4067 | const needed_size = (nlocals + nglobals + 1) * sym_size; |
| 4154 | 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 | 4071 | strtab.sh_size = strsize + 1; |
| 4158 | 4072 | } |
| 4159 | 4073 | |
| 4160 | 4074 | fn writeSyntheticSections(self: *Elf) !void { |
| 4161 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4162 | 4075 | const gpa = self.base.comp.gpa; |
| 4076 | const target = self.getTarget(); | |
| 4077 | const slice = self.sections.slice(); | |
| 4163 | 4078 | |
| 4164 | 4079 | if (self.interp_section_index) |shndx| { |
| 4165 | 4080 | var buffer: [256]u8 = undefined; |
| ... | ... | @@ -4167,18 +4082,18 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4167 | 4082 | @memcpy(buffer[0..interp.len], interp); |
| 4168 | 4083 | buffer[interp.len] = 0; |
| 4169 | 4084 | const contents = buffer[0 .. interp.len + 1]; |
| 4170 | const shdr = self.shdrs.items[shndx]; | |
| 4085 | const shdr = slice.items(.shdr)[shndx]; | |
| 4171 | 4086 | assert(shdr.sh_size == contents.len); |
| 4172 | 4087 | try self.base.file.?.pwriteAll(contents, shdr.sh_offset); |
| 4173 | 4088 | } |
| 4174 | 4089 | |
| 4175 | 4090 | if (self.hash_section_index) |shndx| { |
| 4176 | const shdr = self.shdrs.items[shndx]; | |
| 4091 | const shdr = slice.items(.shdr)[shndx]; | |
| 4177 | 4092 | try self.base.file.?.pwriteAll(self.hash.buffer.items, shdr.sh_offset); |
| 4178 | 4093 | } |
| 4179 | 4094 | |
| 4180 | 4095 | if (self.gnu_hash_section_index) |shndx| { |
| 4181 | const shdr = self.shdrs.items[shndx]; | |
| 4096 | const shdr = slice.items(.shdr)[shndx]; | |
| 4182 | 4097 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size()); |
| 4183 | 4098 | defer buffer.deinit(); |
| 4184 | 4099 | try self.gnu_hash.write(self, buffer.writer()); |
| ... | ... | @@ -4186,12 +4101,12 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4186 | 4101 | } |
| 4187 | 4102 | |
| 4188 | 4103 | if (self.versym_section_index) |shndx| { |
| 4189 | const shdr = self.shdrs.items[shndx]; | |
| 4104 | const shdr = slice.items(.shdr)[shndx]; | |
| 4190 | 4105 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.versym.items), shdr.sh_offset); |
| 4191 | 4106 | } |
| 4192 | 4107 | |
| 4193 | 4108 | if (self.verneed_section_index) |shndx| { |
| 4194 | const shdr = self.shdrs.items[shndx]; | |
| 4109 | const shdr = slice.items(.shdr)[shndx]; | |
| 4195 | 4110 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.verneed.size()); |
| 4196 | 4111 | defer buffer.deinit(); |
| 4197 | 4112 | try self.verneed.write(buffer.writer()); |
| ... | ... | @@ -4199,7 +4114,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4199 | 4114 | } |
| 4200 | 4115 | |
| 4201 | 4116 | if (self.dynamic_section_index) |shndx| { |
| 4202 | const shdr = self.shdrs.items[shndx]; | |
| 4117 | const shdr = slice.items(.shdr)[shndx]; | |
| 4203 | 4118 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynamic.size(self)); |
| 4204 | 4119 | defer buffer.deinit(); |
| 4205 | 4120 | try self.dynamic.write(self, buffer.writer()); |
| ... | ... | @@ -4207,7 +4122,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4207 | 4122 | } |
| 4208 | 4123 | |
| 4209 | 4124 | if (self.dynsymtab_section_index) |shndx| { |
| 4210 | const shdr = self.shdrs.items[shndx]; | |
| 4125 | const shdr = slice.items(.shdr)[shndx]; | |
| 4211 | 4126 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.dynsym.size()); |
| 4212 | 4127 | defer buffer.deinit(); |
| 4213 | 4128 | try self.dynsym.write(self, buffer.writer()); |
| ... | ... | @@ -4215,12 +4130,12 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4215 | 4130 | } |
| 4216 | 4131 | |
| 4217 | 4132 | if (self.dynstrtab_section_index) |shndx| { |
| 4218 | const shdr = self.shdrs.items[shndx]; | |
| 4133 | const shdr = slice.items(.shdr)[shndx]; | |
| 4219 | 4134 | try self.base.file.?.pwriteAll(self.dynstrtab.items, shdr.sh_offset); |
| 4220 | 4135 | } |
| 4221 | 4136 | |
| 4222 | 4137 | if (self.eh_frame_section_index) |shndx| { |
| 4223 | const shdr = self.shdrs.items[shndx]; | |
| 4138 | const shdr = slice.items(.shdr)[shndx]; | |
| 4224 | 4139 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 4225 | 4140 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4226 | 4141 | defer buffer.deinit(); |
| ... | ... | @@ -4229,7 +4144,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4229 | 4144 | } |
| 4230 | 4145 | |
| 4231 | 4146 | if (self.eh_frame_hdr_section_index) |shndx| { |
| 4232 | const shdr = self.shdrs.items[shndx]; | |
| 4147 | const shdr = slice.items(.shdr)[shndx]; | |
| 4233 | 4148 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 4234 | 4149 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 4235 | 4150 | defer buffer.deinit(); |
| ... | ... | @@ -4238,7 +4153,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4238 | 4153 | } |
| 4239 | 4154 | |
| 4240 | 4155 | if (self.got_section_index) |index| { |
| 4241 | const shdr = self.shdrs.items[index]; | |
| 4156 | const shdr = slice.items(.shdr)[index]; | |
| 4242 | 4157 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self)); |
| 4243 | 4158 | defer buffer.deinit(); |
| 4244 | 4159 | try self.got.write(self, buffer.writer()); |
| ... | ... | @@ -4246,7 +4161,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4246 | 4161 | } |
| 4247 | 4162 | |
| 4248 | 4163 | if (self.rela_dyn_section_index) |shndx| { |
| 4249 | const shdr = self.shdrs.items[shndx]; | |
| 4164 | const shdr = slice.items(.shdr)[shndx]; | |
| 4250 | 4165 | try self.got.addRela(self); |
| 4251 | 4166 | try self.copy_rel.addRela(self); |
| 4252 | 4167 | self.sortRelaDyn(); |
| ... | ... | @@ -4254,7 +4169,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4254 | 4169 | } |
| 4255 | 4170 | |
| 4256 | 4171 | if (self.plt_section_index) |shndx| { |
| 4257 | const shdr = self.shdrs.items[shndx]; | |
| 4172 | const shdr = slice.items(.shdr)[shndx]; | |
| 4258 | 4173 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt.size(self)); |
| 4259 | 4174 | defer buffer.deinit(); |
| 4260 | 4175 | try self.plt.write(self, buffer.writer()); |
| ... | ... | @@ -4262,7 +4177,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4262 | 4177 | } |
| 4263 | 4178 | |
| 4264 | 4179 | if (self.got_plt_section_index) |shndx| { |
| 4265 | const shdr = self.shdrs.items[shndx]; | |
| 4180 | const shdr = slice.items(.shdr)[shndx]; | |
| 4266 | 4181 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got_plt.size(self)); |
| 4267 | 4182 | defer buffer.deinit(); |
| 4268 | 4183 | try self.got_plt.write(self, buffer.writer()); |
| ... | ... | @@ -4270,7 +4185,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4270 | 4185 | } |
| 4271 | 4186 | |
| 4272 | 4187 | if (self.plt_got_section_index) |shndx| { |
| 4273 | const shdr = self.shdrs.items[shndx]; | |
| 4188 | const shdr = slice.items(.shdr)[shndx]; | |
| 4274 | 4189 | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.plt_got.size(self)); |
| 4275 | 4190 | defer buffer.deinit(); |
| 4276 | 4191 | try self.plt_got.write(self, buffer.writer()); |
| ... | ... | @@ -4278,7 +4193,7 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4278 | 4193 | } |
| 4279 | 4194 | |
| 4280 | 4195 | if (self.rela_plt_section_index) |shndx| { |
| 4281 | const shdr = self.shdrs.items[shndx]; | |
| 4196 | const shdr = slice.items(.shdr)[shndx]; | |
| 4282 | 4197 | try self.plt.addRela(self); |
| 4283 | 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 | 4202 | try self.writeShStrtab(); |
| 4288 | 4203 | } |
| 4289 | 4204 | |
| 4205 | // FIXME:JK again, why is this needed? | |
| 4290 | 4206 | pub fn writeShStrtab(self: *Elf) !void { |
| 4291 | 4207 | if (self.shstrtab_section_index) |index| { |
| 4292 | const shdr = self.shdrs.items[index]; | |
| 4208 | const shdr = self.sections.items(.shdr)[index]; | |
| 4293 | 4209 | log.debug("writing .shstrtab from 0x{x} to 0x{x}", .{ shdr.sh_offset, shdr.sh_offset + shdr.sh_size }); |
| 4294 | 4210 | try self.base.file.?.pwriteAll(self.shstrtab.items, shdr.sh_offset); |
| 4295 | 4211 | } |
| 4296 | 4212 | } |
| 4297 | 4213 | |
| 4298 | 4214 | pub fn writeSymtab(self: *Elf) !void { |
| 4299 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4300 | 4215 | const gpa = self.base.comp.gpa; |
| 4301 | const symtab_shdr = self.shdrs.items[self.symtab_section_index.?]; | |
| 4302 | const strtab_shdr = self.shdrs.items[self.strtab_section_index.?]; | |
| 4216 | const target = self.getTarget(); | |
| 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 | 4220 | const sym_size: u64 = switch (self.ptr_width) { |
| 4304 | 4221 | .p32 => @sizeOf(elf.Elf32_Sym), |
| 4305 | 4222 | .p64 => @sizeOf(elf.Elf64_Sym), |
| ... | ... | @@ -4387,9 +4304,9 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4387 | 4304 | } |
| 4388 | 4305 | |
| 4389 | 4306 | fn writeSectionSymbols(self: *Elf) void { |
| 4307 | const slice = self.sections.slice(); | |
| 4390 | 4308 | var ilocal: u32 = 1; |
| 4391 | for (self.output_sections.keys()) |shndx| { | |
| 4392 | const shdr = self.shdrs.items[shndx]; | |
| 4309 | for (slice.items(.shdr), 0..) |shdr, shndx| { | |
| 4393 | 4310 | const out_sym = &self.symtab.items[ilocal]; |
| 4394 | 4311 | out_sym.* = .{ |
| 4395 | 4312 | .st_name = 0, |
| ... | ... | @@ -4403,7 +4320,7 @@ fn writeSectionSymbols(self: *Elf) void { |
| 4403 | 4320 | } |
| 4404 | 4321 | |
| 4405 | 4322 | if (self.eh_frame_section_index) |shndx| { |
| 4406 | const shdr = self.shdrs.items[shndx]; | |
| 4323 | const shdr = slice.items(.shdr)[shndx]; | |
| 4407 | 4324 | const out_sym = &self.symtab.items[ilocal]; |
| 4408 | 4325 | out_sym.* = .{ |
| 4409 | 4326 | .st_name = 0, |
| ... | ... | @@ -4418,10 +4335,8 @@ fn writeSectionSymbols(self: *Elf) void { |
| 4418 | 4335 | } |
| 4419 | 4336 | |
| 4420 | 4337 | pub fn sectionSymbolOutputSymtabIndex(self: Elf, shndx: u32) u32 { |
| 4421 | if (self.eh_frame_section_index) |index| { | |
| 4422 | if (index == shndx) return @intCast(self.output_sections.keys().len + 1); | |
| 4423 | } | |
| 4424 | return @intCast(self.output_sections.getIndex(shndx).? + 1); | |
| 4338 | _ = self; | |
| 4339 | return shndx + 1; | |
| 4425 | 4340 | } |
| 4426 | 4341 | |
| 4427 | 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 | 4350 | /// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes |
| 4436 | 4351 | /// in a 32-bit ELF file. |
| 4437 | 4352 | pub fn archPtrWidthBytes(self: Elf) u8 { |
| 4438 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4439 | return @intCast(@divExact(target.ptrBitWidth(), 8)); | |
| 4353 | return @intCast(@divExact(self.getTarget().ptrBitWidth(), 8)); | |
| 4440 | 4354 | } |
| 4441 | 4355 | |
| 4442 | 4356 | fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { |
| ... | ... | @@ -4816,25 +4730,26 @@ pub const AddSectionOpts = struct { |
| 4816 | 4730 | |
| 4817 | 4731 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 { |
| 4818 | 4732 | const gpa = self.base.comp.gpa; |
| 4819 | const index: u32 = @intCast(self.shdrs.items.len); | |
| 4820 | const shdr = try self.shdrs.addOne(gpa); | |
| 4821 | shdr.* = .{ | |
| 4822 | .sh_name = opts.name, | |
| 4823 | .sh_type = opts.type, | |
| 4824 | .sh_flags = opts.flags, | |
| 4825 | .sh_addr = 0, | |
| 4826 | .sh_offset = opts.offset, | |
| 4827 | .sh_size = 0, | |
| 4828 | .sh_link = opts.link, | |
| 4829 | .sh_info = opts.info, | |
| 4830 | .sh_addralign = opts.addralign, | |
| 4831 | .sh_entsize = opts.entsize, | |
| 4832 | }; | |
| 4733 | const index: u32 = @intCast(try self.sections.addOne(gpa)); | |
| 4734 | self.sections.set(index, .{ | |
| 4735 | .shdr = .{ | |
| 4736 | .sh_name = opts.name, | |
| 4737 | .sh_type = opts.type, | |
| 4738 | .sh_flags = opts.flags, | |
| 4739 | .sh_addr = 0, | |
| 4740 | .sh_offset = opts.offset, | |
| 4741 | .sh_size = 0, | |
| 4742 | .sh_link = opts.link, | |
| 4743 | .sh_info = opts.info, | |
| 4744 | .sh_addralign = opts.addralign, | |
| 4745 | .sh_entsize = opts.entsize, | |
| 4746 | }, | |
| 4747 | }); | |
| 4833 | 4748 | return index; |
| 4834 | 4749 | } |
| 4835 | 4750 | |
| 4836 | 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 | 4753 | const this_name = self.getShString(shdr.sh_name); |
| 4839 | 4754 | if (mem.eql(u8, this_name, name)) return @intCast(i); |
| 4840 | 4755 | } else return null; |
| ... | ... | @@ -5012,7 +4927,7 @@ pub fn gotAddress(self: *Elf) i64 { |
| 5012 | 4927 | break :blk self.got_plt_section_index.?; |
| 5013 | 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 | 4933 | pub fn tpAddress(self: *Elf) i64 { |
| ... | ... | @@ -5366,16 +5281,16 @@ fn fmtDumpState( |
| 5366 | 5281 | } |
| 5367 | 5282 | |
| 5368 | 5283 | try writer.writeAll("\nOutput shdrs\n"); |
| 5369 | for (self.shdrs.items, 0..) |shdr, shndx| { | |
| 5370 | try writer.print(" shdr({d}) : phdr({?d}) : {}\n", .{ | |
| 5284 | for (self.sections.items(.shdr), self.sections.items(.phndx), 0..) |shdr, phndx, shndx| { | |
| 5285 | try writer.print(" shdr({d}) : phdr({d}) : {}\n", .{ | |
| 5371 | 5286 | shndx, |
| 5372 | self.phdr_to_shdr_table.get(@intCast(shndx)), | |
| 5287 | phndx, | |
| 5373 | 5288 | self.fmtShdr(shdr), |
| 5374 | 5289 | }); |
| 5375 | 5290 | } |
| 5376 | 5291 | try writer.writeAll("\nOutput phdrs\n"); |
| 5377 | 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 | 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 | 5536 | /// Index of the last allocated atom in this section. |
| 5618 | 5537 | last_atom_index: Atom.Index = 0, |
| 5619 | 5538 | |
| ... | ... | @@ -5634,13 +5553,6 @@ const LastAtomAndFreeList = struct { |
| 5634 | 5553 | /// by 1 byte. It will then have -1 overcapacity. |
| 5635 | 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 | 5557 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { |
| 5646 | 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 | 48 | } |
| 49 | 49 | |
| 50 | 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 | 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 | 116 | |
| 117 | 117 | pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 118 | 118 | const zo = elf_file.zigObjectPtr().?; |
| 119 | const shdr = &elf_file.shdrs.items[self.output_section_index]; | |
| 120 | const meta = elf_file.last_atom_and_free_list_table.getPtr(self.output_section_index).?; | |
| 121 | const free_list = &meta.free_list; | |
| 122 | const last_atom_index = &meta.last_atom_index; | |
| 119 | const slice = elf_file.sections.slice(); | |
| 120 | const shdr = &slice.items(.shdr)[self.output_section_index]; | |
| 121 | const free_list = &slice.items(.free_list)[self.output_section_index]; | |
| 122 | const last_atom_index = &slice.items(.last_atom_index)[self.output_section_index]; | |
| 123 | 123 | const new_atom_ideal_capacity = Elf.padToIdeal(self.size); |
| 124 | 124 | |
| 125 | 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 | 254 | const comp = elf_file.base.comp; |
| 255 | 255 | const gpa = comp.gpa; |
| 256 | 256 | const shndx = self.output_section_index; |
| 257 | const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; | |
| 258 | const free_list = &meta.free_list; | |
| 259 | const last_atom_index = &meta.last_atom_index; | |
| 257 | const slice = elf_file.sections.slice(); | |
| 258 | const free_list = &slice.items(.free_list)[shndx]; | |
| 259 | const last_atom_index = &slice.items(.last_atom_index)[shndx]; | |
| 260 | 260 | var already_have_free_list_node = false; |
| 261 | 261 | { |
| 262 | 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 | 129 | |
| 130 | 130 | pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 131 | 131 | const gpa = elf_file.base.comp.gpa; |
| 132 | const slice = elf_file.sections.slice(); | |
| 132 | 133 | |
| 133 | 134 | var nsyms: usize = 0; |
| 134 | for (elf_file.shdrs.items) |shdr| { | |
| 135 | for (slice.items(.shdr)) |shdr| { | |
| 135 | 136 | if (elf_file.getStartStopBasename(shdr)) |_| { |
| 136 | 137 | nsyms += 2; // __start_, __stop_ |
| 137 | 138 | } |
| ... | ... | @@ -143,7 +144,7 @@ pub fn initStartStopSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 143 | 144 | try self.symbols_extra.ensureUnusedCapacity(gpa, nsyms * @sizeOf(Symbol.Extra)); |
| 144 | 145 | try self.symbols_resolver.ensureUnusedCapacity(gpa, nsyms); |
| 145 | 146 | |
| 146 | for (elf_file.shdrs.items) |shdr| { | |
| 147 | for (slice.items(.shdr)) |shdr| { | |
| 147 | 148 | if (elf_file.getStartStopBasename(shdr)) |name| { |
| 148 | 149 | const start_name = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name}); |
| 149 | 150 | defer gpa.free(start_name); |
| ... | ... | @@ -193,6 +194,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) !void { |
| 193 | 194 | pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 194 | 195 | const comp = elf_file.base.comp; |
| 195 | 196 | const link_mode = comp.config.link_mode; |
| 197 | const shdrs = elf_file.sections.items(.shdr); | |
| 196 | 198 | |
| 197 | 199 | const allocSymbol = struct { |
| 198 | 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 | 206 | |
| 205 | 207 | // _DYNAMIC |
| 206 | 208 | if (elf_file.dynamic_section_index) |shndx| { |
| 207 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 209 | const shdr = shdrs[shndx]; | |
| 208 | 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 | 215 | |
| 214 | 216 | // __init_array_start, __init_array_end |
| 215 | 217 | if (elf_file.sectionByName(".init_array")) |shndx| { |
| 216 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 218 | const shdr = shdrs[shndx]; | |
| 217 | 219 | allocSymbol(self, self.init_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 218 | 220 | allocSymbol(self, self.init_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); |
| 219 | 221 | } |
| 220 | 222 | |
| 221 | 223 | // __fini_array_start, __fini_array_end |
| 222 | 224 | if (elf_file.sectionByName(".fini_array")) |shndx| { |
| 223 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 225 | const shdr = shdrs[shndx]; | |
| 224 | 226 | allocSymbol(self, self.fini_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 225 | 227 | allocSymbol(self, self.fini_array_end_index.?, shdr.sh_addr + shdr.sh_size, shndx, elf_file); |
| 226 | 228 | } |
| 227 | 229 | |
| 228 | 230 | // __preinit_array_start, __preinit_array_end |
| 229 | 231 | if (elf_file.sectionByName(".preinit_array")) |shndx| { |
| 230 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 232 | const shdr = shdrs[shndx]; | |
| 231 | 233 | allocSymbol(self, self.preinit_array_start_index.?, shdr.sh_addr, shndx, elf_file); |
| 232 | 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 | 237 | // _GLOBAL_OFFSET_TABLE_ |
| 236 | 238 | if (elf_file.getTarget().cpu.arch == .x86_64) { |
| 237 | 239 | if (elf_file.got_plt_section_index) |shndx| { |
| 238 | const shdr = elf_file.shdrs.items[shndx]; | |
| 240 | const shdr = shdrs[shndx]; | |
| 239 | 241 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); |
| 240 | 242 | } |
| 241 | 243 | } else { |
| 242 | 244 | if (elf_file.got_section_index) |shndx| { |
| 243 | const shdr = elf_file.shdrs.items[shndx]; | |
| 245 | const shdr = shdrs[shndx]; | |
| 244 | 246 | allocSymbol(self, self.got_index.?, shdr.sh_addr, shndx, elf_file); |
| 245 | 247 | } |
| 246 | 248 | } |
| 247 | 249 | |
| 248 | 250 | // _PROCEDURE_LINKAGE_TABLE_ |
| 249 | 251 | if (elf_file.plt_section_index) |shndx| { |
| 250 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 252 | const shdr = shdrs[shndx]; | |
| 251 | 253 | allocSymbol(self, self.plt_index.?, shdr.sh_addr, shndx, elf_file); |
| 252 | 254 | } |
| 253 | 255 | |
| 254 | 256 | // __dso_handle |
| 255 | 257 | if (self.dso_handle_index) |index| { |
| 256 | const shdr = &elf_file.shdrs.items[1]; | |
| 258 | const shdr = shdrs[1]; | |
| 257 | 259 | allocSymbol(self, index, shdr.sh_addr, 0, elf_file); |
| 258 | 260 | } |
| 259 | 261 | |
| 260 | 262 | // __GNU_EH_FRAME_HDR |
| 261 | 263 | if (elf_file.eh_frame_hdr_section_index) |shndx| { |
| 262 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 264 | const shdr = shdrs[shndx]; | |
| 263 | 265 | allocSymbol(self, self.gnu_eh_frame_hdr_index.?, shdr.sh_addr, shndx, elf_file); |
| 264 | 266 | } |
| 265 | 267 | |
| 266 | 268 | // __rela_iplt_start, __rela_iplt_end |
| 267 | 269 | if (elf_file.rela_dyn_section_index) |shndx| blk: { |
| 268 | 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 | 272 | const end_addr = shdr.sh_addr + shdr.sh_size; |
| 271 | 273 | const start_addr = end_addr - elf_file.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela); |
| 272 | 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 | 279 | { |
| 278 | 280 | var value: u64 = 0; |
| 279 | 281 | var osec: u32 = 0; |
| 280 | for (elf_file.shdrs.items, 0..) |shdr, shndx| { | |
| 282 | for (shdrs, 0..) |shdr, shndx| { | |
| 281 | 283 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) { |
| 282 | 284 | value = shdr.sh_addr + shdr.sh_size; |
| 283 | 285 | osec = @intCast(shndx); |
| ... | ... | @@ -289,7 +291,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 289 | 291 | // __global_pointer$ |
| 290 | 292 | if (self.global_pointer_index) |index| { |
| 291 | 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 | 295 | shndx, |
| 294 | 296 | } else .{ 0, 0 }; |
| 295 | 297 | allocSymbol(self, index, value, osec, elf_file); |
| ... | ... | @@ -305,7 +307,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 305 | 307 | const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file); |
| 306 | 308 | const stop = elf_file.symbol(stop_ref).?; |
| 307 | 309 | const shndx = elf_file.sectionByName(name["__start_".len..]).?; |
| 308 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 310 | const shdr = shdrs[shndx]; | |
| 309 | 311 | start.value = @intCast(shdr.sh_addr); |
| 310 | 312 | start.output_section_index = shndx; |
| 311 | 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 | 998 | |
| 999 | 999 | const comp = elf_file.base.comp; |
| 1000 | 1000 | const gpa = comp.gpa; |
| 1001 | const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_index); | |
| 1002 | if (!gop.found_existing) gop.value_ptr.* = .{}; | |
| 1003 | try gop.value_ptr.append(gpa, .{ .index = atom_index, .file = self.index }); | |
| 1001 | const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index]; | |
| 1002 | try atom_list.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 | 1010 | const shndx = atom_ptr.relocsShndx() orelse continue; |
| 1012 | 1011 | const shdr = self.shdrs.items[shndx]; |
| 1013 | 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 | 1015 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); |
| 1016 | 1016 | out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela); |
| 1017 | 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 | 1022 | for (self.atoms_indexes.items) |atom_index| { |
| 1023 | 1023 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1024 | 1024 | if (!atom_ptr.alive) continue; |
| ... | ... | @@ -1027,15 +1027,10 @@ pub fn addAtomsToRelaSections(self: *Object, elf_file: *Elf) !void { |
| 1027 | 1027 | const shdr = self.shdrs.items[shndx]; |
| 1028 | 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 | 1032 | shdr.sh_info = atom_ptr.output_section_index; |
| 1032 | 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 | 126 | const sym_name = symbol.name(elf_file); |
| 127 | 127 | const sh_addr, const sh_size = blk: { |
| 128 | 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 | 130 | break :blk .{ shdr.sh_addr, shdr.sh_size }; |
| 131 | 131 | }; |
| 132 | 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 | 173 | pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 174 | 174 | if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; |
| 175 | 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 | 177 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 178 | 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 | 181 | pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 182 | 182 | if (!symbol.flags.has_plt) return 0; |
| 183 | 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 | 185 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 186 | 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 | 189 | pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 190 | 190 | if (!symbol.flags.has_plt) return 0; |
| 191 | 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 | 193 | return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size); |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 197 | 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 | 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 | 300 | break :blk 0; |
| 301 | 301 | } |
| 302 | 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 | 304 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) |
| 305 | 305 | break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); |
| 306 | 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 | 170 | .addralign = 1, |
| 171 | 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 | 175 | try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index); |
| 175 | 176 | if (elf_file.base.isRelocatable()) { |
| 176 | const rela_shndx = try elf_file.addRelaShdr( | |
| 177 | _ = try elf_file.addRelaShdr( | |
| 177 | 178 | try elf_file.insertShString(".rela.text.zig"), |
| 178 | 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 | 181 | } else { |
| 184 | try elf_file.phdr_to_shdr_table.putNoClobber( | |
| 185 | gpa, | |
| 186 | elf_file.zig_text_section_index.?, | |
| 187 | elf_file.phdr_zig_load_re_index.?, | |
| 188 | ); | |
| 182 | phndx.* = elf_file.phdr_zig_load_re_index.?; | |
| 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 | 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 | 191 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 200 | 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 | 196 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index); |
| 204 | 197 | if (elf_file.base.isRelocatable()) { |
| 205 | const rela_shndx = try elf_file.addRelaShdr( | |
| 198 | _ = try elf_file.addRelaShdr( | |
| 206 | 199 | try elf_file.insertShString(".rela.data.rel.ro.zig"), |
| 207 | 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 | 202 | } else { |
| 213 | try elf_file.phdr_to_shdr_table.putNoClobber( | |
| 214 | gpa, | |
| 215 | elf_file.zig_data_rel_ro_section_index.?, | |
| 216 | elf_file.phdr_zig_load_ro_index.?, | |
| 217 | ); | |
| 203 | phndx.* = elf_file.phdr_zig_load_ro_index.?; | |
| 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 | 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 | 212 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 229 | 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 | 217 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index); |
| 233 | 218 | if (elf_file.base.isRelocatable()) { |
| 234 | const rela_shndx = try elf_file.addRelaShdr( | |
| 219 | _ = try elf_file.addRelaShdr( | |
| 235 | 220 | try elf_file.insertShString(".rela.data.zig"), |
| 236 | 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 | 223 | } else { |
| 242 | try elf_file.phdr_to_shdr_table.putNoClobber( | |
| 243 | gpa, | |
| 244 | elf_file.zig_data_section_index.?, | |
| 245 | elf_file.phdr_zig_load_rw_index.?, | |
| 246 | ); | |
| 224 | phndx.* = elf_file.phdr_zig_load_rw_index.?; | |
| 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 | 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 | 233 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 258 | 234 | .offset = 0, |
| 259 | 235 | }); |
| 260 | const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?]; | |
| 261 | if (elf_file.phdr_zig_load_zerofill_index) |phndx| { | |
| 262 | const phdr = elf_file.phdrs.items[phndx]; | |
| 236 | const shdr = &elf_file.sections.items(.shdr)[elf_file.zig_bss_section_index.?]; | |
| 237 | const phndx = &elf_file.sections.items(.phndx)[elf_file.zig_bss_section_index.?]; | |
| 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 | 243 | shdr.sh_addr = phdr.p_vaddr; |
| 264 | 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 | 248 | switch (comp.config.debug_format) { |
| ... | ... | @@ -305,7 +280,6 @@ pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { |
| 305 | 280 | }); |
| 306 | 281 | self.debug_str_section_dirty = true; |
| 307 | 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 | 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 | 290 | }); |
| 317 | 291 | self.debug_info_section_dirty = true; |
| 318 | 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 | 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 | 300 | }); |
| 328 | 301 | self.debug_abbrev_section_dirty = true; |
| 329 | 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 | 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 | 310 | }); |
| 339 | 311 | self.debug_aranges_section_dirty = true; |
| 340 | 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 | 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 | 320 | }); |
| 350 | 321 | self.debug_line_section_dirty = true; |
| 351 | 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 | 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 | 332 | }); |
| 363 | 333 | self.debug_line_str_section_dirty = true; |
| 364 | 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 | 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 | 342 | }); |
| 374 | 343 | self.debug_loclists_section_dirty = true; |
| 375 | 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 | 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 | 352 | }); |
| 385 | 353 | self.debug_rnglists_section_dirty = true; |
| 386 | 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 | 357 | try dwarf.initMetadata(); |
| ... | ... | @@ -507,7 +474,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi |
| 507 | 474 | const atom_ptr = self.atom(sym.ref.index).?; |
| 508 | 475 | if (!atom_ptr.alive) continue; |
| 509 | 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 | 478 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; |
| 512 | 479 | esym.st_size = shdr.sh_size; |
| 513 | 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 | 634 | } |
| 668 | 635 | |
| 669 | 636 | if (elf_file.base.isRelocatable() and relocs.items.len > 0) { |
| 670 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx); | |
| 671 | if (!gop.found_existing) { | |
| 672 | const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)}); | |
| 673 | defer gpa.free(rela_sect_name); | |
| 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 }; | |
| 637 | const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)}); | |
| 638 | defer gpa.free(rela_sect_name); | |
| 639 | if (elf_file.sectionByName(rela_sect_name) == null) { | |
| 640 | _ = try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), shndx); | |
| 677 | 641 | } |
| 678 | 642 | } |
| 679 | 643 | } |
| ... | ... | @@ -769,7 +733,7 @@ fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Sym |
| 769 | 733 | pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.Elf64_Shdr { |
| 770 | 734 | const atom_ptr = self.atom(atom_index) orelse return Elf.null_shdr; |
| 771 | 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 | 737 | shdr.sh_addr = 0; |
| 774 | 738 | shdr.sh_offset = 0; |
| 775 | 739 | shdr.sh_size = atom_ptr.size; |
| ... | ... | @@ -947,8 +911,8 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void { |
| 947 | 911 | .p32 => @sizeOf(elf.Elf32_Shdr), |
| 948 | 912 | .p64 => @sizeOf(elf.Elf64_Shdr), |
| 949 | 913 | }; |
| 950 | var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.shdrs.items.len * shsize; | |
| 951 | for (elf_file.shdrs.items) |shdr| { | |
| 914 | var end_pos: u64 = elf_file.shdr_table_offset.? + elf_file.sections.items(.shdr).len * shsize; | |
| 915 | for (elf_file.sections.items(.shdr)) |shdr| { | |
| 952 | 916 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 953 | 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 | 965 | // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level |
| 1002 | 966 | if (self.relocs.items[rela_shndx].items.len == 0) continue; |
| 1003 | 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 | 969 | if (out_shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1006 | ||
| 970 | const atom_list = &elf_file.sections.items(.atom_list)[out_shndx]; | |
| 1007 | 971 | const gpa = elf_file.base.comp.gpa; |
| 1008 | const sec = elf_file.output_rela_sections.getPtr(out_shndx).?; | |
| 1009 | try sec.atom_list.append(gpa, .{ .index = atom_index, .file = self.index }); | |
| 972 | try 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 | 1039 | pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 { |
| 1077 | 1040 | const gpa = elf_file.base.comp.gpa; |
| 1078 | 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 | 1044 | if (shdr.sh_flags & elf.SHF_TLS != 0) { |
| 1082 | 1045 | const tlv = self.tls_variables.get(atom_index).?; |
| ... | ... | @@ -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 | 1370 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 1408 | 1371 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1409 | 1372 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| ... | ... | @@ -1458,16 +1421,13 @@ fn updateTlv( |
| 1458 | 1421 | gop.value_ptr.* = .{ .symbol_index = sym_index }; |
| 1459 | 1422 | |
| 1460 | 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 | 1425 | gop.value_ptr.code = try gpa.dupe(u8, code); |
| 1463 | 1426 | } |
| 1464 | 1427 | } |
| 1465 | 1428 | |
| 1466 | { | |
| 1467 | const gop = try elf_file.output_sections.getOrPut(gpa, atom_ptr.output_section_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 | } | |
| 1429 | const atom_list = &elf_file.sections.items(.atom_list)[atom_ptr.output_section_index]; | |
| 1430 | try atom_list.append(gpa, .{ .index = atom_ptr.atom_index, .file = self.index }); | |
| 1471 | 1431 | } |
| 1472 | 1432 | |
| 1473 | 1433 | pub fn updateFunc( |
| ... | ... | @@ -1519,7 +1479,7 @@ pub fn updateFunc( |
| 1519 | 1479 | const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code); |
| 1520 | 1480 | log.debug("setting shdr({x},{s}) for {}", .{ |
| 1521 | 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 | 1483 | ip.getNav(func.owner_nav).fqn.fmt(ip), |
| 1524 | 1484 | }); |
| 1525 | 1485 | const old_rva, const old_alignment = blk: { |
| ... | ... | @@ -1647,10 +1607,10 @@ pub fn updateNav( |
| 1647 | 1607 | const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code); |
| 1648 | 1608 | log.debug("setting shdr({x},{s}) for {}", .{ |
| 1649 | 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 | 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 | 1614 | try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code) |
| 1655 | 1615 | else |
| 1656 | 1616 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); |
| ... | ... | @@ -1749,7 +1709,7 @@ fn updateLazySymbol( |
| 1749 | 1709 | local_sym.value = 0; |
| 1750 | 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 | 1713 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1754 | 1714 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1755 | 1715 | } |
| ... | ... | @@ -1805,7 +1765,7 @@ fn lowerConst( |
| 1805 | 1765 | // TODO rename and re-audit this method |
| 1806 | 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 | 1769 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1810 | 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 | 1929 | |
| 1970 | 1930 | fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { |
| 1971 | 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 | 1933 | const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1974 | 1934 | const source_addr = tr_sym.address(.{}, elf_file); |
| 1975 | 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 | 13 | |
| 14 | 14 | pub fn address(fde: Fde, elf_file: *Elf) u64 { |
| 15 | 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 | 17 | else |
| 18 | 18 | 0; |
| 19 | 19 | return base + fde.out_offset; |
| ... | ... | @@ -112,7 +112,7 @@ pub const Cie = struct { |
| 112 | 112 | |
| 113 | 113 | pub fn address(cie: Cie, elf_file: *Elf) u64 { |
| 114 | 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 | 116 | else |
| 117 | 117 | 0; |
| 118 | 118 | return base + cie.out_offset; |
| ... | ... | @@ -326,7 +326,9 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file: |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | 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 | 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 | 448 | } |
| 447 | 449 | |
| 448 | 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 | 455 | for (elf_file.objects.items) |index| { |
| 452 | 456 | const object = elf_file.file(index).?.object; |
| ... | ... | @@ -482,8 +486,9 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void { |
| 482 | 486 | try writer.writeByte(EH_PE.udata4); |
| 483 | 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.?]; | |
| 486 | const eh_frame_hdr_shdr = elf_file.shdrs.items[elf_file.eh_frame_hdr_section_index.?]; | |
| 489 | const shdrs = elf_file.sections.items(.shdr); | |
| 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 | 492 | const num_fdes = @as(u32, @intCast(@divExact(eh_frame_hdr_shdr.sh_size - eh_frame_hdr_header_size, 8))); |
| 488 | 493 | try writer.writeInt( |
| 489 | 494 | u32, |
src/link/Elf/merge_section.zig+2-4| ... | ... | @@ -29,7 +29,7 @@ pub const MergeSection = struct { |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | 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 | 33 | return @intCast(shdr.sh_addr + msec.value); |
| 34 | 34 | } |
| 35 | 35 | |
| ... | ... | @@ -108,13 +108,11 @@ pub const MergeSection = struct { |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 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 | 112 | .name = msec.name_offset, |
| 113 | 113 | .type = msec.type, |
| 114 | 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 | 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 | 209 | for (elf_file.objects.items) |index| { |
| 210 | 210 | const object = elf_file.file(index).?.object; |
| 211 | 211 | try object.addAtomsToOutputSections(elf_file); |
| 212 | try object.addAtomsToRelaSections(elf_file); | |
| 212 | object.addAtomsToRelaSections(elf_file); | |
| 213 | 213 | } |
| 214 | 214 | try elf_file.updateMergeSectionSizes(); |
| 215 | 215 | try updateSectionSizes(elf_file); |
| ... | ... | @@ -347,36 +347,37 @@ fn initComdatGroups(elf_file: *Elf) !void { |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | fn updateSectionSizes(elf_file: *Elf) !void { |
| 350 | for (elf_file.output_sections.keys(), elf_file.output_sections.values()) |shndx, atom_list| { | |
| 351 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 352 | for (atom_list.items) |ref| { | |
| 353 | const atom_ptr = elf_file.atom(ref) orelse continue; | |
| 354 | if (!atom_ptr.alive) continue; | |
| 355 | const offset = atom_ptr.alignment.forward(shdr.sh_size); | |
| 356 | const padding = offset - shdr.sh_size; | |
| 357 | atom_ptr.value = @intCast(offset); | |
| 358 | shdr.sh_size += padding + atom_ptr.size; | |
| 359 | shdr.sh_addralign = @max(shdr.sh_addralign, atom_ptr.alignment.toByteUnits() orelse 1); | |
| 360 | } | |
| 361 | } | |
| 350 | const slice = elf_file.sections.slice(); | |
| 351 | for (slice.items(.shdr), 0..) |*shdr, shndx| { | |
| 352 | if (shdr.sh_type != elf.SHT_RELA) { | |
| 353 | const atom_list = slice.items(.atom_list)[shndx]; | |
| 354 | for (atom_list.items) |ref| { | |
| 355 | const atom_ptr = elf_file.atom(ref) orelse continue; | |
| 356 | if (!atom_ptr.alive) continue; | |
| 357 | const offset = atom_ptr.alignment.forward(shdr.sh_size); | |
| 358 | const padding = offset - shdr.sh_size; | |
| 359 | atom_ptr.value = @intCast(offset); | |
| 360 | shdr.sh_size += padding + atom_ptr.size; | |
| 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| { | |
| 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; | |
| 372 | if (shdr.sh_size == 0) shdr.sh_offset = 0; | |
| 370 | 373 | } |
| 371 | ||
| 372 | if (shdr.sh_size == 0) shdr.sh_offset = 0; | |
| 373 | 374 | } |
| 374 | 375 | |
| 375 | 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 | 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 | 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 | 388 | |
| 388 | 389 | fn updateComdatGroupsSizes(elf_file: *Elf) void { |
| 389 | 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 | 392 | shdr.sh_size = cg.size(elf_file); |
| 392 | 393 | shdr.sh_link = elf_file.symtab_section_index.?; |
| 393 | 394 | |
| ... | ... | @@ -399,7 +400,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void { |
| 399 | 400 | |
| 400 | 401 | /// Allocates alloc sections when merging relocatable objects files together. |
| 401 | 402 | fn allocateAllocSections(elf_file: *Elf) !void { |
| 402 | for (elf_file.shdrs.items) |*shdr| { | |
| 403 | for (elf_file.sections.items(.shdr)) |*shdr| { | |
| 403 | 404 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 404 | 405 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 405 | 406 | if (shdr.sh_type == elf.SHT_NOBITS) { |
| ... | ... | @@ -418,13 +419,13 @@ fn allocateAllocSections(elf_file: *Elf) !void { |
| 418 | 419 | |
| 419 | 420 | fn writeAtoms(elf_file: *Elf) !void { |
| 420 | 421 | const gpa = elf_file.base.comp.gpa; |
| 422 | const slice = elf_file.sections.slice(); | |
| 421 | 423 | |
| 422 | 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 | 426 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 425 | 427 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 426 | ||
| 427 | const atom_list = elf_file.output_sections.get(@intCast(shndx)) orelse continue; | |
| 428 | if (shdr.sh_type == elf.SHT_RELA) continue; | |
| 428 | 429 | if (atom_list.items.len == 0) continue; |
| 429 | 430 | |
| 430 | 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 | 491 | |
| 491 | 492 | fn writeSyntheticSections(elf_file: *Elf) !void { |
| 492 | 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| { | |
| 495 | if (sec.atom_list.items.len == 0) continue; | |
| 496 | ||
| 497 | const shdr = elf_file.shdrs.items[sec.shndx]; | |
| 496 | for (slice.items(.shdr)) |shdr| { | |
| 497 | if (shdr.sh_type != elf.SHT_RELA) continue; | |
| 498 | const atom_list = slice.items(.atom_list)[shdr.sh_info]; | |
| 499 | if (atom_list.items.len == 0) continue; | |
| 498 | 500 | |
| 499 | 501 | const num_relocs = math.cast(usize, @divExact(shdr.sh_size, shdr.sh_entsize)) orelse |
| 500 | 502 | return error.Overflow; |
| 501 | 503 | var relocs = try std.ArrayList(elf.Elf64_Rela).initCapacity(gpa, num_relocs); |
| 502 | 504 | defer relocs.deinit(); |
| 503 | 505 | |
| 504 | for (sec.atom_list.items) |ref| { | |
| 506 | for (atom_list.items) |ref| { | |
| 505 | 507 | const atom_ptr = elf_file.atom(ref) orelse continue; |
| 506 | 508 | if (!atom_ptr.alive) continue; |
| 507 | 509 | try atom_ptr.writeRelocs(elf_file, &relocs); |
| ... | ... | @@ -527,7 +529,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 527 | 529 | } |
| 528 | 530 | |
| 529 | 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 | 533 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 532 | 534 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 533 | 535 | defer buffer.deinit(); |
| ... | ... | @@ -540,7 +542,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 540 | 542 | try elf_file.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 541 | 543 | } |
| 542 | 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 | 546 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 545 | 547 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 546 | 548 | defer buffer.deinit(); |
| ... | ... | @@ -561,7 +563,7 @@ fn writeSyntheticSections(elf_file: *Elf) !void { |
| 561 | 563 | fn writeComdatGroups(elf_file: *Elf) !void { |
| 562 | 564 | const gpa = elf_file.base.comp.gpa; |
| 563 | 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 | 567 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 566 | 568 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 567 | 569 | defer buffer.deinit(); |
src/link/Elf/synthetic_sections.zig+30-22| ... | ... | @@ -95,6 +95,8 @@ pub const DynamicSection = struct { |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | pub fn write(dt: DynamicSection, elf_file: *Elf, writer: anytype) !void { |
| 98 | const shdrs = elf_file.sections.items(.shdr); | |
| 99 | ||
| 98 | 100 | // NEEDED |
| 99 | 101 | for (dt.needed.items) |off| { |
| 100 | 102 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NEEDED, .d_val = off }); |
| ... | ... | @@ -112,33 +114,33 @@ pub const DynamicSection = struct { |
| 112 | 114 | |
| 113 | 115 | // INIT |
| 114 | 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 | 118 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT, .d_val = addr }); |
| 117 | 119 | } |
| 118 | 120 | |
| 119 | 121 | // FINI |
| 120 | 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 | 124 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI, .d_val = addr }); |
| 123 | 125 | } |
| 124 | 126 | |
| 125 | 127 | // INIT_ARRAY |
| 126 | 128 | if (elf_file.sectionByName(".init_array")) |shndx| { |
| 127 | const shdr = elf_file.shdrs.items[shndx]; | |
| 129 | const shdr = shdrs[shndx]; | |
| 128 | 130 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAY, .d_val = shdr.sh_addr }); |
| 129 | 131 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_INIT_ARRAYSZ, .d_val = shdr.sh_size }); |
| 130 | 132 | } |
| 131 | 133 | |
| 132 | 134 | // FINI_ARRAY |
| 133 | 135 | if (elf_file.sectionByName(".fini_array")) |shndx| { |
| 134 | const shdr = elf_file.shdrs.items[shndx]; | |
| 136 | const shdr = shdrs[shndx]; | |
| 135 | 137 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAY, .d_val = shdr.sh_addr }); |
| 136 | 138 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_FINI_ARRAYSZ, .d_val = shdr.sh_size }); |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | 141 | // RELA |
| 140 | 142 | if (elf_file.rela_dyn_section_index) |shndx| { |
| 141 | const shdr = elf_file.shdrs.items[shndx]; | |
| 143 | const shdr = shdrs[shndx]; | |
| 142 | 144 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELA, .d_val = shdr.sh_addr }); |
| 143 | 145 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_RELASZ, .d_val = shdr.sh_size }); |
| 144 | 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 | 148 | |
| 147 | 149 | // JMPREL |
| 148 | 150 | if (elf_file.rela_plt_section_index) |shndx| { |
| 149 | const shdr = elf_file.shdrs.items[shndx]; | |
| 151 | const shdr = shdrs[shndx]; | |
| 150 | 152 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_JMPREL, .d_val = shdr.sh_addr }); |
| 151 | 153 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTRELSZ, .d_val = shdr.sh_size }); |
| 152 | 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 | 156 | |
| 155 | 157 | // PLTGOT |
| 156 | 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 | 160 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_PLTGOT, .d_val = addr }); |
| 159 | 161 | } |
| 160 | 162 | |
| 161 | 163 | { |
| 162 | 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 | 166 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_HASH, .d_val = addr }); |
| 165 | 167 | } |
| 166 | 168 | |
| 167 | 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 | 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 | 179 | // SYMTAB + SYMENT |
| 178 | 180 | { |
| 179 | 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 | 183 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_SYMTAB, .d_val = shdr.sh_addr }); |
| 182 | 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 | 187 | // STRTAB + STRSZ |
| 186 | 188 | { |
| 187 | 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 | 191 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRTAB, .d_val = shdr.sh_addr }); |
| 190 | 192 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_STRSZ, .d_val = shdr.sh_size }); |
| 191 | 193 | } |
| 192 | 194 | |
| 193 | 195 | // VERSYM |
| 194 | 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 | 198 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERSYM, .d_val = addr }); |
| 197 | 199 | } |
| 198 | 200 | |
| 199 | 201 | // VERNEED + VERNEEDNUM |
| 200 | 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 | 204 | try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_VERNEED, .d_val = addr }); |
| 203 | 205 | try writer.writeStruct(elf.Elf64_Dyn{ |
| 204 | 206 | .d_tag = elf.DT_VERNEEDNUM, |
| ... | ... | @@ -259,7 +261,7 @@ pub const GotSection = struct { |
| 259 | 261 | |
| 260 | 262 | pub fn address(entry: Entry, elf_file: *Elf) i64 { |
| 261 | 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 | 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 | 761 | |
| 760 | 762 | const x86_64 = struct { |
| 761 | 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; | |
| 763 | const got_plt_addr = elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr; | |
| 764 | const shdrs = elf_file.sections.items(.shdr); | |
| 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 | 767 | var preamble = [_]u8{ |
| 765 | 768 | 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 |
| 766 | 769 | 0x41, 0x53, // push r11 |
| ... | ... | @@ -794,8 +797,9 @@ pub const PltSection = struct { |
| 794 | 797 | const aarch64 = struct { |
| 795 | 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); | |
| 798 | const got_plt_addr: i64 = @intCast(elf_file.shdrs.items[elf_file.got_plt_section_index.?].sh_addr); | |
| 800 | const shdrs = elf_file.sections.items(.shdr); | |
| 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 | 803 | // TODO: relax if possible |
| 800 | 804 | // .got.plt[2] |
| 801 | 805 | const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16); |
| ... | ... | @@ -869,7 +873,7 @@ pub const GotPltSection = struct { |
| 869 | 873 | try writer.writeInt(u64, 0x0, .little); |
| 870 | 874 | try writer.writeInt(u64, 0x0, .little); |
| 871 | 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 | 877 | for (0..elf_file.plt.symbols.items.len) |_| { |
| 874 | 878 | // [N]: .plt |
| 875 | 879 | try writer.writeInt(u64, plt_addr, .little); |
| ... | ... | @@ -1027,7 +1031,7 @@ pub const CopyRelSection = struct { |
| 1027 | 1031 | } |
| 1028 | 1032 | |
| 1029 | 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 | 1035 | for (copy_rel.symbols.items) |ref| { |
| 1032 | 1036 | const symbol = elf_file.symbol(ref).?; |
| 1033 | 1037 | const shared_object = symbol.file(elf_file).?.shared_object; |
| ... | ... | @@ -1487,8 +1491,12 @@ pub const ComdatGroupSection = struct { |
| 1487 | 1491 | elf.SHT_RELA => { |
| 1488 | 1492 | const atom_index = object.atoms_indexes.items[shdr.sh_info]; |
| 1489 | 1493 | const atom = object.atom(atom_index).?; |
| 1490 | const rela = elf_file.output_rela_sections.get(atom.output_section_index).?; | |
| 1491 | try writer.writeInt(u32, rela.shndx, .little); | |
| 1494 | const rela_shndx = for (elf_file.sections.items(.shdr), 0..) |rela_shdr, rela_shndx| { | |
| 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 | 1501 | else => { |
| 1494 | 1502 | const atom_index = object.atoms_indexes.items[shndx]; |
src/link/Elf/thunks.zig+3-4| ... | ... | @@ -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 | 2 | const gpa = elf_file.base.comp.gpa; |
| 3 | 3 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 4 | 4 | const max_distance = maxAllowedDistance(cpu_arch); |
| 5 | const shdr = &elf_file.shdrs.items[shndx]; | |
| 6 | const atoms = elf_file.output_sections.get(shndx).?.items; | |
| 5 | const atoms = elf_file.sections.items(.atom_list)[shndx].items; | |
| 7 | 6 | assert(atoms.len > 0); |
| 8 | 7 | |
| 9 | 8 | for (atoms) |ref| { |
| ... | ... | @@ -89,7 +88,7 @@ pub const Thunk = struct { |
| 89 | 88 | } |
| 90 | 89 | |
| 91 | 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 | 92 | return @as(i64, @intCast(shdr.sh_addr)) + thunk.value; |
| 94 | 93 | } |
| 95 | 94 |