authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-19 08:17:28+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-21 01:43:21-04:00
logd3d5ed992c339ef114115fb621e0659ce121e027
tree397782fb0131dc932f53db662d080c3ab673c024
parent517721bbccbbbe571c90226197948a9ae2430d8f

elf: emit .rela.debug* sections for relocatable if required


4 files changed, 69 insertions(+), 46 deletions(-)

src/arch/riscv64/Emit.zig+12-12
...@@ -56,17 +56,17 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -56,17 +56,17 @@ pub fn emitMir(emit: *Emit) Error!void {
56 const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);56 const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
57 const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);57 const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
5858
59 try atom_ptr.addReloc(elf_file, .{59 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
60 .r_offset = start_offset,60 .r_offset = start_offset,
61 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,61 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
62 .r_addend = 0,62 .r_addend = 0,
63 });63 }, zo);
6464
65 try atom_ptr.addReloc(elf_file, .{65 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
66 .r_offset = start_offset + 4,66 .r_offset = start_offset + 4,
67 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,67 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
68 .r_addend = 0,68 .r_addend = 0,
69 });69 }, zo);
70 },70 },
71 .load_tlv_reloc => |symbol| {71 .load_tlv_reloc => |symbol| {
72 const elf_file = emit.bin_file.cast(.elf).?;72 const elf_file = emit.bin_file.cast(.elf).?;
...@@ -76,23 +76,23 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -76,23 +76,23 @@ pub fn emitMir(emit: *Emit) Error!void {
7676
77 const R_RISCV = std.elf.R_RISCV;77 const R_RISCV = std.elf.R_RISCV;
7878
79 try atom_ptr.addReloc(elf_file, .{79 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
80 .r_offset = start_offset,80 .r_offset = start_offset,
81 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20),81 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20),
82 .r_addend = 0,82 .r_addend = 0,
83 });83 }, zo);
8484
85 try atom_ptr.addReloc(elf_file, .{85 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
86 .r_offset = start_offset + 4,86 .r_offset = start_offset + 4,
87 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD),87 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD),
88 .r_addend = 0,88 .r_addend = 0,
89 });89 }, zo);
9090
91 try atom_ptr.addReloc(elf_file, .{91 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
92 .r_offset = start_offset + 8,92 .r_offset = start_offset + 8,
93 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I),93 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I),
94 .r_addend = 0,94 .r_addend = 0,
95 });95 }, zo);
96 },96 },
97 .call_extern_fn_reloc => |symbol| {97 .call_extern_fn_reloc => |symbol| {
98 const elf_file = emit.bin_file.cast(.elf).?;98 const elf_file = emit.bin_file.cast(.elf).?;
...@@ -101,11 +101,11 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -101,11 +101,11 @@ pub fn emitMir(emit: *Emit) Error!void {
101101
102 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);102 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
103103
104 try atom_ptr.addReloc(elf_file, .{104 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
105 .r_offset = start_offset,105 .r_offset = start_offset,
106 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,106 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
107 .r_addend = 0,107 .r_addend = 0,
108 });108 }, zo);
109 },109 },
110 };110 };
111 }111 }
src/arch/x86_64/Emit.zig+10-10
...@@ -48,11 +48,11 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -48,11 +48,11 @@ pub fn emitMir(emit: *Emit) Error!void {
48 const zo = elf_file.zigObjectPtr().?;48 const zo = elf_file.zigObjectPtr().?;
49 const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?;49 const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?;
50 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);50 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
51 try atom_ptr.addReloc(elf_file, .{51 try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
52 .r_offset = end_offset - 4,52 .r_offset = end_offset - 4,
53 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,53 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
54 .r_addend = lowered_relocs[0].off - 4,54 .r_addend = lowered_relocs[0].off - 4,
55 });55 }, zo);
56 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {56 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
57 // Add relocation to the decl.57 // Add relocation to the decl.
58 const zo = macho_file.getZigObject().?;58 const zo = macho_file.getZigObject().?;
...@@ -95,22 +95,22 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -95,22 +95,22 @@ pub fn emitMir(emit: *Emit) Error!void {
95 const zo = elf_file.zigObjectPtr().?;95 const zo = elf_file.zigObjectPtr().?;
96 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;96 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
97 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);97 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
98 try atom.addReloc(elf_file, .{98 try atom.addReloc(elf_file.base.comp.gpa, .{
99 .r_offset = end_offset - 4,99 .r_offset = end_offset - 4,
100 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,100 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
101 .r_addend = lowered_relocs[0].off - 4,101 .r_addend = lowered_relocs[0].off - 4,
102 });102 }, zo);
103 },103 },
104 .linker_dtpoff => |sym_index| {104 .linker_dtpoff => |sym_index| {
105 const elf_file = emit.lower.bin_file.cast(.elf).?;105 const elf_file = emit.lower.bin_file.cast(.elf).?;
106 const zo = elf_file.zigObjectPtr().?;106 const zo = elf_file.zigObjectPtr().?;
107 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;107 const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
108 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);108 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
109 try atom.addReloc(elf_file, .{109 try atom.addReloc(elf_file.base.comp.gpa, .{
110 .r_offset = end_offset - 4,110 .r_offset = end_offset - 4,
111 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,111 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
112 .r_addend = lowered_relocs[0].off,112 .r_addend = lowered_relocs[0].off,
113 });113 }, zo);
114 },114 },
115 .linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| {115 .linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
116 const zo = elf_file.zigObjectPtr().?;116 const zo = elf_file.zigObjectPtr().?;
...@@ -121,21 +121,21 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -121,21 +121,21 @@ pub fn emitMir(emit: *Emit) Error!void {
121 @intFromEnum(std.elf.R_X86_64.GOTPCREL)121 @intFromEnum(std.elf.R_X86_64.GOTPCREL)
122 else122 else
123 @intFromEnum(std.elf.R_X86_64.PC32);123 @intFromEnum(std.elf.R_X86_64.PC32);
124 try atom.addReloc(elf_file, .{124 try atom.addReloc(elf_file.base.comp.gpa, .{
125 .r_offset = end_offset - 4,125 .r_offset = end_offset - 4,
126 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,126 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
127 .r_addend = lowered_relocs[0].off - 4,127 .r_addend = lowered_relocs[0].off - 4,
128 });128 }, zo);
129 } else {129 } else {
130 const r_type: u32 = if (sym.flags.is_tls)130 const r_type: u32 = if (sym.flags.is_tls)
131 @intFromEnum(std.elf.R_X86_64.TPOFF32)131 @intFromEnum(std.elf.R_X86_64.TPOFF32)
132 else132 else
133 @intFromEnum(std.elf.R_X86_64.@"32");133 @intFromEnum(std.elf.R_X86_64.@"32");
134 try atom.addReloc(elf_file, .{134 try atom.addReloc(elf_file.base.comp.gpa, .{
135 .r_offset = end_offset - 4,135 .r_offset = end_offset - 4,
136 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,136 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
137 .r_addend = lowered_relocs[0].off,137 .r_addend = lowered_relocs[0].off,
138 });138 }, zo);
139 }139 }
140 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {140 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
141 const zo = macho_file.getZigObject().?;141 const zo = macho_file.getZigObject().?;
src/link/Elf/Atom.zig+12-14
...@@ -302,7 +302,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void {...@@ -302,7 +302,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
302 }302 }
303303
304 // TODO create relocs free list304 // TODO create relocs free list
305 self.freeRelocs(elf_file);305 self.freeRelocs(zo);
306 // TODO figure out how to free input section mappind in ZigModule306 // TODO figure out how to free input section mappind in ZigModule
307 // const zig_object = elf_file.zigObjectPtr().?307 // const zig_object = elf_file.zigObjectPtr().?
308 // assert(zig_object.atoms.swapRemove(self.atom_index));308 // assert(zig_object.atoms.swapRemove(self.atom_index));
...@@ -377,21 +377,19 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void {...@@ -377,21 +377,19 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void {
377 }377 }
378}378}
379379
380pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void {380pub fn addReloc(self: Atom, alloc: Allocator, reloc: elf.Elf64_Rela, zo: *ZigObject) !void {
381 const comp = elf_file.base.comp;381 const rels = &zo.relocs.items[self.relocs_section_index];
382 const gpa = comp.gpa;382 try rels.ensureUnusedCapacity(alloc, 1);
383 const file_ptr = self.file(elf_file).?;383 self.addRelocAssumeCapacity(reloc, zo);
384 assert(file_ptr == .zig_object);
385 const zig_object = file_ptr.zig_object;
386 const rels = &zig_object.relocs.items[self.relocs_section_index];
387 try rels.append(gpa, reloc);
388}384}
389385
390pub fn freeRelocs(self: Atom, elf_file: *Elf) void {386pub fn addRelocAssumeCapacity(self: Atom, reloc: elf.Elf64_Rela, zo: *ZigObject) void {
391 const file_ptr = self.file(elf_file).?;387 const rels = &zo.relocs.items[self.relocs_section_index];
392 assert(file_ptr == .zig_object);388 rels.appendAssumeCapacity(reloc);
393 const zig_object = file_ptr.zig_object;389}
394 zig_object.relocs.items[self.relocs_section_index].clearRetainingCapacity();390
391pub fn freeRelocs(self: Atom, zo: *ZigObject) void {
392 zo.relocs.items[self.relocs_section_index].clearRetainingCapacity();
395}393}
396394
397pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {395pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {
src/link/Elf/ZigObject.zig+35-10
...@@ -182,6 +182,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -182,6 +182,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
182 try dwarf.flushModule(pt);182 try dwarf.flushModule(pt);
183 try dwarf.resolveRelocs();183 try dwarf.resolveRelocs();
184184
185 const gpa = elf_file.base.comp.gpa;
186
185 // TODO invert this logic so that we manage the output section with the atom, not the187 // TODO invert this logic so that we manage the output section with the atom, not the
186 // other way around188 // other way around
187 for ([_]u32{189 for ([_]u32{
...@@ -206,24 +208,47 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -206,24 +208,47 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
206 const sym = self.symbol(sym_index);208 const sym = self.symbol(sym_index);
207 const atom_ptr = self.atom(sym.ref.index).?;209 const atom_ptr = self.atom(sym.ref.index).?;
208 if (!atom_ptr.alive) continue;210 if (!atom_ptr.alive) continue;
209 const shdr = elf_file.shdrs.items[sym.outputShndx(elf_file).?];211 const shndx = sym.outputShndx(elf_file).?;
212 const shdr = elf_file.shdrs.items[shndx];
210 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];213 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
211 esym.st_size = shdr.sh_size;214 esym.st_size = shdr.sh_size;
212 atom_ptr.size = shdr.sh_size;215 atom_ptr.size = shdr.sh_size;
213 atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);216 atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
214217
215 const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];218 const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];
216 _ = relocs;
217 for (sect.units.items) |*unit| {219 for (sect.units.items) |*unit| {
220 try relocs.ensureUnusedCapacity(gpa, unit.external_relocs.items.len);
218 for (unit.external_relocs.items) |reloc| {221 for (unit.external_relocs.items) |reloc| {
219 const tsym = self.symbol(reloc.target_sym);222 const tsym = self.symbol(reloc.target_sym);
220 const r_offset = unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off;223 const r_offset = unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off;
221 const r_addend = reloc.target_off;224 const r_addend: i64 = @intCast(reloc.target_off);
222 std.debug.print("{s} <- r_off={x}, r_add={x}\n", .{225 const r_type: elf.R_X86_64 = switch (dwarf.address_size) {
226 .@"32" => .@"32",
227 .@"64" => .@"64",
228 else => unreachable,
229 };
230 log.debug("{s} <- r_off={x}, r_add={x}, r_type={s}\n", .{
223 tsym.name(elf_file),231 tsym.name(elf_file),
224 r_offset,232 r_offset,
225 r_addend,233 r_addend,
234 @tagName(r_type),
226 });235 });
236 atom_ptr.addRelocAssumeCapacity(.{
237 .r_offset = r_offset,
238 .r_addend = r_addend,
239 .r_info = (@as(u64, @intCast(reloc.target_sym)) << 32) | @intFromEnum(r_type),
240 }, self);
241 }
242 }
243
244 if (elf_file.base.isRelocatable() and relocs.items.len > 0) {
245 const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx);
246 if (!gop.found_existing) {
247 const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
248 defer gpa.free(rela_sect_name);
249 const rela_sh_name = try elf_file.insertShString(rela_sect_name);
250 const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx);
251 gop.value_ptr.* = .{ .shndx = rela_shndx };
227 }252 }
228 }253 }
229 }254 }
...@@ -698,11 +723,11 @@ pub fn getNavVAddr(...@@ -698,11 +723,11 @@ pub fn getNavVAddr(
698 const vaddr = this_sym.address(.{}, elf_file);723 const vaddr = this_sym.address(.{}, elf_file);
699 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;724 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
700 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);725 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
701 try parent_atom.addReloc(elf_file, .{726 try parent_atom.addReloc(elf_file.base.comp.gpa, .{
702 .r_offset = reloc_info.offset,727 .r_offset = reloc_info.offset,
703 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,728 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
704 .r_addend = reloc_info.addend,729 .r_addend = reloc_info.addend,
705 });730 }, self);
706 return @intCast(vaddr);731 return @intCast(vaddr);
707}732}
708733
...@@ -717,11 +742,11 @@ pub fn getUavVAddr(...@@ -717,11 +742,11 @@ pub fn getUavVAddr(
717 const vaddr = sym.address(.{}, elf_file);742 const vaddr = sym.address(.{}, elf_file);
718 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;743 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
719 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);744 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
720 try parent_atom.addReloc(elf_file, .{745 try parent_atom.addReloc(elf_file.base.comp.gpa, .{
721 .r_offset = reloc_info.offset,746 .r_offset = reloc_info.offset,
722 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,747 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
723 .r_addend = reloc_info.addend,748 .r_addend = reloc_info.addend,
724 });749 }, self);
725 return @intCast(vaddr);750 return @intCast(vaddr);
726}751}
727752
...@@ -1068,7 +1093,7 @@ pub fn updateFunc(...@@ -1068,7 +1093,7 @@ pub fn updateFunc(
1068 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });1093 log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
10691094
1070 const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);1095 const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1071 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);1096 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
10721097
1073 var code_buffer = std.ArrayList(u8).init(gpa);1098 var code_buffer = std.ArrayList(u8).init(gpa);
1074 defer code_buffer.deinit();1099 defer code_buffer.deinit();
...@@ -1196,7 +1221,7 @@ pub fn updateNav(...@@ -1196,7 +1221,7 @@ pub fn updateNav(
11961221
1197 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) {1222 if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) {
1198 const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);1223 const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);
1199 self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);1224 self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
12001225
1201 var code_buffer = std.ArrayList(u8).init(zcu.gpa);1226 var code_buffer = std.ArrayList(u8).init(zcu.gpa);
1202 defer code_buffer.deinit();1227 defer code_buffer.deinit();