| author | |
| committer | |
| log | 0701646beb8421464346ce6e8993394d8d2c7d5c |
| tree | f65daea499e13e7c0e97a019a404f9490a9f3115 |
| parent | 24126f5382c09f54d8344208e6e38df632d35a44 |
7 files changed, 80 insertions(+), 72 deletions(-)
src/link/Elf.zig+13-28| ... | @@ -208,9 +208,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{}, | ... | @@ -208,9 +208,6 @@ thunks: std.ArrayListUnmanaged(Thunk) = .{}, |
| 208 | 208 | ||
| 209 | /// List of output merge sections with deduped contents. | 209 | /// List of output merge sections with deduped contents. |
| 210 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .{}, | 210 | merge_sections: std.ArrayListUnmanaged(MergeSection) = .{}, |
| 211 | /// List of output merge subsections. | ||
| 212 | /// Each subsection is akin to Atom but belongs to a MergeSection. | ||
| 213 | merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{}, | ||
| 214 | 211 | ||
| 215 | /// Table of last atom index in a section and matching atom free list if any. | 212 | /// Table of last atom index in a section and matching atom free list if any. |
| 216 | last_atom_and_free_list_table: LastAtomAndFreeListTable = .{}, | 213 | last_atom_and_free_list_table: LastAtomAndFreeListTable = .{}, |
| ... | @@ -497,7 +494,6 @@ pub fn deinit(self: *Elf) void { | ... | @@ -497,7 +494,6 @@ pub fn deinit(self: *Elf) void { |
| 497 | sect.deinit(gpa); | 494 | sect.deinit(gpa); |
| 498 | } | 495 | } |
| 499 | self.merge_sections.deinit(gpa); | 496 | self.merge_sections.deinit(gpa); |
| 500 | self.merge_subsections.deinit(gpa); | ||
| 501 | for (self.last_atom_and_free_list_table.values()) |*value| { | 497 | for (self.last_atom_and_free_list_table.values()) |*value| { |
| 502 | value.free_list.deinit(gpa); | 498 | value.free_list.deinit(gpa); |
| 503 | } | 499 | } |
| ... | @@ -3288,12 +3284,13 @@ fn checkDuplicates(self: *Elf) !void { | ... | @@ -3288,12 +3284,13 @@ fn checkDuplicates(self: *Elf) !void { |
| 3288 | } | 3284 | } |
| 3289 | 3285 | ||
| 3290 | pub fn addCommentString(self: *Elf) !void { | 3286 | pub fn addCommentString(self: *Elf) !void { |
| 3287 | const gpa = self.base.comp.gpa; | ||
| 3291 | const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS); | 3288 | const msec_index = try self.getOrCreateMergeSection(".comment", elf.SHF_MERGE | elf.SHF_STRINGS, elf.SHT_PROGBITS); |
| 3292 | const msec = self.mergeSection(msec_index); | 3289 | const msec = self.mergeSection(msec_index); |
| 3293 | const res = try msec.insertZ(self.base.comp.gpa, "zig " ++ builtin.zig_version_string); | 3290 | const res = try msec.insertZ(gpa, "zig " ++ builtin.zig_version_string); |
| 3294 | if (res.found_existing) return; | 3291 | if (res.found_existing) return; |
| 3295 | const msub_index = try self.addMergeSubsection(); | 3292 | const msub_index = try msec.addMergeSubsection(gpa); |
| 3296 | const msub = self.mergeSubsection(msub_index); | 3293 | const msub = msec.mergeSubsection(msub_index); |
| 3297 | msub.merge_section_index = msec_index; | 3294 | msub.merge_section_index = msec_index; |
| 3298 | msub.string_index = res.key.pos; | 3295 | msub.string_index = res.key.pos; |
| 3299 | msub.alignment = .@"1"; | 3296 | msub.alignment = .@"1"; |
| ... | @@ -3340,8 +3337,8 @@ pub fn finalizeMergeSections(self: *Elf) !void { | ... | @@ -3340,8 +3337,8 @@ pub fn finalizeMergeSections(self: *Elf) !void { |
| 3340 | pub fn updateMergeSectionSizes(self: *Elf) !void { | 3337 | pub fn updateMergeSectionSizes(self: *Elf) !void { |
| 3341 | for (self.merge_sections.items) |*msec| { | 3338 | for (self.merge_sections.items) |*msec| { |
| 3342 | const shdr = &self.shdrs.items[msec.output_section_index]; | 3339 | const shdr = &self.shdrs.items[msec.output_section_index]; |
| 3343 | for (msec.subsections.items) |msub_index| { | 3340 | for (msec.finalized_subsections.items) |msub_index| { |
| 3344 | const msub = self.mergeSubsection(msub_index); | 3341 | const msub = msec.mergeSubsection(msub_index); |
| 3345 | assert(msub.alive); | 3342 | assert(msub.alive); |
| 3346 | const offset = msub.alignment.forward(shdr.sh_size); | 3343 | const offset = msub.alignment.forward(shdr.sh_size); |
| 3347 | const padding = offset - shdr.sh_size; | 3344 | const padding = offset - shdr.sh_size; |
| ... | @@ -3357,14 +3354,14 @@ pub fn writeMergeSections(self: *Elf) !void { | ... | @@ -3357,14 +3354,14 @@ pub fn writeMergeSections(self: *Elf) !void { |
| 3357 | var buffer = std.ArrayList(u8).init(gpa); | 3354 | var buffer = std.ArrayList(u8).init(gpa); |
| 3358 | defer buffer.deinit(); | 3355 | defer buffer.deinit(); |
| 3359 | 3356 | ||
| 3360 | for (self.merge_sections.items) |msec| { | 3357 | for (self.merge_sections.items) |*msec| { |
| 3361 | const shdr = self.shdrs.items[msec.output_section_index]; | 3358 | const shdr = self.shdrs.items[msec.output_section_index]; |
| 3362 | const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 3359 | const size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 3363 | try buffer.ensureTotalCapacity(size); | 3360 | try buffer.ensureTotalCapacity(size); |
| 3364 | buffer.appendNTimesAssumeCapacity(0, size); | 3361 | buffer.appendNTimesAssumeCapacity(0, size); |
| 3365 | 3362 | ||
| 3366 | for (msec.subsections.items) |msub_index| { | 3363 | for (msec.finalized_subsections.items) |msub_index| { |
| 3367 | const msub = self.mergeSubsection(msub_index); | 3364 | const msub = msec.mergeSubsection(msub_index); |
| 3368 | assert(msub.alive); | 3365 | assert(msub.alive); |
| 3369 | const string = msub.getString(self); | 3366 | const string = msub.getString(self); |
| 3370 | const off = math.cast(usize, msub.value) orelse return error.Overflow; | 3367 | const off = math.cast(usize, msub.value) orelse return error.Overflow; |
| ... | @@ -3384,7 +3381,7 @@ fn initOutputSections(self: *Elf) !void { | ... | @@ -3384,7 +3381,7 @@ fn initOutputSections(self: *Elf) !void { |
| 3384 | 3381 | ||
| 3385 | pub fn initMergeSections(self: *Elf) !void { | 3382 | pub fn initMergeSections(self: *Elf) !void { |
| 3386 | for (self.merge_sections.items) |*msec| { | 3383 | for (self.merge_sections.items) |*msec| { |
| 3387 | if (msec.subsections.items.len == 0) continue; | 3384 | if (msec.finalized_subsections.items.len == 0) continue; |
| 3388 | const name = msec.name(self); | 3385 | const name = msec.name(self); |
| 3389 | const shndx = self.sectionByName(name) orelse try self.addSection(.{ | 3386 | const shndx = self.sectionByName(name) orelse try self.addSection(.{ |
| 3390 | .name = name, | 3387 | .name = name, |
| ... | @@ -3393,9 +3390,9 @@ pub fn initMergeSections(self: *Elf) !void { | ... | @@ -3393,9 +3390,9 @@ pub fn initMergeSections(self: *Elf) !void { |
| 3393 | }); | 3390 | }); |
| 3394 | msec.output_section_index = shndx; | 3391 | msec.output_section_index = shndx; |
| 3395 | 3392 | ||
| 3396 | var entsize = self.mergeSubsection(msec.subsections.items[0]).entsize; | 3393 | var entsize = msec.mergeSubsection(msec.finalized_subsections.items[0]).entsize; |
| 3397 | for (msec.subsections.items) |index| { | 3394 | for (msec.finalized_subsections.items) |msub_index| { |
| 3398 | const msub = self.mergeSubsection(index); | 3395 | const msub = msec.mergeSubsection(msub_index); |
| 3399 | entsize = @min(entsize, msub.entsize); | 3396 | entsize = @min(entsize, msub.entsize); |
| 3400 | } | 3397 | } |
| 3401 | const shdr = &self.shdrs.items[shndx]; | 3398 | const shdr = &self.shdrs.items[shndx]; |
| ... | @@ -5706,18 +5703,6 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject { | ... | @@ -5706,18 +5703,6 @@ pub fn zigObjectPtr(self: *Elf) ?*ZigObject { |
| 5706 | return self.file(index).?.zig_object; | 5703 | return self.file(index).?.zig_object; |
| 5707 | } | 5704 | } |
| 5708 | 5705 | ||
| 5709 | pub fn addMergeSubsection(self: *Elf) !MergeSubsection.Index { | ||
| 5710 | const index: MergeSubsection.Index = @intCast(self.merge_subsections.items.len); | ||
| 5711 | const msec = try self.merge_subsections.addOne(self.base.comp.gpa); | ||
| 5712 | msec.* = .{}; | ||
| 5713 | return index; | ||
| 5714 | } | ||
| 5715 | |||
| 5716 | pub fn mergeSubsection(self: *Elf, index: MergeSubsection.Index) *MergeSubsection { | ||
| 5717 | assert(index < self.merge_subsections.items.len); | ||
| 5718 | return &self.merge_subsections.items[index]; | ||
| 5719 | } | ||
| 5720 | |||
| 5721 | pub fn getOrCreateMergeSection(self: *Elf, name: []const u8, flags: u64, @"type": u32) !MergeSection.Index { | 5706 | pub fn getOrCreateMergeSection(self: *Elf, name: []const u8, flags: u64, @"type": u32) !MergeSection.Index { |
| 5722 | const gpa = self.base.comp.gpa; | 5707 | const gpa = self.base.comp.gpa; |
| 5723 | const out_name = name: { | 5708 | const out_name = name: { |
src/link/Elf/LinkerDefined.zig+1-1| ... | @@ -47,7 +47,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void { | ... | @@ -47,7 +47,7 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void { |
| 47 | const global = elf_file.symbol(index); | 47 | const global = elf_file.symbol(index); |
| 48 | if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) { | 48 | if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) { |
| 49 | global.value = 0; | 49 | global.value = 0; |
| 50 | global.atom_ref = .{ .index = 0, .file = 0 }; | 50 | global.ref = .{ .index = 0, .file = 0 }; |
| 51 | global.file_index = self.index; | 51 | global.file_index = self.index; |
| 52 | global.esym_index = sym_idx; | 52 | global.esym_index = sym_idx; |
| 53 | global.version_index = elf_file.default_sym_version; | 53 | global.version_index = elf_file.default_sym_version; |
src/link/Elf/Object.zig+15-16| ... | @@ -388,7 +388,7 @@ fn initSymtab(self: *Object, allocator: Allocator, elf_file: *Elf) !void { | ... | @@ -388,7 +388,7 @@ fn initSymtab(self: *Object, allocator: Allocator, elf_file: *Elf) !void { |
| 388 | sym_ptr.esym_index = @as(u32, @intCast(i)); | 388 | sym_ptr.esym_index = @as(u32, @intCast(i)); |
| 389 | sym_ptr.file_index = self.index; | 389 | sym_ptr.file_index = self.index; |
| 390 | if (sym.st_shndx != elf.SHN_ABS) { | 390 | if (sym.st_shndx != elf.SHN_ABS) { |
| 391 | sym_ptr.atom_ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; | 391 | sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; |
| 392 | } | 392 | } |
| 393 | } | 393 | } |
| 394 | 394 | ||
| ... | @@ -575,7 +575,7 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void { | ... | @@ -575,7 +575,7 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void { |
| 575 | if (self.asFile().symbolRank(esym, !self.alive) < global.symbolRank(elf_file)) { | 575 | if (self.asFile().symbolRank(esym, !self.alive) < global.symbolRank(elf_file)) { |
| 576 | switch (esym.st_shndx) { | 576 | switch (esym.st_shndx) { |
| 577 | elf.SHN_ABS, elf.SHN_COMMON => {}, | 577 | elf.SHN_ABS, elf.SHN_COMMON => {}, |
| 578 | else => global.atom_ref = .{ | 578 | else => global.ref = .{ |
| 579 | .index = self.atoms_indexes.items[esym.st_shndx], | 579 | .index = self.atoms_indexes.items[esym.st_shndx], |
| 580 | .file = self.index, | 580 | .file = self.index, |
| 581 | }, | 581 | }, |
| ... | @@ -609,7 +609,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { | ... | @@ -609,7 +609,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { |
| 609 | }; | 609 | }; |
| 610 | 610 | ||
| 611 | global.value = 0; | 611 | global.value = 0; |
| 612 | global.atom_ref = .{ .index = 0, .file = 0 }; | 612 | global.ref = .{ .index = 0, .file = 0 }; |
| 613 | global.esym_index = esym_index; | 613 | global.esym_index = esym_index; |
| 614 | global.file_index = self.index; | 614 | global.file_index = self.index; |
| 615 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | 615 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; |
| ... | @@ -630,7 +630,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void { | ... | @@ -630,7 +630,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void { |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | global.value = 0; | 632 | global.value = 0; |
| 633 | global.atom_ref = .{ .index = 0, .file = 0 }; | 633 | global.ref = .{ .index = 0, .file = 0 }; |
| 634 | global.esym_index = esym_index; | 634 | global.esym_index = esym_index; |
| 635 | global.file_index = self.index; | 635 | global.file_index = self.index; |
| 636 | } | 636 | } |
| ... | @@ -785,8 +785,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -785,8 +785,8 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 785 | const string = imsec.bytes.items[str.pos..][0..str.len]; | 785 | const string = imsec.bytes.items[str.pos..][0..str.len]; |
| 786 | const res = try msec.insert(gpa, string); | 786 | const res = try msec.insert(gpa, string); |
| 787 | if (!res.found_existing) { | 787 | if (!res.found_existing) { |
| 788 | const msub_index = try elf_file.addMergeSubsection(); | 788 | const msub_index = try msec.addMergeSubsection(gpa); |
| 789 | const msub = elf_file.mergeSubsection(msub_index); | 789 | const msub = msec.mergeSubsection(msub_index); |
| 790 | msub.merge_section_index = imsec.merge_section_index; | 790 | msub.merge_section_index = imsec.merge_section_index; |
| 791 | msub.string_index = res.key.pos; | 791 | msub.string_index = res.key.pos; |
| 792 | msub.alignment = atom_ptr.alignment; | 792 | msub.alignment = atom_ptr.alignment; |
| ... | @@ -810,7 +810,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -810,7 +810,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 810 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; | 810 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 811 | const imsec = self.inputMergeSection(imsec_index) orelse continue; | 811 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 812 | if (imsec.offsets.items.len == 0) continue; | 812 | if (imsec.offsets.items.len == 0) continue; |
| 813 | const msub_index, const offset = imsec.findSubsection(@intCast(esym.st_value)) orelse { | 813 | const res = imsec.findSubsection(@intCast(esym.st_value)) orelse { |
| 814 | var err = try elf_file.base.addErrorWithNotes(2); | 814 | var err = try elf_file.base.addErrorWithNotes(2); |
| 815 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); | 815 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); |
| 816 | try err.addNote("for symbol {s}", .{sym.name(elf_file)}); | 816 | try err.addNote("for symbol {s}", .{sym.name(elf_file)}); |
| ... | @@ -818,9 +818,9 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -818,9 +818,9 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 818 | return error.MalformedObject; | 818 | return error.MalformedObject; |
| 819 | }; | 819 | }; |
| 820 | 820 | ||
| 821 | try sym.addExtra(.{ .subsection = msub_index }, elf_file); | 821 | sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; |
| 822 | sym.flags.merge_subsection = true; | 822 | sym.flags.merge_subsection = true; |
| 823 | sym.value = offset; | 823 | sym.value = res.offset; |
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | for (self.atoms_indexes.items) |atom_index| { | 826 | for (self.atoms_indexes.items) |atom_index| { |
| ... | @@ -835,28 +835,27 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { | ... | @@ -835,28 +835,27 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { |
| 835 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; | 835 | const imsec_index = self.input_merge_sections_indexes.items[esym.st_shndx]; |
| 836 | const imsec = self.inputMergeSection(imsec_index) orelse continue; | 836 | const imsec = self.inputMergeSection(imsec_index) orelse continue; |
| 837 | if (imsec.offsets.items.len == 0) continue; | 837 | if (imsec.offsets.items.len == 0) continue; |
| 838 | const msub_index, const offset = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { | 838 | const msec = elf_file.mergeSection(imsec.merge_section_index); |
| 839 | const res = imsec.findSubsection(@intCast(@as(i64, @intCast(esym.st_value)) + rel.r_addend)) orelse { | ||
| 839 | var err = try elf_file.base.addErrorWithNotes(1); | 840 | var err = try elf_file.base.addErrorWithNotes(1); |
| 840 | try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset}); | 841 | try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset}); |
| 841 | try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); | 842 | try err.addNote("in {}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); |
| 842 | return error.MalformedObject; | 843 | return error.MalformedObject; |
| 843 | }; | 844 | }; |
| 844 | const msub = elf_file.mergeSubsection(msub_index); | ||
| 845 | const msec = msub.mergeSection(elf_file); | ||
| 846 | 845 | ||
| 847 | const out_sym_idx: u64 = @intCast(self.symbols.items.len); | 846 | const out_sym_idx: u64 = @intCast(self.symbols.items.len); |
| 848 | try self.symbols.ensureUnusedCapacity(gpa, 1); | 847 | try self.symbols.ensureUnusedCapacity(gpa, 1); |
| 849 | const name = try std.fmt.allocPrint(gpa, "{s}$subsection{d}", .{ msec.name(elf_file), msub_index }); | 848 | const name = try std.fmt.allocPrint(gpa, "{s}$subsection{d}", .{ msec.name(elf_file), res.msub_index }); |
| 850 | defer gpa.free(name); | 849 | defer gpa.free(name); |
| 851 | const sym_index = try elf_file.addSymbol(); | 850 | const sym_index = try elf_file.addSymbol(); |
| 852 | const sym = elf_file.symbol(sym_index); | 851 | const sym = elf_file.symbol(sym_index); |
| 853 | sym.* = .{ | 852 | sym.* = .{ |
| 854 | .value = @bitCast(@as(i64, @intCast(offset)) - rel.r_addend), | 853 | .value = @bitCast(@as(i64, @intCast(res.offset)) - rel.r_addend), |
| 855 | .name_offset = try self.addString(gpa, name), | 854 | .name_offset = try self.addString(gpa, name), |
| 856 | .esym_index = rel.r_sym(), | 855 | .esym_index = rel.r_sym(), |
| 857 | .file_index = self.index, | 856 | .file_index = self.index, |
| 858 | }; | 857 | }; |
| 859 | try sym.addExtra(.{ .subsection = msub_index }, elf_file); | 858 | sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; |
| 860 | sym.flags.merge_subsection = true; | 859 | sym.flags.merge_subsection = true; |
| 861 | self.symbols.addOneAssumeCapacity().* = sym_index; | 860 | self.symbols.addOneAssumeCapacity().* = sym_index; |
| 862 | rel.r_info = (out_sym_idx << 32) | rel.r_type(); | 861 | rel.r_info = (out_sym_idx << 32) | rel.r_type(); |
| ... | @@ -920,7 +919,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { | ... | @@ -920,7 +919,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { |
| 920 | try self.atoms_indexes.append(gpa, atom_index); | 919 | try self.atoms_indexes.append(gpa, atom_index); |
| 921 | 920 | ||
| 922 | global.value = 0; | 921 | global.value = 0; |
| 923 | global.atom_ref = .{ .index = atom_index, .file = self.index }; | 922 | global.ref = .{ .index = atom_index, .file = self.index }; |
| 924 | global.flags.weak = false; | 923 | global.flags.weak = false; |
| 925 | } | 924 | } |
| 926 | } | 925 | } |
src/link/Elf/SharedObject.zig+1-1| ... | @@ -232,7 +232,7 @@ pub fn resolveSymbols(self: *SharedObject, elf_file: *Elf) void { | ... | @@ -232,7 +232,7 @@ pub fn resolveSymbols(self: *SharedObject, elf_file: *Elf) void { |
| 232 | const global = elf_file.symbol(index); | 232 | const global = elf_file.symbol(index); |
| 233 | if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) { | 233 | if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) { |
| 234 | global.value = @intCast(this_sym.st_value); | 234 | global.value = @intCast(this_sym.st_value); |
| 235 | global.atom_ref = .{ .index = 0, .file = 0 }; | 235 | global.ref = .{ .index = 0, .file = 0 }; |
| 236 | global.esym_index = esym_index; | 236 | global.esym_index = esym_index; |
| 237 | global.version_index = self.versyms.items[esym_index]; | 237 | global.version_index = self.versyms.items[esym_index]; |
| 238 | global.file_index = self.index; | 238 | global.file_index = self.index; |
src/link/Elf/Symbol.zig+9-9| ... | @@ -9,9 +9,9 @@ name_offset: u32 = 0, | ... | @@ -9,9 +9,9 @@ name_offset: u32 = 0, |
| 9 | /// Index of file where this symbol is defined. | 9 | /// Index of file where this symbol is defined. |
| 10 | file_index: File.Index = 0, | 10 | file_index: File.Index = 0, |
| 11 | 11 | ||
| 12 | /// Reference to Atom containing this symbol if any. | 12 | /// Reference to Atom or merge subsection containing this symbol if any. |
| 13 | /// Use `atom` to get the pointer to the atom. | 13 | /// Use `atom` or `mergeSubsection` to get the pointer to the atom. |
| 14 | atom_ref: Elf.Ref = .{ .index = 0, .file = 0 }, | 14 | ref: Elf.Ref = .{ .index = 0, .file = 0 }, |
| 15 | 15 | ||
| 16 | /// Assigned output section index for this symbol. | 16 | /// Assigned output section index for this symbol. |
| 17 | output_section_index: u32 = 0, | 17 | output_section_index: u32 = 0, |
| ... | @@ -71,14 +71,15 @@ pub fn name(symbol: Symbol, elf_file: *Elf) [:0]const u8 { | ... | @@ -71,14 +71,15 @@ pub fn name(symbol: Symbol, elf_file: *Elf) [:0]const u8 { |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | pub fn atom(symbol: Symbol, elf_file: *Elf) ?*Atom { | 73 | pub fn atom(symbol: Symbol, elf_file: *Elf) ?*Atom { |
| 74 | const file_ptr = elf_file.file(symbol.atom_ref.file) orelse return null; | 74 | if (symbol.flags.merge_subsection) return null; |
| 75 | return file_ptr.atom(symbol.atom_ref.index); | 75 | const file_ptr = elf_file.file(symbol.ref.file) orelse return null; |
| 76 | return file_ptr.atom(symbol.ref.index); | ||
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | pub fn mergeSubsection(symbol: Symbol, elf_file: *Elf) ?*MergeSubsection { | 79 | pub fn mergeSubsection(symbol: Symbol, elf_file: *Elf) ?*MergeSubsection { |
| 79 | if (!symbol.flags.merge_subsection) return null; | 80 | if (!symbol.flags.merge_subsection) return null; |
| 80 | const extras = symbol.extra(elf_file).?; | 81 | const msec = elf_file.mergeSection(symbol.ref.file); |
| 81 | return elf_file.mergeSubsection(extras.subsection); | 82 | return msec.mergeSubsection(symbol.ref.index); |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | pub fn file(symbol: Symbol, elf_file: *Elf) ?File { | 85 | pub fn file(symbol: Symbol, elf_file: *Elf) ?File { |
| ... | @@ -262,7 +263,6 @@ const AddExtraOpts = struct { | ... | @@ -262,7 +263,6 @@ const AddExtraOpts = struct { |
| 262 | gottp: ?u32 = null, | 263 | gottp: ?u32 = null, |
| 263 | tlsdesc: ?u32 = null, | 264 | tlsdesc: ?u32 = null, |
| 264 | zig_got: ?u32 = null, | 265 | zig_got: ?u32 = null, |
| 265 | subsection: ?u32 = null, | ||
| 266 | }; | 266 | }; |
| 267 | 267 | ||
| 268 | pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { | 268 | pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { |
| ... | @@ -488,7 +488,7 @@ pub const Extra = struct { | ... | @@ -488,7 +488,7 @@ pub const Extra = struct { |
| 488 | gottp: u32 = 0, | 488 | gottp: u32 = 0, |
| 489 | tlsdesc: u32 = 0, | 489 | tlsdesc: u32 = 0, |
| 490 | zig_got: u32 = 0, | 490 | zig_got: u32 = 0, |
| 491 | subsection: u32 = 0, | 491 | merge_section: u32 = 0, |
| 492 | }; | 492 | }; |
| 493 | 493 | ||
| 494 | pub const Index = u32; | 494 | pub const Index = u32; |
src/link/Elf/ZigObject.zig+4-4| ... | @@ -291,7 +291,7 @@ pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { | ... | @@ -291,7 +291,7 @@ pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { |
| 291 | 291 | ||
| 292 | const symbol_ptr = elf_file.symbol(symbol_index); | 292 | const symbol_ptr = elf_file.symbol(symbol_index); |
| 293 | symbol_ptr.file_index = self.index; | 293 | symbol_ptr.file_index = self.index; |
| 294 | symbol_ptr.atom_ref = .{ .index = atom_index, .file = self.index }; | 294 | symbol_ptr.ref = .{ .index = atom_index, .file = self.index }; |
| 295 | 295 | ||
| 296 | self.local_esyms.items(.shndx)[esym_index] = atom_index; | 296 | self.local_esyms.items(.shndx)[esym_index] = atom_index; |
| 297 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; | 297 | self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; |
| ... | @@ -342,7 +342,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void { | ... | @@ -342,7 +342,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void { |
| 342 | else => unreachable, | 342 | else => unreachable, |
| 343 | }; | 343 | }; |
| 344 | global.value = @intCast(esym.st_value); | 344 | global.value = @intCast(esym.st_value); |
| 345 | global.atom_ref = .{ .index = atom_index, .file = self.index }; | 345 | global.ref = .{ .index = atom_index, .file = self.index }; |
| 346 | global.esym_index = esym_index; | 346 | global.esym_index = esym_index; |
| 347 | global.file_index = self.index; | 347 | global.file_index = self.index; |
| 348 | global.version_index = elf_file.default_sym_version; | 348 | global.version_index = elf_file.default_sym_version; |
| ... | @@ -371,7 +371,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { | ... | @@ -371,7 +371,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { |
| 371 | }; | 371 | }; |
| 372 | 372 | ||
| 373 | global.value = 0; | 373 | global.value = 0; |
| 374 | global.atom_ref = .{ .index = 0, .file = 0 }; | 374 | global.ref = .{ .index = 0, .file = 0 }; |
| 375 | global.esym_index = esym_index; | 375 | global.esym_index = esym_index; |
| 376 | global.file_index = self.index; | 376 | global.file_index = self.index; |
| 377 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; | 377 | global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version; |
| ... | @@ -392,7 +392,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { | ... | @@ -392,7 +392,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | global.value = 0; | 394 | global.value = 0; |
| 395 | global.atom_ref = .{ .index = 0, .file = 0 }; | 395 | global.ref = .{ .index = 0, .file = 0 }; |
| 396 | global.esym_index = esym_index; | 396 | global.esym_index = esym_index; |
| 397 | global.file_index = self.index; | 397 | global.file_index = self.index; |
| 398 | } | 398 | } |
src/link/Elf/merge_section.zig+37-13| ... | @@ -10,12 +10,14 @@ pub const MergeSection = struct { | ... | @@ -10,12 +10,14 @@ pub const MergeSection = struct { |
| 10 | IndexContext, | 10 | IndexContext, |
| 11 | std.hash_map.default_max_load_percentage, | 11 | std.hash_map.default_max_load_percentage, |
| 12 | ) = .{}, | 12 | ) = .{}, |
| 13 | subsections: std.ArrayListUnmanaged(MergeSubsection.Index) = .{}, | 13 | subsections: std.ArrayListUnmanaged(MergeSubsection) = .{}, |
| 14 | finalized_subsections: std.ArrayListUnmanaged(MergeSubsection.Index) = .{}, | ||
| 14 | 15 | ||
| 15 | pub fn deinit(msec: *MergeSection, allocator: Allocator) void { | 16 | pub fn deinit(msec: *MergeSection, allocator: Allocator) void { |
| 16 | msec.bytes.deinit(allocator); | 17 | msec.bytes.deinit(allocator); |
| 17 | msec.table.deinit(allocator); | 18 | msec.table.deinit(allocator); |
| 18 | msec.subsections.deinit(allocator); | 19 | msec.subsections.deinit(allocator); |
| 20 | msec.finalized_subsections.deinit(allocator); | ||
| 19 | } | 21 | } |
| 20 | 22 | ||
| 21 | pub fn name(msec: MergeSection, elf_file: *Elf) [:0]const u8 { | 23 | pub fn name(msec: MergeSection, elf_file: *Elf) [:0]const u8 { |
| ... | @@ -60,23 +62,25 @@ pub const MergeSection = struct { | ... | @@ -60,23 +62,25 @@ pub const MergeSection = struct { |
| 60 | /// Sorts all owned subsections. | 62 | /// Sorts all owned subsections. |
| 61 | pub fn finalize(msec: *MergeSection, elf_file: *Elf) !void { | 63 | pub fn finalize(msec: *MergeSection, elf_file: *Elf) !void { |
| 62 | const gpa = elf_file.base.comp.gpa; | 64 | const gpa = elf_file.base.comp.gpa; |
| 63 | try msec.subsections.ensureTotalCapacityPrecise(gpa, msec.table.count()); | 65 | try msec.finalized_subsections.ensureTotalCapacityPrecise(gpa, msec.subsections.items.len); |
| 64 | 66 | ||
| 65 | var it = msec.table.iterator(); | 67 | var it = msec.table.iterator(); |
| 66 | while (it.next()) |entry| { | 68 | while (it.next()) |entry| { |
| 67 | const msub = elf_file.mergeSubsection(entry.value_ptr.*); | 69 | const msub = msec.mergeSubsection(entry.value_ptr.*); |
| 68 | if (!msub.alive) continue; | 70 | if (!msub.alive) continue; |
| 69 | msec.subsections.appendAssumeCapacity(entry.value_ptr.*); | 71 | msec.finalized_subsections.appendAssumeCapacity(entry.value_ptr.*); |
| 70 | } | 72 | } |
| 71 | msec.table.clearAndFree(gpa); | 73 | msec.table.clearAndFree(gpa); |
| 72 | 74 | ||
| 73 | const sortFn = struct { | 75 | const sortFn = struct { |
| 74 | pub fn sortFn(ctx: *Elf, lhs: MergeSubsection.Index, rhs: MergeSubsection.Index) bool { | 76 | pub fn sortFn(ctx: *MergeSection, lhs: MergeSubsection.Index, rhs: MergeSubsection.Index) bool { |
| 75 | const lhs_msub = ctx.mergeSubsection(lhs); | 77 | const lhs_msub = ctx.mergeSubsection(lhs); |
| 76 | const rhs_msub = ctx.mergeSubsection(rhs); | 78 | const rhs_msub = ctx.mergeSubsection(rhs); |
| 77 | if (lhs_msub.alignment.compareStrict(.eq, rhs_msub.alignment)) { | 79 | if (lhs_msub.alignment.compareStrict(.eq, rhs_msub.alignment)) { |
| 78 | if (lhs_msub.size == rhs_msub.size) { | 80 | if (lhs_msub.size == rhs_msub.size) { |
| 79 | return mem.order(u8, lhs_msub.getString(ctx), rhs_msub.getString(ctx)) == .lt; | 81 | const lhs_string = ctx.bytes.items[lhs_msub.string_index..][0..lhs_msub.size]; |
| 82 | const rhs_string = ctx.bytes.items[rhs_msub.string_index..][0..rhs_msub.size]; | ||
| 83 | return mem.order(u8, lhs_string, rhs_string) == .lt; | ||
| 80 | } | 84 | } |
| 81 | return lhs_msub.size < rhs_msub.size; | 85 | return lhs_msub.size < rhs_msub.size; |
| 82 | } | 86 | } |
| ... | @@ -84,7 +88,19 @@ pub const MergeSection = struct { | ... | @@ -84,7 +88,19 @@ pub const MergeSection = struct { |
| 84 | } | 88 | } |
| 85 | }.sortFn; | 89 | }.sortFn; |
| 86 | 90 | ||
| 87 | std.mem.sort(MergeSubsection.Index, msec.subsections.items, elf_file, sortFn); | 91 | std.mem.sort(MergeSubsection.Index, msec.finalized_subsections.items, msec, sortFn); |
| 92 | } | ||
| 93 | |||
| 94 | pub fn addMergeSubsection(msec: *MergeSection, allocator: Allocator) !MergeSubsection.Index { | ||
| 95 | const index: MergeSubsection.Index = @intCast(msec.subsections.items.len); | ||
| 96 | const msub = try msec.subsections.addOne(allocator); | ||
| 97 | msub.* = .{}; | ||
| 98 | return index; | ||
| 99 | } | ||
| 100 | |||
| 101 | pub fn mergeSubsection(msec: *MergeSection, index: MergeSubsection.Index) *MergeSubsection { | ||
| 102 | assert(index < msec.subsections.items.len); | ||
| 103 | return &msec.subsections.items[index]; | ||
| 88 | } | 104 | } |
| 89 | 105 | ||
| 90 | pub const IndexContext = struct { | 106 | pub const IndexContext = struct { |
| ... | @@ -154,8 +170,8 @@ pub const MergeSection = struct { | ... | @@ -154,8 +170,8 @@ pub const MergeSection = struct { |
| 154 | msec.type, | 170 | msec.type, |
| 155 | msec.flags, | 171 | msec.flags, |
| 156 | }); | 172 | }); |
| 157 | for (msec.subsections.items) |index| { | 173 | for (msec.subsections.items) |msub| { |
| 158 | try writer.print(" {}\n", .{elf_file.mergeSubsection(index).fmt(elf_file)}); | 174 | try writer.print(" {}\n", .{msub.fmt(elf_file)}); |
| 159 | } | 175 | } |
| 160 | } | 176 | } |
| 161 | 177 | ||
| ... | @@ -250,18 +266,26 @@ pub const InputMergeSection = struct { | ... | @@ -250,18 +266,26 @@ pub const InputMergeSection = struct { |
| 250 | // TODO: imsec.strings.clearAndFree(allocator); | 266 | // TODO: imsec.strings.clearAndFree(allocator); |
| 251 | } | 267 | } |
| 252 | 268 | ||
| 253 | pub fn findSubsection(imsec: InputMergeSection, offset: u32) ?struct { MergeSubsection.Index, u32 } { | 269 | const FindSubsectionResult = struct { |
| 270 | msub_index: MergeSubsection.Index, | ||
| 271 | offset: u32, | ||
| 272 | }; | ||
| 273 | |||
| 274 | pub fn findSubsection(imsec: InputMergeSection, offset: u32) ?FindSubsectionResult { | ||
| 254 | // TODO: binary search | 275 | // TODO: binary search |
| 255 | for (imsec.offsets.items, 0..) |off, index| { | 276 | for (imsec.offsets.items, 0..) |off, index| { |
| 256 | if (offset < off) return .{ | 277 | if (offset < off) return .{ |
| 257 | imsec.subsections.items[index - 1], | 278 | .msub_index = imsec.subsections.items[index - 1], |
| 258 | offset - imsec.offsets.items[index - 1], | 279 | .offset = offset - imsec.offsets.items[index - 1], |
| 259 | }; | 280 | }; |
| 260 | } | 281 | } |
| 261 | const last = imsec.offsets.items.len - 1; | 282 | const last = imsec.offsets.items.len - 1; |
| 262 | const last_off = imsec.offsets.items[last]; | 283 | const last_off = imsec.offsets.items[last]; |
| 263 | const last_len = imsec.strings.items[last].len; | 284 | const last_len = imsec.strings.items[last].len; |
| 264 | if (offset < last_off + last_len) return .{ imsec.subsections.items[last], offset - last_off }; | 285 | if (offset < last_off + last_len) return .{ |
| 286 | .msub_index = imsec.subsections.items[last], | ||
| 287 | .offset = offset - last_off, | ||
| 288 | }; | ||
| 265 | return null; | 289 | return null; |
| 266 | } | 290 | } |
| 267 | 291 |