| author | |
| committer | |
| log | 3f5593205dd687e9c637d7c34bd05b3ba53c2312 |
| tree | 7ccf8c6c1014412fed368f2c245f7404c5214b1b |
| parent | 5f925582909916b3843323c77b2edc05acc3f172 |
| parent | 216a5594f62aca7524012e0a2bbf226c4064fae4 |
| signature |
elf: store relative offsets in atom and symbol8 files changed, 139 insertions(+), 156 deletions(-)
src/link/Elf.zig+60-70| ... | ... | @@ -138,40 +138,40 @@ comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, |
| 138 | 138 | |
| 139 | 139 | /// Tracked section headers with incremental updates to Zig object. |
| 140 | 140 | /// .rela.* sections are only used when emitting a relocatable object file. |
| 141 | zig_text_section_index: ?u16 = null, | |
| 142 | zig_data_rel_ro_section_index: ?u16 = null, | |
| 143 | zig_data_section_index: ?u16 = null, | |
| 144 | zig_bss_section_index: ?u16 = null, | |
| 145 | zig_got_section_index: ?u16 = null, | |
| 146 | ||
| 147 | debug_info_section_index: ?u16 = null, | |
| 148 | debug_abbrev_section_index: ?u16 = null, | |
| 149 | debug_str_section_index: ?u16 = null, | |
| 150 | debug_aranges_section_index: ?u16 = null, | |
| 151 | debug_line_section_index: ?u16 = null, | |
| 152 | ||
| 153 | copy_rel_section_index: ?u16 = null, | |
| 154 | dynamic_section_index: ?u16 = null, | |
| 155 | dynstrtab_section_index: ?u16 = null, | |
| 156 | dynsymtab_section_index: ?u16 = null, | |
| 157 | eh_frame_section_index: ?u16 = null, | |
| 158 | eh_frame_rela_section_index: ?u16 = null, | |
| 159 | eh_frame_hdr_section_index: ?u16 = null, | |
| 160 | hash_section_index: ?u16 = null, | |
| 161 | gnu_hash_section_index: ?u16 = null, | |
| 162 | got_section_index: ?u16 = null, | |
| 163 | got_plt_section_index: ?u16 = null, | |
| 164 | interp_section_index: ?u16 = null, | |
| 165 | plt_section_index: ?u16 = null, | |
| 166 | plt_got_section_index: ?u16 = null, | |
| 167 | rela_dyn_section_index: ?u16 = null, | |
| 168 | rela_plt_section_index: ?u16 = null, | |
| 169 | versym_section_index: ?u16 = null, | |
| 170 | verneed_section_index: ?u16 = null, | |
| 171 | ||
| 172 | shstrtab_section_index: ?u16 = null, | |
| 173 | strtab_section_index: ?u16 = null, | |
| 174 | symtab_section_index: ?u16 = null, | |
| 141 | zig_text_section_index: ?u32 = null, | |
| 142 | zig_data_rel_ro_section_index: ?u32 = null, | |
| 143 | zig_data_section_index: ?u32 = null, | |
| 144 | zig_bss_section_index: ?u32 = null, | |
| 145 | zig_got_section_index: ?u32 = null, | |
| 146 | ||
| 147 | debug_info_section_index: ?u32 = null, | |
| 148 | debug_abbrev_section_index: ?u32 = null, | |
| 149 | debug_str_section_index: ?u32 = null, | |
| 150 | debug_aranges_section_index: ?u32 = null, | |
| 151 | debug_line_section_index: ?u32 = null, | |
| 152 | ||
| 153 | copy_rel_section_index: ?u32 = null, | |
| 154 | dynamic_section_index: ?u32 = null, | |
| 155 | dynstrtab_section_index: ?u32 = null, | |
| 156 | dynsymtab_section_index: ?u32 = null, | |
| 157 | eh_frame_section_index: ?u32 = null, | |
| 158 | eh_frame_rela_section_index: ?u32 = null, | |
| 159 | eh_frame_hdr_section_index: ?u32 = null, | |
| 160 | hash_section_index: ?u32 = null, | |
| 161 | gnu_hash_section_index: ?u32 = null, | |
| 162 | got_section_index: ?u32 = null, | |
| 163 | got_plt_section_index: ?u32 = null, | |
| 164 | interp_section_index: ?u32 = null, | |
| 165 | plt_section_index: ?u32 = null, | |
| 166 | plt_got_section_index: ?u32 = null, | |
| 167 | rela_dyn_section_index: ?u32 = null, | |
| 168 | rela_plt_section_index: ?u32 = null, | |
| 169 | versym_section_index: ?u32 = null, | |
| 170 | verneed_section_index: ?u32 = null, | |
| 171 | ||
| 172 | shstrtab_section_index: ?u32 = null, | |
| 173 | strtab_section_index: ?u32 = null, | |
| 174 | symtab_section_index: ?u32 = null, | |
| 175 | 175 | |
| 176 | 176 | // Linker-defined symbols |
| 177 | 177 | dynamic_index: ?Symbol.Index = null, |
| ... | ... | @@ -931,7 +931,7 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 931 | 931 | try self.base.file.?.pwriteAll(&[1]u8{0}, end_pos); |
| 932 | 932 | } |
| 933 | 933 | |
| 934 | pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { | |
| 934 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | |
| 935 | 935 | const shdr = &self.shdrs.items[shdr_index]; |
| 936 | 936 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; |
| 937 | 937 | const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; |
| ... | ... | @@ -981,7 +981,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 981 | 981 | |
| 982 | 982 | pub fn growNonAllocSection( |
| 983 | 983 | self: *Elf, |
| 984 | shdr_index: u16, | |
| 984 | shdr_index: u32, | |
| 985 | 985 | needed_size: u64, |
| 986 | 986 | min_alignment: u32, |
| 987 | 987 | requires_file_copy: bool, |
| ... | ... | @@ -1018,7 +1018,7 @@ pub fn growNonAllocSection( |
| 1018 | 1018 | self.markDirty(shdr_index); |
| 1019 | 1019 | } |
| 1020 | 1020 | |
| 1021 | pub fn markDirty(self: *Elf, shdr_index: u16) void { | |
| 1021 | pub fn markDirty(self: *Elf, shdr_index: u32) void { | |
| 1022 | 1022 | const zig_object = self.zigObjectPtr().?; |
| 1023 | 1023 | if (zig_object.dwarf) |_| { |
| 1024 | 1024 | if (self.debug_info_section_index.? == shdr_index) { |
| ... | ... | @@ -1332,7 +1332,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) |
| 1332 | 1332 | try self.sortPhdrs(); |
| 1333 | 1333 | try self.allocateNonAllocSections(); |
| 1334 | 1334 | self.allocateSpecialPhdrs(); |
| 1335 | self.allocateAtoms(); | |
| 1336 | 1335 | self.allocateLinkerDefinedSymbols(); |
| 1337 | 1336 | |
| 1338 | 1337 | // Dump the state for easy debugging. |
| ... | ... | @@ -1352,7 +1351,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) |
| 1352 | 1351 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1353 | 1352 | const code = try zig_object.codeAlloc(self, atom_index); |
| 1354 | 1353 | defer gpa.free(code); |
| 1355 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 1354 | const file_offset = shdr.sh_offset + atom_ptr.value; | |
| 1356 | 1355 | atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { |
| 1357 | 1356 | // TODO |
| 1358 | 1357 | error.RelaxFail, error.InvalidInstruction, error.CannotEncode => { |
| ... | ... | @@ -2907,7 +2906,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2907 | 2906 | mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian); |
| 2908 | 2907 | index += 4; |
| 2909 | 2908 | |
| 2910 | const e_entry = if (self.entry_index) |entry_index| self.symbol(entry_index).value else 0; | |
| 2909 | const e_entry = if (self.entry_index) |entry_index| self.symbol(entry_index).address(.{}, self) else 0; | |
| 2911 | 2910 | const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0; |
| 2912 | 2911 | switch (self.ptr_width) { |
| 2913 | 2912 | .p32 => { |
| ... | ... | @@ -2970,7 +2969,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2970 | 2969 | mem.writeInt(u16, hdr_buf[index..][0..2], e_shnum, endian); |
| 2971 | 2970 | index += 2; |
| 2972 | 2971 | |
| 2973 | mem.writeInt(u16, hdr_buf[index..][0..2], self.shstrtab_section_index.?, endian); | |
| 2972 | mem.writeInt(u16, hdr_buf[index..][0..2], @intCast(self.shstrtab_section_index.?), endian); | |
| 2974 | 2973 | index += 2; |
| 2975 | 2974 | |
| 2976 | 2975 | assert(index == e_ehsize); |
| ... | ... | @@ -3710,7 +3709,7 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 3710 | 3709 | } |
| 3711 | 3710 | } |
| 3712 | 3711 | |
| 3713 | fn shdrRank(self: *Elf, shndx: u16) u8 { | |
| 3712 | fn shdrRank(self: *Elf, shndx: u32) u8 { | |
| 3714 | 3713 | const shdr = self.shdrs.items[shndx]; |
| 3715 | 3714 | const name = self.getShString(shdr.sh_name); |
| 3716 | 3715 | const flags = shdr.sh_flags; |
| ... | ... | @@ -3760,7 +3759,7 @@ fn shdrRank(self: *Elf, shndx: u16) u8 { |
| 3760 | 3759 | |
| 3761 | 3760 | pub fn sortShdrs(self: *Elf) !void { |
| 3762 | 3761 | const Entry = struct { |
| 3763 | shndx: u16, | |
| 3762 | shndx: u32, | |
| 3764 | 3763 | |
| 3765 | 3764 | pub fn lessThan(elf_file: *Elf, lhs: @This(), rhs: @This()) bool { |
| 3766 | 3765 | return elf_file.shdrRank(lhs.shndx) < elf_file.shdrRank(rhs.shndx); |
| ... | ... | @@ -3771,15 +3770,15 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3771 | 3770 | var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len); |
| 3772 | 3771 | defer entries.deinit(); |
| 3773 | 3772 | for (0..self.shdrs.items.len) |shndx| { |
| 3774 | entries.appendAssumeCapacity(.{ .shndx = @as(u16, @intCast(shndx)) }); | |
| 3773 | entries.appendAssumeCapacity(.{ .shndx = @intCast(shndx) }); | |
| 3775 | 3774 | } |
| 3776 | 3775 | |
| 3777 | 3776 | mem.sort(Entry, entries.items, self, Entry.lessThan); |
| 3778 | 3777 | |
| 3779 | const backlinks = try gpa.alloc(u16, entries.items.len); | |
| 3778 | const backlinks = try gpa.alloc(u32, entries.items.len); | |
| 3780 | 3779 | defer gpa.free(backlinks); |
| 3781 | 3780 | for (entries.items, 0..) |entry, i| { |
| 3782 | backlinks[entry.shndx] = @as(u16, @intCast(i)); | |
| 3781 | backlinks[entry.shndx] = @intCast(i); | |
| 3783 | 3782 | } |
| 3784 | 3783 | |
| 3785 | 3784 | const slice = try self.shdrs.toOwnedSlice(gpa); |
| ... | ... | @@ -3793,10 +3792,10 @@ pub fn sortShdrs(self: *Elf) !void { |
| 3793 | 3792 | try self.resetShdrIndexes(backlinks); |
| 3794 | 3793 | } |
| 3795 | 3794 | |
| 3796 | fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void { | |
| 3795 | fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | |
| 3797 | 3796 | const gpa = self.base.comp.gpa; |
| 3798 | 3797 | |
| 3799 | for (&[_]*?u16{ | |
| 3798 | for (&[_]*?u32{ | |
| 3800 | 3799 | &self.eh_frame_section_index, |
| 3801 | 3800 | &self.eh_frame_rela_section_index, |
| 3802 | 3801 | &self.eh_frame_hdr_section_index, |
| ... | ... | @@ -4192,7 +4191,7 @@ pub fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4192 | 4191 | // virtual and file offsets. However, the simple one will do for one |
| 4193 | 4192 | // as we are more interested in quick turnaround and compatibility |
| 4194 | 4193 | // with `findFreeSpace` mechanics than anything else. |
| 4195 | const Cover = std.ArrayList(u16); | |
| 4194 | const Cover = std.ArrayList(u32); | |
| 4196 | 4195 | const gpa = self.base.comp.gpa; |
| 4197 | 4196 | var covers: [max_number_of_object_segments]Cover = undefined; |
| 4198 | 4197 | for (&covers) |*cover| { |
| ... | ... | @@ -4348,7 +4347,7 @@ pub fn allocateNonAllocSections(self: *Elf) !void { |
| 4348 | 4347 | } |
| 4349 | 4348 | |
| 4350 | 4349 | fn allocateSpecialPhdrs(self: *Elf) void { |
| 4351 | for (&[_]struct { ?u16, ?u16 }{ | |
| 4350 | for (&[_]struct { ?u16, ?u32 }{ | |
| 4352 | 4351 | .{ self.phdr_interp_index, self.interp_section_index }, |
| 4353 | 4352 | .{ self.phdr_dynamic_index, self.dynamic_section_index }, |
| 4354 | 4353 | .{ self.phdr_gnu_eh_frame_index, self.eh_frame_hdr_section_index }, |
| ... | ... | @@ -4371,7 +4370,7 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 4371 | 4370 | if (self.phdr_tls_index) |index| { |
| 4372 | 4371 | const slice = self.shdrs.items; |
| 4373 | 4372 | const phdr = &self.phdrs.items[index]; |
| 4374 | var shndx: u16 = 0; | |
| 4373 | var shndx: u32 = 0; | |
| 4375 | 4374 | while (shndx < slice.len) { |
| 4376 | 4375 | const shdr = slice[shndx]; |
| 4377 | 4376 | if (shdr.sh_flags & elf.SHF_TLS == 0) { |
| ... | ... | @@ -4402,15 +4401,6 @@ fn allocateSpecialPhdrs(self: *Elf) void { |
| 4402 | 4401 | } |
| 4403 | 4402 | } |
| 4404 | 4403 | |
| 4405 | pub fn allocateAtoms(self: *Elf) void { | |
| 4406 | if (self.zigObjectPtr()) |zig_object| { | |
| 4407 | zig_object.allocateTlvAtoms(self); | |
| 4408 | } | |
| 4409 | for (self.objects.items) |index| { | |
| 4410 | self.file(index).?.object.allocateAtoms(self); | |
| 4411 | } | |
| 4412 | } | |
| 4413 | ||
| 4414 | 4404 | fn writeAtoms(self: *Elf) !void { |
| 4415 | 4405 | const gpa = self.base.comp.gpa; |
| 4416 | 4406 | |
| ... | ... | @@ -4464,7 +4454,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4464 | 4454 | const atom_ptr = self.atom(atom_index).?; |
| 4465 | 4455 | assert(atom_ptr.flags.alive); |
| 4466 | 4456 | |
| 4467 | const offset = math.cast(usize, atom_ptr.value - shdr.sh_addr - base_offset) orelse | |
| 4457 | const offset = math.cast(usize, atom_ptr.value - base_offset) orelse | |
| 4468 | 4458 | return error.Overflow; |
| 4469 | 4459 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 4470 | 4460 | |
| ... | ... | @@ -5148,8 +5138,8 @@ const CsuObjects = struct { |
| 5148 | 5138 | } |
| 5149 | 5139 | }; |
| 5150 | 5140 | |
| 5151 | pub fn isZigSection(self: Elf, shndx: u16) bool { | |
| 5152 | inline for (&[_]?u16{ | |
| 5141 | pub fn isZigSection(self: Elf, shndx: u32) bool { | |
| 5142 | inline for (&[_]?u32{ | |
| 5153 | 5143 | self.zig_text_section_index, |
| 5154 | 5144 | self.zig_data_rel_ro_section_index, |
| 5155 | 5145 | self.zig_data_section_index, |
| ... | ... | @@ -5163,8 +5153,8 @@ pub fn isZigSection(self: Elf, shndx: u16) bool { |
| 5163 | 5153 | return false; |
| 5164 | 5154 | } |
| 5165 | 5155 | |
| 5166 | pub fn isDebugSection(self: Elf, shndx: u16) bool { | |
| 5167 | inline for (&[_]?u16{ | |
| 5156 | pub fn isDebugSection(self: Elf, shndx: u32) bool { | |
| 5157 | inline for (&[_]?u32{ | |
| 5168 | 5158 | self.debug_info_section_index, |
| 5169 | 5159 | self.debug_abbrev_section_index, |
| 5170 | 5160 | self.debug_str_section_index, |
| ... | ... | @@ -5202,7 +5192,7 @@ fn addPhdr(self: *Elf, opts: struct { |
| 5202 | 5192 | return index; |
| 5203 | 5193 | } |
| 5204 | 5194 | |
| 5205 | pub fn addRelaShdr(self: *Elf, name: [:0]const u8, shndx: u16) !u16 { | |
| 5195 | pub fn addRelaShdr(self: *Elf, name: [:0]const u8, shndx: u32) !u32 { | |
| 5206 | 5196 | const entsize: u64 = switch (self.ptr_width) { |
| 5207 | 5197 | .p32 => @sizeOf(elf.Elf32_Rela), |
| 5208 | 5198 | .p64 => @sizeOf(elf.Elf64_Rela), |
| ... | ... | @@ -5233,9 +5223,9 @@ pub const AddSectionOpts = struct { |
| 5233 | 5223 | offset: u64 = 0, |
| 5234 | 5224 | }; |
| 5235 | 5225 | |
| 5236 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { | |
| 5226 | pub fn addSection(self: *Elf, opts: AddSectionOpts) !u32 { | |
| 5237 | 5227 | const gpa = self.base.comp.gpa; |
| 5238 | const index = @as(u16, @intCast(self.shdrs.items.len)); | |
| 5228 | const index = @as(u32, @intCast(self.shdrs.items.len)); | |
| 5239 | 5229 | const shdr = try self.shdrs.addOne(gpa); |
| 5240 | 5230 | shdr.* = .{ |
| 5241 | 5231 | .sh_name = try self.insertShString(opts.name), |
| ... | ... | @@ -5252,10 +5242,10 @@ pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 { |
| 5252 | 5242 | return index; |
| 5253 | 5243 | } |
| 5254 | 5244 | |
| 5255 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 { | |
| 5245 | pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u32 { | |
| 5256 | 5246 | for (self.shdrs.items, 0..) |*shdr, i| { |
| 5257 | 5247 | const this_name = self.getShString(shdr.sh_name); |
| 5258 | if (mem.eql(u8, this_name, name)) return @as(u16, @intCast(i)); | |
| 5248 | if (mem.eql(u8, this_name, name)) return @intCast(i); | |
| 5259 | 5249 | } else return null; |
| 5260 | 5250 | } |
| 5261 | 5251 |
src/link/Elf/Atom.zig+26-17| ... | ... | @@ -17,7 +17,7 @@ alignment: Alignment = .@"1", |
| 17 | 17 | input_section_index: u32 = 0, |
| 18 | 18 | |
| 19 | 19 | /// Index of the output section. |
| 20 | output_section_index: u16 = 0, | |
| 20 | output_section_index: u32 = 0, | |
| 21 | 21 | |
| 22 | 22 | /// Index of the input section containing this atom's relocs. |
| 23 | 23 | relocs_section_index: u32 = 0, |
| ... | ... | @@ -54,6 +54,12 @@ pub fn name(self: Atom, elf_file: *Elf) []const u8 { |
| 54 | 54 | }; |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | pub fn address(self: Atom, elf_file: *Elf) u64 { | |
| 58 | const shndx = self.outputShndx() orelse return self.value; | |
| 59 | const shdr = elf_file.shdrs.items[shndx]; | |
| 60 | return shdr.sh_addr + self.value; | |
| 61 | } | |
| 62 | ||
| 57 | 63 | pub fn file(self: Atom, elf_file: *Elf) ?File { |
| 58 | 64 | return elf_file.file(self.file_index); |
| 59 | 65 | } |
| ... | ... | @@ -71,7 +77,7 @@ pub fn relocsShndx(self: Atom) ?u32 { |
| 71 | 77 | return self.relocs_section_index; |
| 72 | 78 | } |
| 73 | 79 | |
| 74 | pub fn outputShndx(self: Atom) ?u16 { | |
| 80 | pub fn outputShndx(self: Atom) ?u32 { | |
| 75 | 81 | if (self.output_section_index == 0) return null; |
| 76 | 82 | return self.output_section_index; |
| 77 | 83 | } |
| ... | ... | @@ -85,14 +91,17 @@ pub fn priority(self: Atom, elf_file: *Elf) u64 { |
| 85 | 91 | /// File offset relocation happens transparently, so it is not included in |
| 86 | 92 | /// this calculation. |
| 87 | 93 | pub fn capacity(self: Atom, elf_file: *Elf) u64 { |
| 88 | const next_value = if (elf_file.atom(self.next_index)) |next| next.value else std.math.maxInt(u32); | |
| 89 | return next_value - self.value; | |
| 94 | const next_addr = if (elf_file.atom(self.next_index)) |next| | |
| 95 | next.address(elf_file) | |
| 96 | else | |
| 97 | std.math.maxInt(u32); | |
| 98 | return next_addr - self.address(elf_file); | |
| 90 | 99 | } |
| 91 | 100 | |
| 92 | 101 | pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { |
| 93 | 102 | // No need to keep a free list node for the last block. |
| 94 | 103 | const next = elf_file.atom(self.next_index) orelse return false; |
| 95 | const cap = next.value - self.value; | |
| 104 | const cap = next.address(elf_file) - self.address(elf_file); | |
| 96 | 105 | const ideal_cap = Elf.padToIdeal(self.size); |
| 97 | 106 | if (cap <= ideal_cap) return false; |
| 98 | 107 | const surplus = cap - ideal_cap; |
| ... | ... | @@ -160,15 +169,15 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 160 | 169 | atom_placement = last.atom_index; |
| 161 | 170 | break :blk new_start_vaddr; |
| 162 | 171 | } else { |
| 163 | break :blk shdr.sh_addr; | |
| 172 | break :blk 0; | |
| 164 | 173 | } |
| 165 | 174 | }; |
| 166 | 175 | |
| 167 | 176 | log.debug("allocated atom({d}) : '{s}' at 0x{x} to 0x{x}", .{ |
| 168 | 177 | self.atom_index, |
| 169 | 178 | self.name(elf_file), |
| 170 | self.value, | |
| 171 | self.value + self.size, | |
| 179 | self.address(elf_file), | |
| 180 | self.address(elf_file) + self.size, | |
| 172 | 181 | }); |
| 173 | 182 | |
| 174 | 183 | const expand_section = if (atom_placement) |placement_index| |
| ... | ... | @@ -176,7 +185,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 176 | 185 | else |
| 177 | 186 | true; |
| 178 | 187 | if (expand_section) { |
| 179 | const needed_size = (self.value + self.size) - shdr.sh_addr; | |
| 188 | const needed_size = self.value + self.size; | |
| 180 | 189 | try elf_file.growAllocSection(self.outputShndx().?, needed_size); |
| 181 | 190 | last_atom_index.* = self.atom_index; |
| 182 | 191 | |
| ... | ... | @@ -301,7 +310,7 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 301 | 310 | } |
| 302 | 311 | |
| 303 | 312 | pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void { |
| 304 | relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) }); | |
| 313 | relocs_log.debug("0x{x}: {s}", .{ self.address(elf_file), self.name(elf_file) }); | |
| 305 | 314 | |
| 306 | 315 | const file_ptr = self.file(elf_file).?; |
| 307 | 316 | for (self.relocs(elf_file)) |rel| { |
| ... | ... | @@ -322,7 +331,7 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El |
| 322 | 331 | var r_sym: u32 = 0; |
| 323 | 332 | switch (target.type(elf_file)) { |
| 324 | 333 | elf.STT_SECTION => { |
| 325 | r_addend += @intCast(target.value); | |
| 334 | r_addend += @intCast(target.address(.{}, elf_file)); | |
| 326 | 335 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(target.outputShndx().?); |
| 327 | 336 | }, |
| 328 | 337 | else => { |
| ... | ... | @@ -778,7 +787,7 @@ fn reportUndefined( |
| 778 | 787 | } |
| 779 | 788 | |
| 780 | 789 | pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 781 | relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) }); | |
| 790 | relocs_log.debug("0x{x}: {s}", .{ self.address(elf_file), self.name(elf_file) }); | |
| 782 | 791 | |
| 783 | 792 | const file_ptr = self.file(elf_file).?; |
| 784 | 793 | var stream = std.io.fixedBufferStream(code); |
| ... | ... | @@ -802,7 +811,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 802 | 811 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ |
| 803 | 812 | // |
| 804 | 813 | // Address of the source atom. |
| 805 | const P = @as(i64, @intCast(self.value + rel.r_offset)); | |
| 814 | const P = @as(i64, @intCast(self.address(elf_file) + rel.r_offset)); | |
| 806 | 815 | // Addend from the relocation. |
| 807 | 816 | const A = rel.r_addend; |
| 808 | 817 | // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. |
| ... | ... | @@ -969,7 +978,7 @@ fn resolveDynAbsReloc( |
| 969 | 978 | ) !void { |
| 970 | 979 | const comp = elf_file.base.comp; |
| 971 | 980 | const gpa = comp.gpa; |
| 972 | const P = self.value + rel.r_offset; | |
| 981 | const P = self.address(elf_file) + rel.r_offset; | |
| 973 | 982 | const A = rel.r_addend; |
| 974 | 983 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); |
| 975 | 984 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; |
| ... | ... | @@ -1058,7 +1067,7 @@ fn applyDynamicReloc(value: i64, elf_file: *Elf, writer: anytype) !void { |
| 1058 | 1067 | } |
| 1059 | 1068 | |
| 1060 | 1069 | pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: anytype) !void { |
| 1061 | relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) }); | |
| 1070 | relocs_log.debug("0x{x}: {s}", .{ self.address(elf_file), self.name(elf_file) }); | |
| 1062 | 1071 | |
| 1063 | 1072 | const file_ptr = self.file(elf_file).?; |
| 1064 | 1073 | var stream = std.io.fixedBufferStream(code); |
| ... | ... | @@ -1097,7 +1106,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 1097 | 1106 | // We will use equation format to resolve relocations: |
| 1098 | 1107 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ |
| 1099 | 1108 | // |
| 1100 | const P = @as(i64, @intCast(self.value + rel.r_offset)); | |
| 1109 | const P = @as(i64, @intCast(self.address(elf_file) + rel.r_offset)); | |
| 1101 | 1110 | // Addend from the relocation. |
| 1102 | 1111 | const A = rel.r_addend; |
| 1103 | 1112 | // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. |
| ... | ... | @@ -1248,7 +1257,7 @@ fn format2( |
| 1248 | 1257 | const atom = ctx.atom; |
| 1249 | 1258 | const elf_file = ctx.elf_file; |
| 1250 | 1259 | try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x})", .{ |
| 1251 | atom.atom_index, atom.name(elf_file), atom.value, | |
| 1260 | atom.atom_index, atom.name(elf_file), atom.address(elf_file), | |
| 1252 | 1261 | atom.output_section_index, atom.alignment, atom.size, |
| 1253 | 1262 | }); |
| 1254 | 1263 | if (atom.fde_start != atom.fde_end) { |
src/link/Elf/Object.zig+5-16| ... | ... | @@ -126,7 +126,7 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil |
| 126 | 126 | try self.strtab.appendSlice(allocator, shstrtab); |
| 127 | 127 | |
| 128 | 128 | const symtab_index = for (self.shdrs.items, 0..) |shdr, i| switch (shdr.sh_type) { |
| 129 | elf.SHT_SYMTAB => break @as(u16, @intCast(i)), | |
| 129 | elf.SHT_SYMTAB => break @as(u32, @intCast(i)), | |
| 130 | 130 | else => {}, |
| 131 | 131 | } else null; |
| 132 | 132 | |
| ... | ... | @@ -223,7 +223,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: |
| 223 | 223 | => {}, |
| 224 | 224 | |
| 225 | 225 | else => { |
| 226 | const shndx = @as(u16, @intCast(i)); | |
| 226 | const shndx = @as(u32, @intCast(i)); | |
| 227 | 227 | if (self.skipShdr(shndx, elf_file)) continue; |
| 228 | 228 | try self.addAtom(allocator, handle, shdr, shndx, elf_file); |
| 229 | 229 | }, |
| ... | ... | @@ -268,7 +268,7 @@ fn addAtom(self: *Object, allocator: Allocator, handle: std.fs.File, shdr: elf.E |
| 268 | 268 | } |
| 269 | 269 | } |
| 270 | 270 | |
| 271 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u16 { | |
| 271 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{OutOfMemory}!u32 { | |
| 272 | 272 | const name = blk: { |
| 273 | 273 | const name = self.getString(shdr.sh_name); |
| 274 | 274 | if (elf_file.base.isRelocatable()) break :blk name; |
| ... | ... | @@ -316,7 +316,7 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) error{O |
| 316 | 316 | return out_shndx; |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { | |
| 319 | fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool { | |
| 320 | 320 | const comp = elf_file.base.comp; |
| 321 | 321 | const shdr = self.shdrs.items[index]; |
| 322 | 322 | const name = self.getString(shdr.sh_name); |
| ... | ... | @@ -673,7 +673,7 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void { |
| 673 | 673 | |
| 674 | 674 | var sh_flags: u32 = elf.SHF_ALLOC | elf.SHF_WRITE; |
| 675 | 675 | if (is_tls) sh_flags |= elf.SHF_TLS; |
| 676 | const shndx = @as(u16, @intCast(self.shdrs.items.len)); | |
| 676 | const shndx = @as(u32, @intCast(self.shdrs.items.len)); | |
| 677 | 677 | const shdr = try self.shdrs.addOne(gpa); |
| 678 | 678 | const sh_size = math.cast(usize, this_sym.st_size) orelse return error.Overflow; |
| 679 | 679 | shdr.* = .{ |
| ... | ... | @@ -718,21 +718,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { |
| 718 | 718 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 719 | 719 | try gop.value_ptr.append(gpa, atom_index); |
| 720 | 720 | } |
| 721 | } | |
| 722 | ||
| 723 | pub fn allocateAtoms(self: Object, elf_file: *Elf) void { | |
| 724 | for (self.atoms.items) |atom_index| { | |
| 725 | const atom = elf_file.atom(atom_index) orelse continue; | |
| 726 | if (!atom.flags.alive) continue; | |
| 727 | const shdr = elf_file.shdrs.items[atom.output_section_index]; | |
| 728 | atom.value += shdr.sh_addr; | |
| 729 | } | |
| 730 | 721 | |
| 731 | 722 | for (self.locals()) |local_index| { |
| 732 | 723 | const local = elf_file.symbol(local_index); |
| 733 | 724 | const atom = local.atom(elf_file) orelse continue; |
| 734 | 725 | if (!atom.flags.alive) continue; |
| 735 | local.value += atom.value; | |
| 736 | 726 | local.output_section_index = atom.output_section_index; |
| 737 | 727 | } |
| 738 | 728 | |
| ... | ... | @@ -741,7 +731,6 @@ pub fn allocateAtoms(self: Object, elf_file: *Elf) void { |
| 741 | 731 | const atom = global.atom(elf_file) orelse continue; |
| 742 | 732 | if (!atom.flags.alive) continue; |
| 743 | 733 | if (global.file(elf_file).?.index() != self.index) continue; |
| 744 | global.value += atom.value; | |
| 745 | 734 | global.output_section_index = atom.output_section_index; |
| 746 | 735 | } |
| 747 | 736 | } |
src/link/Elf/Symbol.zig+16-9| ... | ... | @@ -15,7 +15,7 @@ file_index: File.Index = 0, |
| 15 | 15 | atom_index: Atom.Index = 0, |
| 16 | 16 | |
| 17 | 17 | /// Assigned output section index for this atom. |
| 18 | output_section_index: u16 = 0, | |
| 18 | output_section_index: u32 = 0, | |
| 19 | 19 | |
| 20 | 20 | /// Index of the source symbol this symbol references. |
| 21 | 21 | /// Use `elfSym` to pull the source symbol from the relevant file. |
| ... | ... | @@ -37,7 +37,7 @@ pub fn isAbs(symbol: Symbol, elf_file: *Elf) bool { |
| 37 | 37 | file_ptr != .linker_defined; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | pub fn outputShndx(symbol: Symbol) ?u16 { | |
| 40 | pub fn outputShndx(symbol: Symbol) ?u32 { | |
| 41 | 41 | if (symbol.output_section_index == 0) return null; |
| 42 | 42 | return symbol.output_section_index; |
| 43 | 43 | } |
| ... | ... | @@ -104,6 +104,9 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true }, elf_file: *Elf |
| 104 | 104 | // Lazy-bound function it is! |
| 105 | 105 | return symbol.pltAddress(elf_file); |
| 106 | 106 | } |
| 107 | if (symbol.atom(elf_file)) |atom_ptr| { | |
| 108 | return atom_ptr.address(elf_file) + symbol.value; | |
| 109 | } | |
| 107 | 110 | return symbol.value; |
| 108 | 111 | } |
| 109 | 112 | |
| ... | ... | @@ -234,12 +237,12 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 234 | 237 | if (file_ptr == .shared_object) break :blk elf.STB_GLOBAL; |
| 235 | 238 | break :blk esym.st_bind(); |
| 236 | 239 | }; |
| 237 | const st_shndx = blk: { | |
| 238 | if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?; | |
| 240 | const st_shndx: u16 = blk: { | |
| 241 | if (symbol.flags.has_copy_rel) break :blk @intCast(elf_file.copy_rel_section_index.?); | |
| 239 | 242 | if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF; |
| 240 | 243 | if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON; |
| 241 | 244 | if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS; |
| 242 | break :blk symbol.outputShndx() orelse elf.SHN_UNDEF; | |
| 245 | break :blk @intCast(symbol.outputShndx() orelse elf.SHN_UNDEF); | |
| 243 | 246 | }; |
| 244 | 247 | const st_value = blk: { |
| 245 | 248 | if (symbol.flags.has_copy_rel) break :blk symbol.address(.{}, elf_file); |
| ... | ... | @@ -247,11 +250,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 247 | 250 | if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file); |
| 248 | 251 | break :blk 0; |
| 249 | 252 | } |
| 250 | if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.value; | |
| 253 | if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file); | |
| 251 | 254 | const shdr = &elf_file.shdrs.items[st_shndx]; |
| 252 | 255 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) |
| 253 | break :blk symbol.value - elf_file.tlsAddress(); | |
| 254 | break :blk symbol.value; | |
| 256 | break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); | |
| 257 | break :blk symbol.address(.{ .plt = false }, elf_file); | |
| 255 | 258 | }; |
| 256 | 259 | out.st_info = (st_bind << 4) | st_type; |
| 257 | 260 | out.st_other = esym.st_other; |
| ... | ... | @@ -323,7 +326,11 @@ fn format2( |
| 323 | 326 | _ = options; |
| 324 | 327 | _ = unused_fmt_string; |
| 325 | 328 | const symbol = ctx.symbol; |
| 326 | try writer.print("%{d} : {s} : @{x}", .{ symbol.esym_index, symbol.fmtName(ctx.elf_file), symbol.value }); | |
| 329 | try writer.print("%{d} : {s} : @{x}", .{ | |
| 330 | symbol.esym_index, | |
| 331 | symbol.fmtName(ctx.elf_file), | |
| 332 | symbol.address(.{}, ctx.elf_file), | |
| 333 | }); | |
| 327 | 334 | if (symbol.file(ctx.elf_file)) |file_ptr| { |
| 328 | 335 | if (symbol.isAbs(ctx.elf_file)) { |
| 329 | 336 | if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) { |
src/link/Elf/ZigObject.zig+24-35| ... | ... | @@ -401,19 +401,6 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { |
| 401 | 401 | } |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | pub fn allocateTlvAtoms(self: ZigObject, elf_file: *Elf) void { | |
| 405 | for (self.tls_variables.keys(), self.tls_variables.values()) |atom_index, tlv| { | |
| 406 | const atom = elf_file.atom(atom_index) orelse continue; | |
| 407 | if (!atom.flags.alive) continue; | |
| 408 | const local = elf_file.symbol(tlv.symbol_index); | |
| 409 | const shdr = elf_file.shdrs.items[atom.output_section_index]; | |
| 410 | atom.value += shdr.sh_addr; | |
| 411 | local.value = atom.value; | |
| 412 | ||
| 413 | // TODO exported TLS vars | |
| 414 | } | |
| 415 | } | |
| 416 | ||
| 417 | 404 | pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 418 | 405 | const gpa = elf_file.base.comp.gpa; |
| 419 | 406 | for (self.atoms.items) |atom_index| { |
| ... | ... | @@ -644,7 +631,7 @@ pub fn codeAlloc(self: ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 |
| 644 | 631 | return code; |
| 645 | 632 | } |
| 646 | 633 | |
| 647 | const file_offset = shdr.sh_offset + atom.value - shdr.sh_addr; | |
| 634 | const file_offset = shdr.sh_offset + atom.value; | |
| 648 | 635 | const size = std.math.cast(usize, atom.size) orelse return error.Overflow; |
| 649 | 636 | const code = try gpa.alloc(u8, size); |
| 650 | 637 | errdefer gpa.free(code); |
| ... | ... | @@ -664,7 +651,7 @@ pub fn getDeclVAddr( |
| 664 | 651 | ) !u64 { |
| 665 | 652 | const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 666 | 653 | const this_sym = elf_file.symbol(this_sym_index); |
| 667 | const vaddr = this_sym.value; | |
| 654 | const vaddr = this_sym.address(.{}, elf_file); | |
| 668 | 655 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 669 | 656 | try parent_atom.addReloc(elf_file, .{ |
| 670 | 657 | .r_offset = reloc_info.offset, |
| ... | ... | @@ -682,7 +669,7 @@ pub fn getAnonDeclVAddr( |
| 682 | 669 | ) !u64 { |
| 683 | 670 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; |
| 684 | 671 | const sym = elf_file.symbol(sym_index); |
| 685 | const vaddr = sym.value; | |
| 672 | const vaddr = sym.address(.{}, elf_file); | |
| 686 | 673 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 687 | 674 | try parent_atom.addReloc(elf_file, .{ |
| 688 | 675 | .r_offset = reloc_info.offset, |
| ... | ... | @@ -853,7 +840,7 @@ fn getDeclShdrIndex( |
| 853 | 840 | elf_file: *Elf, |
| 854 | 841 | decl: *const Module.Decl, |
| 855 | 842 | code: []const u8, |
| 856 | ) error{OutOfMemory}!u16 { | |
| 843 | ) error{OutOfMemory}!u32 { | |
| 857 | 844 | _ = self; |
| 858 | 845 | const mod = elf_file.base.comp.module.?; |
| 859 | 846 | const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; |
| ... | ... | @@ -907,7 +894,7 @@ fn updateDeclCode( |
| 907 | 894 | elf_file: *Elf, |
| 908 | 895 | decl_index: InternPool.DeclIndex, |
| 909 | 896 | sym_index: Symbol.Index, |
| 910 | shdr_index: u16, | |
| 897 | shdr_index: u32, | |
| 911 | 898 | code: []const u8, |
| 912 | 899 | stt_bits: u8, |
| 913 | 900 | ) !void { |
| ... | ... | @@ -941,13 +928,13 @@ fn updateDeclCode( |
| 941 | 928 | |
| 942 | 929 | if (old_size > 0 and elf_file.base.child_pid == null) { |
| 943 | 930 | const capacity = atom_ptr.capacity(elf_file); |
| 944 | const need_realloc = code.len > capacity or !required_alignment.check(sym.value); | |
| 931 | const need_realloc = code.len > capacity or !required_alignment.check(atom_ptr.value); | |
| 945 | 932 | if (need_realloc) { |
| 946 | 933 | try atom_ptr.grow(elf_file); |
| 947 | 934 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom_ptr.value }); |
| 948 | 935 | if (old_vaddr != atom_ptr.value) { |
| 949 | sym.value = atom_ptr.value; | |
| 950 | esym.st_value = atom_ptr.value; | |
| 936 | sym.value = 0; | |
| 937 | esym.st_value = 0; | |
| 951 | 938 | |
| 952 | 939 | if (!elf_file.base.isRelocatable()) { |
| 953 | 940 | log.debug(" (writing new offset table entry)", .{}); |
| ... | ... | @@ -963,9 +950,9 @@ fn updateDeclCode( |
| 963 | 950 | try atom_ptr.allocate(elf_file); |
| 964 | 951 | errdefer self.freeDeclMetadata(elf_file, sym_index); |
| 965 | 952 | |
| 966 | sym.value = atom_ptr.value; | |
| 953 | sym.value = 0; | |
| 967 | 954 | sym.flags.needs_zig_got = true; |
| 968 | esym.st_value = atom_ptr.value; | |
| 955 | esym.st_value = 0; | |
| 969 | 956 | |
| 970 | 957 | if (!elf_file.base.isRelocatable()) { |
| 971 | 958 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| ... | ... | @@ -981,7 +968,7 @@ fn updateDeclCode( |
| 981 | 968 | .iov_len = code.len, |
| 982 | 969 | }}; |
| 983 | 970 | var remote_vec: [1]std.os.iovec_const = .{.{ |
| 984 | .iov_base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.value)))), | |
| 971 | .iov_base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{}, elf_file))))), | |
| 985 | 972 | .iov_len = code.len, |
| 986 | 973 | }}; |
| 987 | 974 | const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0); |
| ... | ... | @@ -996,7 +983,7 @@ fn updateDeclCode( |
| 996 | 983 | |
| 997 | 984 | const shdr = elf_file.shdrs.items[shdr_index]; |
| 998 | 985 | if (shdr.sh_type != elf.SHT_NOBITS) { |
| 999 | const file_offset = shdr.sh_offset + sym.value - shdr.sh_addr; | |
| 986 | const file_offset = shdr.sh_offset + atom_ptr.value; | |
| 1000 | 987 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1001 | 988 | } |
| 1002 | 989 | } |
| ... | ... | @@ -1006,7 +993,7 @@ fn updateTlv( |
| 1006 | 993 | elf_file: *Elf, |
| 1007 | 994 | decl_index: InternPool.DeclIndex, |
| 1008 | 995 | sym_index: Symbol.Index, |
| 1009 | shndx: u16, | |
| 996 | shndx: u32, | |
| 1010 | 997 | code: []const u8, |
| 1011 | 998 | ) !void { |
| 1012 | 999 | const gpa = elf_file.base.comp.gpa; |
| ... | ... | @@ -1022,12 +1009,14 @@ fn updateTlv( |
| 1022 | 1009 | const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index]; |
| 1023 | 1010 | const atom_ptr = sym.atom(elf_file).?; |
| 1024 | 1011 | |
| 1012 | sym.value = 0; | |
| 1025 | 1013 | sym.output_section_index = shndx; |
| 1026 | 1014 | atom_ptr.output_section_index = shndx; |
| 1027 | 1015 | |
| 1028 | 1016 | sym.name_offset = try self.strtab.insert(gpa, decl_name); |
| 1029 | 1017 | atom_ptr.flags.alive = true; |
| 1030 | 1018 | atom_ptr.name_offset = sym.name_offset; |
| 1019 | esym.st_value = 0; | |
| 1031 | 1020 | esym.st_name = sym.name_offset; |
| 1032 | 1021 | esym.st_info = elf.STT_TLS; |
| 1033 | 1022 | esym.st_size = code.len; |
| ... | ... | @@ -1117,7 +1106,7 @@ pub fn updateFunc( |
| 1117 | 1106 | try self.dwarf.?.commitDeclState( |
| 1118 | 1107 | mod, |
| 1119 | 1108 | decl_index, |
| 1120 | sym.value, | |
| 1109 | sym.address(.{}, elf_file), | |
| 1121 | 1110 | sym.atom(elf_file).?.size, |
| 1122 | 1111 | ds, |
| 1123 | 1112 | ); |
| ... | ... | @@ -1202,7 +1191,7 @@ pub fn updateDecl( |
| 1202 | 1191 | try self.dwarf.?.commitDeclState( |
| 1203 | 1192 | mod, |
| 1204 | 1193 | decl_index, |
| 1205 | sym.value, | |
| 1194 | sym.address(.{}, elf_file), | |
| 1206 | 1195 | sym.atom(elf_file).?.size, |
| 1207 | 1196 | ds, |
| 1208 | 1197 | ); |
| ... | ... | @@ -1281,9 +1270,9 @@ fn updateLazySymbol( |
| 1281 | 1270 | try atom_ptr.allocate(elf_file); |
| 1282 | 1271 | errdefer self.freeDeclMetadata(elf_file, symbol_index); |
| 1283 | 1272 | |
| 1284 | local_sym.value = atom_ptr.value; | |
| 1273 | local_sym.value = 0; | |
| 1285 | 1274 | local_sym.flags.needs_zig_got = true; |
| 1286 | local_esym.st_value = atom_ptr.value; | |
| 1275 | local_esym.st_value = 0; | |
| 1287 | 1276 | |
| 1288 | 1277 | if (!elf_file.base.isRelocatable()) { |
| 1289 | 1278 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); |
| ... | ... | @@ -1291,7 +1280,7 @@ fn updateLazySymbol( |
| 1291 | 1280 | } |
| 1292 | 1281 | |
| 1293 | 1282 | const shdr = elf_file.shdrs.items[output_section_index]; |
| 1294 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 1283 | const file_offset = shdr.sh_offset + atom_ptr.value; | |
| 1295 | 1284 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1296 | 1285 | } |
| 1297 | 1286 | |
| ... | ... | @@ -1345,7 +1334,7 @@ fn lowerConst( |
| 1345 | 1334 | name: []const u8, |
| 1346 | 1335 | tv: TypedValue, |
| 1347 | 1336 | required_alignment: InternPool.Alignment, |
| 1348 | output_section_index: u16, | |
| 1337 | output_section_index: u32, | |
| 1349 | 1338 | src_loc: Module.SrcLoc, |
| 1350 | 1339 | ) !LowerConstResult { |
| 1351 | 1340 | const gpa = elf_file.base.comp.gpa; |
| ... | ... | @@ -1384,11 +1373,11 @@ fn lowerConst( |
| 1384 | 1373 | // TODO rename and re-audit this method |
| 1385 | 1374 | errdefer self.freeDeclMetadata(elf_file, sym_index); |
| 1386 | 1375 | |
| 1387 | local_sym.value = atom_ptr.value; | |
| 1388 | local_esym.st_value = atom_ptr.value; | |
| 1376 | local_sym.value = 0; | |
| 1377 | local_esym.st_value = 0; | |
| 1389 | 1378 | |
| 1390 | 1379 | const shdr = elf_file.shdrs.items[output_section_index]; |
| 1391 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 1380 | const file_offset = shdr.sh_offset + atom_ptr.value; | |
| 1392 | 1381 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1393 | 1382 | |
| 1394 | 1383 | return .{ .ok = sym_index }; |
src/link/Elf/eh_frame.zig+1-1| ... | ... | @@ -409,7 +409,7 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re |
| 409 | 409 | var r_sym: u32 = 0; |
| 410 | 410 | switch (sym.type(elf_file)) { |
| 411 | 411 | elf.STT_SECTION => { |
| 412 | r_addend += @intCast(sym.value); | |
| 412 | r_addend += @intCast(sym.address(.{}, elf_file)); | |
| 413 | 413 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?); |
| 414 | 414 | }, |
| 415 | 415 | else => { |
src/link/Elf/relocatable.zig-1| ... | ... | @@ -195,7 +195,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 195 | 195 | |
| 196 | 196 | try allocateAllocSections(elf_file); |
| 197 | 197 | try elf_file.allocateNonAllocSections(); |
| 198 | elf_file.allocateAtoms(); | |
| 199 | 198 | |
| 200 | 199 | if (build_options.enable_logging) { |
| 201 | 200 | state_log.debug("{}", .{elf_file.dumpState()}); |
src/link/Elf/synthetic_sections.zig+7-7| ... | ... | @@ -297,7 +297,7 @@ pub const ZigGotSection = struct { |
| 297 | 297 | const off = zig_got.entryOffset(index, elf_file); |
| 298 | 298 | const vaddr = zig_got.entryAddress(index, elf_file); |
| 299 | 299 | const entry = zig_got.entries.items[index]; |
| 300 | const value = elf_file.symbol(entry).value; | |
| 300 | const value = elf_file.symbol(entry).address(.{}, elf_file); | |
| 301 | 301 | switch (entry_size) { |
| 302 | 302 | 2 => { |
| 303 | 303 | var buf: [2]u8 = undefined; |
| ... | ... | @@ -388,7 +388,7 @@ pub const ZigGotSection = struct { |
| 388 | 388 | .st_name = st_name, |
| 389 | 389 | .st_info = elf.STT_OBJECT, |
| 390 | 390 | .st_other = 0, |
| 391 | .st_shndx = elf_file.zig_got_section_index.?, | |
| 391 | .st_shndx = @intCast(elf_file.zig_got_section_index.?), | |
| 392 | 392 | .st_value = st_value, |
| 393 | 393 | .st_size = st_size, |
| 394 | 394 | }; |
| ... | ... | @@ -813,7 +813,7 @@ pub const GotSection = struct { |
| 813 | 813 | .st_name = st_name, |
| 814 | 814 | .st_info = elf.STT_OBJECT, |
| 815 | 815 | .st_other = 0, |
| 816 | .st_shndx = elf_file.got_section_index.?, | |
| 816 | .st_shndx = @intCast(elf_file.got_section_index.?), | |
| 817 | 817 | .st_value = st_value, |
| 818 | 818 | .st_size = st_size, |
| 819 | 819 | }; |
| ... | ... | @@ -953,7 +953,7 @@ pub const PltSection = struct { |
| 953 | 953 | .st_name = st_name, |
| 954 | 954 | .st_info = elf.STT_FUNC, |
| 955 | 955 | .st_other = 0, |
| 956 | .st_shndx = elf_file.plt_section_index.?, | |
| 956 | .st_shndx = @intCast(elf_file.plt_section_index.?), | |
| 957 | 957 | .st_value = sym.pltAddress(elf_file), |
| 958 | 958 | .st_size = 16, |
| 959 | 959 | }; |
| ... | ... | @@ -1004,7 +1004,7 @@ pub const GotPltSection = struct { |
| 1004 | 1004 | { |
| 1005 | 1005 | // [0]: _DYNAMIC |
| 1006 | 1006 | const symbol = elf_file.symbol(elf_file.dynamic_index.?); |
| 1007 | try writer.writeInt(u64, symbol.value, .little); | |
| 1007 | try writer.writeInt(u64, symbol.address(.{}, elf_file), .little); | |
| 1008 | 1008 | } |
| 1009 | 1009 | // [1]: 0x0 |
| 1010 | 1010 | // [2]: 0x0 |
| ... | ... | @@ -1082,7 +1082,7 @@ pub const PltGotSection = struct { |
| 1082 | 1082 | .st_name = st_name, |
| 1083 | 1083 | .st_info = elf.STT_FUNC, |
| 1084 | 1084 | .st_other = 0, |
| 1085 | .st_shndx = elf_file.plt_got_section_index.?, | |
| 1085 | .st_shndx = @intCast(elf_file.plt_got_section_index.?), | |
| 1086 | 1086 | .st_value = sym.pltGotAddress(elf_file), |
| 1087 | 1087 | .st_size = 16, |
| 1088 | 1088 | }; |
| ... | ... | @@ -1132,7 +1132,7 @@ pub const CopyRelSection = struct { |
| 1132 | 1132 | } |
| 1133 | 1133 | } |
| 1134 | 1134 | |
| 1135 | pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u16, elf_file: *Elf) !void { | |
| 1135 | pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void { | |
| 1136 | 1136 | const shdr = &elf_file.shdrs.items[shndx]; |
| 1137 | 1137 | for (copy_rel.symbols.items) |sym_index| { |
| 1138 | 1138 | const symbol = elf_file.symbol(sym_index); |