| author | |
| committer | |
| log | e401930fa862e3b9b3eedc8eb405c501fbf3de30 |
| tree | dad8558d3ccf98880a4c7f8f6ecb443b52a34247 |
| parent | c22bb3805821d7ffe60e048f1efe362aad703668 |
8 files changed, 61 insertions(+), 78 deletions(-)
src/link/Elf.zig+3-13| ... | @@ -1332,7 +1332,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) | ... | @@ -1332,7 +1332,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) |
| 1332 | try self.sortPhdrs(); | 1332 | try self.sortPhdrs(); |
| 1333 | try self.allocateNonAllocSections(); | 1333 | try self.allocateNonAllocSections(); |
| 1334 | self.allocateSpecialPhdrs(); | 1334 | self.allocateSpecialPhdrs(); |
| 1335 | self.allocateAtoms(); | ||
| 1336 | self.allocateLinkerDefinedSymbols(); | 1335 | self.allocateLinkerDefinedSymbols(); |
| 1337 | 1336 | ||
| 1338 | // Dump the state for easy debugging. | 1337 | // Dump the state for easy debugging. |
| ... | @@ -1352,7 +1351,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) | ... | @@ -1352,7 +1351,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) |
| 1352 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 1351 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1353 | const code = try zig_object.codeAlloc(self, atom_index); | 1352 | const code = try zig_object.codeAlloc(self, atom_index); |
| 1354 | defer gpa.free(code); | 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 | atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { | 1355 | atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { |
| 1357 | // TODO | 1356 | // TODO |
| 1358 | error.RelaxFail, error.InvalidInstruction, error.CannotEncode => { | 1357 | error.RelaxFail, error.InvalidInstruction, error.CannotEncode => { |
| ... | @@ -2907,7 +2906,7 @@ pub fn writeElfHeader(self: *Elf) !void { | ... | @@ -2907,7 +2906,7 @@ pub fn writeElfHeader(self: *Elf) !void { |
| 2907 | mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian); | 2906 | mem.writeInt(u32, hdr_buf[index..][0..4], 1, endian); |
| 2908 | index += 4; | 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 | const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0; | 2910 | const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0; |
| 2912 | switch (self.ptr_width) { | 2911 | switch (self.ptr_width) { |
| 2913 | .p32 => { | 2912 | .p32 => { |
| ... | @@ -4402,15 +4401,6 @@ fn allocateSpecialPhdrs(self: *Elf) void { | ... | @@ -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 | fn writeAtoms(self: *Elf) !void { | 4404 | fn writeAtoms(self: *Elf) !void { |
| 4415 | const gpa = self.base.comp.gpa; | 4405 | const gpa = self.base.comp.gpa; |
| 4416 | 4406 | ||
| ... | @@ -4464,7 +4454,7 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -4464,7 +4454,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4464 | const atom_ptr = self.atom(atom_index).?; | 4454 | const atom_ptr = self.atom(atom_index).?; |
| 4465 | assert(atom_ptr.flags.alive); | 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 | return error.Overflow; | 4458 | return error.Overflow; |
| 4469 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; | 4459 | const size = math.cast(usize, atom_ptr.size) orelse return error.Overflow; |
| 4470 | 4460 |
src/link/Elf/Atom.zig+24-15| ... | @@ -54,6 +54,12 @@ pub fn name(self: Atom, elf_file: *Elf) []const u8 { | ... | @@ -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 | pub fn file(self: Atom, elf_file: *Elf) ?File { | 63 | pub fn file(self: Atom, elf_file: *Elf) ?File { |
| 58 | return elf_file.file(self.file_index); | 64 | return elf_file.file(self.file_index); |
| 59 | } | 65 | } |
| ... | @@ -85,14 +91,17 @@ pub fn priority(self: Atom, elf_file: *Elf) u64 { | ... | @@ -85,14 +91,17 @@ pub fn priority(self: Atom, elf_file: *Elf) u64 { |
| 85 | /// File offset relocation happens transparently, so it is not included in | 91 | /// File offset relocation happens transparently, so it is not included in |
| 86 | /// this calculation. | 92 | /// this calculation. |
| 87 | pub fn capacity(self: Atom, elf_file: *Elf) u64 { | 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); | 94 | const next_addr = if (elf_file.atom(self.next_index)) |next| |
| 89 | return next_value - self.value; | 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 | pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { | 101 | pub fn freeListEligible(self: Atom, elf_file: *Elf) bool { |
| 93 | // No need to keep a free list node for the last block. | 102 | // No need to keep a free list node for the last block. |
| 94 | const next = elf_file.atom(self.next_index) orelse return false; | 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 | const ideal_cap = Elf.padToIdeal(self.size); | 105 | const ideal_cap = Elf.padToIdeal(self.size); |
| 97 | if (cap <= ideal_cap) return false; | 106 | if (cap <= ideal_cap) return false; |
| 98 | const surplus = cap - ideal_cap; | 107 | const surplus = cap - ideal_cap; |
| ... | @@ -160,15 +169,15 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { | ... | @@ -160,15 +169,15 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 160 | atom_placement = last.atom_index; | 169 | atom_placement = last.atom_index; |
| 161 | break :blk new_start_vaddr; | 170 | break :blk new_start_vaddr; |
| 162 | } else { | 171 | } else { |
| 163 | break :blk shdr.sh_addr; | 172 | break :blk 0; |
| 164 | } | 173 | } |
| 165 | }; | 174 | }; |
| 166 | 175 | ||
| 167 | log.debug("allocated atom({d}) : '{s}' at 0x{x} to 0x{x}", .{ | 176 | log.debug("allocated atom({d}) : '{s}' at 0x{x} to 0x{x}", .{ |
| 168 | self.atom_index, | 177 | self.atom_index, |
| 169 | self.name(elf_file), | 178 | self.name(elf_file), |
| 170 | self.value, | 179 | self.address(elf_file), |
| 171 | self.value + self.size, | 180 | self.address(elf_file) + self.size, |
| 172 | }); | 181 | }); |
| 173 | 182 | ||
| 174 | const expand_section = if (atom_placement) |placement_index| | 183 | const expand_section = if (atom_placement) |placement_index| |
| ... | @@ -176,7 +185,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { | ... | @@ -176,7 +185,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 176 | else | 185 | else |
| 177 | true; | 186 | true; |
| 178 | if (expand_section) { | 187 | if (expand_section) { |
| 179 | const needed_size = (self.value + self.size) - shdr.sh_addr; | 188 | const needed_size = self.value + self.size; |
| 180 | try elf_file.growAllocSection(self.outputShndx().?, needed_size); | 189 | try elf_file.growAllocSection(self.outputShndx().?, needed_size); |
| 181 | last_atom_index.* = self.atom_index; | 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,7 +310,7 @@ pub fn relocs(self: Atom, elf_file: *Elf) []align(1) const elf.Elf64_Rela { |
| 301 | } | 310 | } |
| 302 | 311 | ||
| 303 | pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.Elf64_Rela)) !void { | 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 | const file_ptr = self.file(elf_file).?; | 315 | const file_ptr = self.file(elf_file).?; |
| 307 | for (self.relocs(elf_file)) |rel| { | 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,7 +331,7 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El |
| 322 | var r_sym: u32 = 0; | 331 | var r_sym: u32 = 0; |
| 323 | switch (target.type(elf_file)) { | 332 | switch (target.type(elf_file)) { |
| 324 | elf.STT_SECTION => { | 333 | elf.STT_SECTION => { |
| 325 | r_addend += @intCast(target.value); | 334 | r_addend += @intCast(target.address(.{}, elf_file)); |
| 326 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(target.outputShndx().?); | 335 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(target.outputShndx().?); |
| 327 | }, | 336 | }, |
| 328 | else => { | 337 | else => { |
| ... | @@ -778,7 +787,7 @@ fn reportUndefined( | ... | @@ -778,7 +787,7 @@ fn reportUndefined( |
| 778 | } | 787 | } |
| 779 | 788 | ||
| 780 | pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { | 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 | const file_ptr = self.file(elf_file).?; | 792 | const file_ptr = self.file(elf_file).?; |
| 784 | var stream = std.io.fixedBufferStream(code); | 793 | var stream = std.io.fixedBufferStream(code); |
| ... | @@ -802,7 +811,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { | ... | @@ -802,7 +811,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 802 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ | 811 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ |
| 803 | // | 812 | // |
| 804 | // Address of the source atom. | 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 | // Addend from the relocation. | 815 | // Addend from the relocation. |
| 807 | const A = rel.r_addend; | 816 | const A = rel.r_addend; |
| 808 | // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. | 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,7 +978,7 @@ fn resolveDynAbsReloc( |
| 969 | ) !void { | 978 | ) !void { |
| 970 | const comp = elf_file.base.comp; | 979 | const comp = elf_file.base.comp; |
| 971 | const gpa = comp.gpa; | 980 | const gpa = comp.gpa; |
| 972 | const P = self.value + rel.r_offset; | 981 | const P = self.address(elf_file) + rel.r_offset; |
| 973 | const A = rel.r_addend; | 982 | const A = rel.r_addend; |
| 974 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); | 983 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); |
| 975 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; | 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,7 +1067,7 @@ fn applyDynamicReloc(value: i64, elf_file: *Elf, writer: anytype) !void { |
| 1058 | } | 1067 | } |
| 1059 | 1068 | ||
| 1060 | pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: anytype) !void { | 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 | const file_ptr = self.file(elf_file).?; | 1072 | const file_ptr = self.file(elf_file).?; |
| 1064 | var stream = std.io.fixedBufferStream(code); | 1073 | var stream = std.io.fixedBufferStream(code); |
| ... | @@ -1097,7 +1106,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any | ... | @@ -1097,7 +1106,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any |
| 1097 | // We will use equation format to resolve relocations: | 1106 | // We will use equation format to resolve relocations: |
| 1098 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ | 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 | // Addend from the relocation. | 1110 | // Addend from the relocation. |
| 1102 | const A = rel.r_addend; | 1111 | const A = rel.r_addend; |
| 1103 | // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. | 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,7 +1257,7 @@ fn format2( |
| 1248 | const atom = ctx.atom; | 1257 | const atom = ctx.atom; |
| 1249 | const elf_file = ctx.elf_file; | 1258 | const elf_file = ctx.elf_file; |
| 1250 | try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x})", .{ | 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 | atom.output_section_index, atom.alignment, atom.size, | 1261 | atom.output_section_index, atom.alignment, atom.size, |
| 1253 | }); | 1262 | }); |
| 1254 | if (atom.fde_start != atom.fde_end) { | 1263 | if (atom.fde_start != atom.fde_end) { |
src/link/Elf/Object.zig-11| ... | @@ -718,21 +718,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -718,21 +718,11 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void { |
| 718 | if (!gop.found_existing) gop.value_ptr.* = .{}; | 718 | if (!gop.found_existing) gop.value_ptr.* = .{}; |
| 719 | try gop.value_ptr.append(gpa, atom_index); | 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 | for (self.locals()) |local_index| { | 722 | for (self.locals()) |local_index| { |
| 732 | const local = elf_file.symbol(local_index); | 723 | const local = elf_file.symbol(local_index); |
| 733 | const atom = local.atom(elf_file) orelse continue; | 724 | const atom = local.atom(elf_file) orelse continue; |
| 734 | if (!atom.flags.alive) continue; | 725 | if (!atom.flags.alive) continue; |
| 735 | local.value += atom.value; | ||
| 736 | local.output_section_index = atom.output_section_index; | 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,7 +731,6 @@ pub fn allocateAtoms(self: Object, elf_file: *Elf) void { |
| 741 | const atom = global.atom(elf_file) orelse continue; | 731 | const atom = global.atom(elf_file) orelse continue; |
| 742 | if (!atom.flags.alive) continue; | 732 | if (!atom.flags.alive) continue; |
| 743 | if (global.file(elf_file).?.index() != self.index) continue; | 733 | if (global.file(elf_file).?.index() != self.index) continue; |
| 744 | global.value += atom.value; | ||
| 745 | global.output_section_index = atom.output_section_index; | 734 | global.output_section_index = atom.output_section_index; |
| 746 | } | 735 | } |
| 747 | } | 736 | } |
src/link/Elf/Symbol.zig+11-4| ... | @@ -104,6 +104,9 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true }, elf_file: *Elf | ... | @@ -104,6 +104,9 @@ pub fn address(symbol: Symbol, opts: struct { plt: bool = true }, elf_file: *Elf |
| 104 | // Lazy-bound function it is! | 104 | // Lazy-bound function it is! |
| 105 | return symbol.pltAddress(elf_file); | 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 | return symbol.value; | 110 | return symbol.value; |
| 108 | } | 111 | } |
| 109 | 112 | ||
| ... | @@ -247,11 +250,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { | ... | @@ -247,11 +250,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 247 | if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file); | 250 | if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file); |
| 248 | break :blk 0; | 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 | const shdr = &elf_file.shdrs.items[st_shndx]; | 254 | const shdr = &elf_file.shdrs.items[st_shndx]; |
| 252 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) | 255 | if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) |
| 253 | break :blk symbol.value - elf_file.tlsAddress(); | 256 | break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); |
| 254 | break :blk symbol.value; | 257 | break :blk symbol.address(.{ .plt = false }, elf_file); |
| 255 | }; | 258 | }; |
| 256 | out.st_info = (st_bind << 4) | st_type; | 259 | out.st_info = (st_bind << 4) | st_type; |
| 257 | out.st_other = esym.st_other; | 260 | out.st_other = esym.st_other; |
| ... | @@ -323,7 +326,11 @@ fn format2( | ... | @@ -323,7 +326,11 @@ fn format2( |
| 323 | _ = options; | 326 | _ = options; |
| 324 | _ = unused_fmt_string; | 327 | _ = unused_fmt_string; |
| 325 | const symbol = ctx.symbol; | 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 | if (symbol.file(ctx.elf_file)) |file_ptr| { | 334 | if (symbol.file(ctx.elf_file)) |file_ptr| { |
| 328 | if (symbol.isAbs(ctx.elf_file)) { | 335 | if (symbol.isAbs(ctx.elf_file)) { |
| 329 | if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) { | 336 | if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) { |
src/link/Elf/ZigObject.zig+20-31| ... | @@ -401,19 +401,6 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void { | ... | @@ -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 | pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { | 404 | pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 418 | const gpa = elf_file.base.comp.gpa; | 405 | const gpa = elf_file.base.comp.gpa; |
| 419 | for (self.atoms.items) |atom_index| { | 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,7 +631,7 @@ pub fn codeAlloc(self: ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 |
| 644 | return code; | 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 | const size = std.math.cast(usize, atom.size) orelse return error.Overflow; | 635 | const size = std.math.cast(usize, atom.size) orelse return error.Overflow; |
| 649 | const code = try gpa.alloc(u8, size); | 636 | const code = try gpa.alloc(u8, size); |
| 650 | errdefer gpa.free(code); | 637 | errdefer gpa.free(code); |
| ... | @@ -664,7 +651,7 @@ pub fn getDeclVAddr( | ... | @@ -664,7 +651,7 @@ pub fn getDeclVAddr( |
| 664 | ) !u64 { | 651 | ) !u64 { |
| 665 | const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); | 652 | const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); |
| 666 | const this_sym = elf_file.symbol(this_sym_index); | 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 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; | 655 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 669 | try parent_atom.addReloc(elf_file, .{ | 656 | try parent_atom.addReloc(elf_file, .{ |
| 670 | .r_offset = reloc_info.offset, | 657 | .r_offset = reloc_info.offset, |
| ... | @@ -682,7 +669,7 @@ pub fn getAnonDeclVAddr( | ... | @@ -682,7 +669,7 @@ pub fn getAnonDeclVAddr( |
| 682 | ) !u64 { | 669 | ) !u64 { |
| 683 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; | 670 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; |
| 684 | const sym = elf_file.symbol(sym_index); | 671 | const sym = elf_file.symbol(sym_index); |
| 685 | const vaddr = sym.value; | 672 | const vaddr = sym.address(.{}, elf_file); |
| 686 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; | 673 | const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?; |
| 687 | try parent_atom.addReloc(elf_file, .{ | 674 | try parent_atom.addReloc(elf_file, .{ |
| 688 | .r_offset = reloc_info.offset, | 675 | .r_offset = reloc_info.offset, |
| ... | @@ -941,13 +928,13 @@ fn updateDeclCode( | ... | @@ -941,13 +928,13 @@ fn updateDeclCode( |
| 941 | 928 | ||
| 942 | if (old_size > 0 and elf_file.base.child_pid == null) { | 929 | if (old_size > 0 and elf_file.base.child_pid == null) { |
| 943 | const capacity = atom_ptr.capacity(elf_file); | 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 | if (need_realloc) { | 932 | if (need_realloc) { |
| 946 | try atom_ptr.grow(elf_file); | 933 | try atom_ptr.grow(elf_file); |
| 947 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom_ptr.value }); | 934 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, old_vaddr, atom_ptr.value }); |
| 948 | if (old_vaddr != atom_ptr.value) { | 935 | if (old_vaddr != atom_ptr.value) { |
| 949 | sym.value = atom_ptr.value; | 936 | sym.value = 0; |
| 950 | esym.st_value = atom_ptr.value; | 937 | esym.st_value = 0; |
| 951 | 938 | ||
| 952 | if (!elf_file.base.isRelocatable()) { | 939 | if (!elf_file.base.isRelocatable()) { |
| 953 | log.debug(" (writing new offset table entry)", .{}); | 940 | log.debug(" (writing new offset table entry)", .{}); |
| ... | @@ -963,9 +950,9 @@ fn updateDeclCode( | ... | @@ -963,9 +950,9 @@ fn updateDeclCode( |
| 963 | try atom_ptr.allocate(elf_file); | 950 | try atom_ptr.allocate(elf_file); |
| 964 | errdefer self.freeDeclMetadata(elf_file, sym_index); | 951 | errdefer self.freeDeclMetadata(elf_file, sym_index); |
| 965 | 952 | ||
| 966 | sym.value = atom_ptr.value; | 953 | sym.value = 0; |
| 967 | sym.flags.needs_zig_got = true; | 954 | sym.flags.needs_zig_got = true; |
| 968 | esym.st_value = atom_ptr.value; | 955 | esym.st_value = 0; |
| 969 | 956 | ||
| 970 | if (!elf_file.base.isRelocatable()) { | 957 | if (!elf_file.base.isRelocatable()) { |
| 971 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); | 958 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| ... | @@ -981,7 +968,7 @@ fn updateDeclCode( | ... | @@ -981,7 +968,7 @@ fn updateDeclCode( |
| 981 | .iov_len = code.len, | 968 | .iov_len = code.len, |
| 982 | }}; | 969 | }}; |
| 983 | var remote_vec: [1]std.os.iovec_const = .{.{ | 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 | .iov_len = code.len, | 972 | .iov_len = code.len, |
| 986 | }}; | 973 | }}; |
| 987 | const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0); | 974 | const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0); |
| ... | @@ -996,7 +983,7 @@ fn updateDeclCode( | ... | @@ -996,7 +983,7 @@ fn updateDeclCode( |
| 996 | 983 | ||
| 997 | const shdr = elf_file.shdrs.items[shdr_index]; | 984 | const shdr = elf_file.shdrs.items[shdr_index]; |
| 998 | if (shdr.sh_type != elf.SHT_NOBITS) { | 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 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 987 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1001 | } | 988 | } |
| 1002 | } | 989 | } |
| ... | @@ -1022,12 +1009,14 @@ fn updateTlv( | ... | @@ -1022,12 +1009,14 @@ fn updateTlv( |
| 1022 | const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index]; | 1009 | const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index]; |
| 1023 | const atom_ptr = sym.atom(elf_file).?; | 1010 | const atom_ptr = sym.atom(elf_file).?; |
| 1024 | 1011 | ||
| 1012 | sym.value = 0; | ||
| 1025 | sym.output_section_index = shndx; | 1013 | sym.output_section_index = shndx; |
| 1026 | atom_ptr.output_section_index = shndx; | 1014 | atom_ptr.output_section_index = shndx; |
| 1027 | 1015 | ||
| 1028 | sym.name_offset = try self.strtab.insert(gpa, decl_name); | 1016 | sym.name_offset = try self.strtab.insert(gpa, decl_name); |
| 1029 | atom_ptr.flags.alive = true; | 1017 | atom_ptr.flags.alive = true; |
| 1030 | atom_ptr.name_offset = sym.name_offset; | 1018 | atom_ptr.name_offset = sym.name_offset; |
| 1019 | esym.st_value = 0; | ||
| 1031 | esym.st_name = sym.name_offset; | 1020 | esym.st_name = sym.name_offset; |
| 1032 | esym.st_info = elf.STT_TLS; | 1021 | esym.st_info = elf.STT_TLS; |
| 1033 | esym.st_size = code.len; | 1022 | esym.st_size = code.len; |
| ... | @@ -1117,7 +1106,7 @@ pub fn updateFunc( | ... | @@ -1117,7 +1106,7 @@ pub fn updateFunc( |
| 1117 | try self.dwarf.?.commitDeclState( | 1106 | try self.dwarf.?.commitDeclState( |
| 1118 | mod, | 1107 | mod, |
| 1119 | decl_index, | 1108 | decl_index, |
| 1120 | sym.value, | 1109 | sym.address(.{}, elf_file), |
| 1121 | sym.atom(elf_file).?.size, | 1110 | sym.atom(elf_file).?.size, |
| 1122 | ds, | 1111 | ds, |
| 1123 | ); | 1112 | ); |
| ... | @@ -1202,7 +1191,7 @@ pub fn updateDecl( | ... | @@ -1202,7 +1191,7 @@ pub fn updateDecl( |
| 1202 | try self.dwarf.?.commitDeclState( | 1191 | try self.dwarf.?.commitDeclState( |
| 1203 | mod, | 1192 | mod, |
| 1204 | decl_index, | 1193 | decl_index, |
| 1205 | sym.value, | 1194 | sym.address(.{}, elf_file), |
| 1206 | sym.atom(elf_file).?.size, | 1195 | sym.atom(elf_file).?.size, |
| 1207 | ds, | 1196 | ds, |
| 1208 | ); | 1197 | ); |
| ... | @@ -1281,9 +1270,9 @@ fn updateLazySymbol( | ... | @@ -1281,9 +1270,9 @@ fn updateLazySymbol( |
| 1281 | try atom_ptr.allocate(elf_file); | 1270 | try atom_ptr.allocate(elf_file); |
| 1282 | errdefer self.freeDeclMetadata(elf_file, symbol_index); | 1271 | errdefer self.freeDeclMetadata(elf_file, symbol_index); |
| 1283 | 1272 | ||
| 1284 | local_sym.value = atom_ptr.value; | 1273 | local_sym.value = 0; |
| 1285 | local_sym.flags.needs_zig_got = true; | 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 | if (!elf_file.base.isRelocatable()) { | 1277 | if (!elf_file.base.isRelocatable()) { |
| 1289 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); | 1278 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); |
| ... | @@ -1291,7 +1280,7 @@ fn updateLazySymbol( | ... | @@ -1291,7 +1280,7 @@ fn updateLazySymbol( |
| 1291 | } | 1280 | } |
| 1292 | 1281 | ||
| 1293 | const shdr = elf_file.shdrs.items[output_section_index]; | 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 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1284 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1296 | } | 1285 | } |
| 1297 | 1286 | ||
| ... | @@ -1384,11 +1373,11 @@ fn lowerConst( | ... | @@ -1384,11 +1373,11 @@ fn lowerConst( |
| 1384 | // TODO rename and re-audit this method | 1373 | // TODO rename and re-audit this method |
| 1385 | errdefer self.freeDeclMetadata(elf_file, sym_index); | 1374 | errdefer self.freeDeclMetadata(elf_file, sym_index); |
| 1386 | 1375 | ||
| 1387 | local_sym.value = atom_ptr.value; | 1376 | local_sym.value = 0; |
| 1388 | local_esym.st_value = atom_ptr.value; | 1377 | local_esym.st_value = 0; |
| 1389 | 1378 | ||
| 1390 | const shdr = elf_file.shdrs.items[output_section_index]; | 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 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1381 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
| 1393 | 1382 | ||
| 1394 | return .{ .ok = sym_index }; | 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,7 +409,7 @@ fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Re |
| 409 | var r_sym: u32 = 0; | 409 | var r_sym: u32 = 0; |
| 410 | switch (sym.type(elf_file)) { | 410 | switch (sym.type(elf_file)) { |
| 411 | elf.STT_SECTION => { | 411 | elf.STT_SECTION => { |
| 412 | r_addend += @intCast(sym.value); | 412 | r_addend += @intCast(sym.address(.{}, elf_file)); |
| 413 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?); | 413 | r_sym = elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx().?); |
| 414 | }, | 414 | }, |
| 415 | else => { | 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,7 +195,6 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]const |
| 195 | 195 | ||
| 196 | try allocateAllocSections(elf_file); | 196 | try allocateAllocSections(elf_file); |
| 197 | try elf_file.allocateNonAllocSections(); | 197 | try elf_file.allocateNonAllocSections(); |
| 198 | elf_file.allocateAtoms(); | ||
| 199 | 198 | ||
| 200 | if (build_options.enable_logging) { | 199 | if (build_options.enable_logging) { |
| 201 | state_log.debug("{}", .{elf_file.dumpState()}); | 200 | state_log.debug("{}", .{elf_file.dumpState()}); |
src/link/Elf/synthetic_sections.zig+2-2| ... | @@ -297,7 +297,7 @@ pub const ZigGotSection = struct { | ... | @@ -297,7 +297,7 @@ pub const ZigGotSection = struct { |
| 297 | const off = zig_got.entryOffset(index, elf_file); | 297 | const off = zig_got.entryOffset(index, elf_file); |
| 298 | const vaddr = zig_got.entryAddress(index, elf_file); | 298 | const vaddr = zig_got.entryAddress(index, elf_file); |
| 299 | const entry = zig_got.entries.items[index]; | 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 | switch (entry_size) { | 301 | switch (entry_size) { |
| 302 | 2 => { | 302 | 2 => { |
| 303 | var buf: [2]u8 = undefined; | 303 | var buf: [2]u8 = undefined; |
| ... | @@ -1004,7 +1004,7 @@ pub const GotPltSection = struct { | ... | @@ -1004,7 +1004,7 @@ pub const GotPltSection = struct { |
| 1004 | { | 1004 | { |
| 1005 | // [0]: _DYNAMIC | 1005 | // [0]: _DYNAMIC |
| 1006 | const symbol = elf_file.symbol(elf_file.dynamic_index.?); | 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 | // [1]: 0x0 | 1009 | // [1]: 0x0 |
| 1010 | // [2]: 0x0 | 1010 | // [2]: 0x0 |