mirror of
https://github.com/ziglang/zig.git
synced 2026-01-04 20:43:19 +00:00
elf: emit .rela.debug* sections for relocatable if required
This commit is contained in:
parent
517721bbcc
commit
d3d5ed992c
@ -56,17 +56,17 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
|
||||
const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset + 4,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | lo_r_type,
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
},
|
||||
.load_tlv_reloc => |symbol| {
|
||||
const elf_file = emit.bin_file.cast(.elf).?;
|
||||
@ -76,23 +76,23 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
|
||||
const R_RISCV = std.elf.R_RISCV;
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_HI20),
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset + 4,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_ADD),
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset + 8,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | @intFromEnum(R_RISCV.TPREL_LO12_I),
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
},
|
||||
.call_extern_fn_reloc => |symbol| {
|
||||
const elf_file = emit.bin_file.cast(.elf).?;
|
||||
@ -101,11 +101,11 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
|
||||
const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
|
||||
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = start_offset,
|
||||
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
|
||||
.r_addend = 0,
|
||||
});
|
||||
}, zo);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -48,11 +48,11 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
const atom_ptr = zo.symbol(emit.atom_index).atom(elf_file).?;
|
||||
const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
|
||||
try atom_ptr.addReloc(elf_file, .{
|
||||
try atom_ptr.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = end_offset - 4,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = lowered_relocs[0].off - 4,
|
||||
});
|
||||
}, zo);
|
||||
} else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
|
||||
// Add relocation to the decl.
|
||||
const zo = macho_file.getZigObject().?;
|
||||
@ -95,22 +95,22 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
|
||||
const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
|
||||
try atom.addReloc(elf_file, .{
|
||||
try atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = end_offset - 4,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = lowered_relocs[0].off - 4,
|
||||
});
|
||||
}, zo);
|
||||
},
|
||||
.linker_dtpoff => |sym_index| {
|
||||
const elf_file = emit.lower.bin_file.cast(.elf).?;
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
const atom = zo.symbol(emit.atom_index).atom(elf_file).?;
|
||||
const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
|
||||
try atom.addReloc(elf_file, .{
|
||||
try atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = end_offset - 4,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = lowered_relocs[0].off,
|
||||
});
|
||||
}, zo);
|
||||
},
|
||||
.linker_reloc => |sym_index| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
@ -121,21 +121,21 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
@intFromEnum(std.elf.R_X86_64.GOTPCREL)
|
||||
else
|
||||
@intFromEnum(std.elf.R_X86_64.PC32);
|
||||
try atom.addReloc(elf_file, .{
|
||||
try atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = end_offset - 4,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = lowered_relocs[0].off - 4,
|
||||
});
|
||||
}, zo);
|
||||
} else {
|
||||
const r_type: u32 = if (sym.flags.is_tls)
|
||||
@intFromEnum(std.elf.R_X86_64.TPOFF32)
|
||||
else
|
||||
@intFromEnum(std.elf.R_X86_64.@"32");
|
||||
try atom.addReloc(elf_file, .{
|
||||
try atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = end_offset - 4,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = lowered_relocs[0].off,
|
||||
});
|
||||
}, zo);
|
||||
}
|
||||
} else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
|
||||
@ -302,7 +302,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void {
|
||||
}
|
||||
|
||||
// TODO create relocs free list
|
||||
self.freeRelocs(elf_file);
|
||||
self.freeRelocs(zo);
|
||||
// TODO figure out how to free input section mappind in ZigModule
|
||||
// const zig_object = elf_file.zigObjectPtr().?
|
||||
// assert(zig_object.atoms.swapRemove(self.atom_index));
|
||||
@ -377,21 +377,19 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void {
|
||||
const comp = elf_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const file_ptr = self.file(elf_file).?;
|
||||
assert(file_ptr == .zig_object);
|
||||
const zig_object = file_ptr.zig_object;
|
||||
const rels = &zig_object.relocs.items[self.relocs_section_index];
|
||||
try rels.append(gpa, reloc);
|
||||
pub fn addReloc(self: Atom, alloc: Allocator, reloc: elf.Elf64_Rela, zo: *ZigObject) !void {
|
||||
const rels = &zo.relocs.items[self.relocs_section_index];
|
||||
try rels.ensureUnusedCapacity(alloc, 1);
|
||||
self.addRelocAssumeCapacity(reloc, zo);
|
||||
}
|
||||
|
||||
pub fn freeRelocs(self: Atom, elf_file: *Elf) void {
|
||||
const file_ptr = self.file(elf_file).?;
|
||||
assert(file_ptr == .zig_object);
|
||||
const zig_object = file_ptr.zig_object;
|
||||
zig_object.relocs.items[self.relocs_section_index].clearRetainingCapacity();
|
||||
pub fn addRelocAssumeCapacity(self: Atom, reloc: elf.Elf64_Rela, zo: *ZigObject) void {
|
||||
const rels = &zo.relocs.items[self.relocs_section_index];
|
||||
rels.appendAssumeCapacity(reloc);
|
||||
}
|
||||
|
||||
pub fn freeRelocs(self: Atom, zo: *ZigObject) void {
|
||||
zo.relocs.items[self.relocs_section_index].clearRetainingCapacity();
|
||||
}
|
||||
|
||||
pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {
|
||||
|
||||
@ -182,6 +182,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
try dwarf.flushModule(pt);
|
||||
try dwarf.resolveRelocs();
|
||||
|
||||
const gpa = elf_file.base.comp.gpa;
|
||||
|
||||
// TODO invert this logic so that we manage the output section with the atom, not the
|
||||
// other way around
|
||||
for ([_]u32{
|
||||
@ -206,24 +208,47 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
const sym = self.symbol(sym_index);
|
||||
const atom_ptr = self.atom(sym.ref.index).?;
|
||||
if (!atom_ptr.alive) continue;
|
||||
const shdr = elf_file.shdrs.items[sym.outputShndx(elf_file).?];
|
||||
const shndx = sym.outputShndx(elf_file).?;
|
||||
const shdr = elf_file.shdrs.items[shndx];
|
||||
const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
|
||||
esym.st_size = shdr.sh_size;
|
||||
atom_ptr.size = shdr.sh_size;
|
||||
atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
|
||||
|
||||
const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];
|
||||
_ = relocs;
|
||||
for (sect.units.items) |*unit| {
|
||||
try relocs.ensureUnusedCapacity(gpa, unit.external_relocs.items.len);
|
||||
for (unit.external_relocs.items) |reloc| {
|
||||
const tsym = self.symbol(reloc.target_sym);
|
||||
const r_offset = unit.off + unit.header_len + unit.getEntry(reloc.source_entry).off + reloc.source_off;
|
||||
const r_addend = reloc.target_off;
|
||||
std.debug.print("{s} <- r_off={x}, r_add={x}\n", .{
|
||||
const r_addend: i64 = @intCast(reloc.target_off);
|
||||
const r_type: elf.R_X86_64 = switch (dwarf.address_size) {
|
||||
.@"32" => .@"32",
|
||||
.@"64" => .@"64",
|
||||
else => unreachable,
|
||||
};
|
||||
log.debug("{s} <- r_off={x}, r_add={x}, r_type={s}\n", .{
|
||||
tsym.name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
@tagName(r_type),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
.r_info = (@as(u64, @intCast(reloc.target_sym)) << 32) | @intFromEnum(r_type),
|
||||
}, self);
|
||||
}
|
||||
}
|
||||
|
||||
if (elf_file.base.isRelocatable() and relocs.items.len > 0) {
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, shndx);
|
||||
if (!gop.found_existing) {
|
||||
const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{elf_file.getShString(shdr.sh_name)});
|
||||
defer gpa.free(rela_sect_name);
|
||||
const rela_sh_name = try elf_file.insertShString(rela_sect_name);
|
||||
const rela_shndx = try elf_file.addRelaShdr(rela_sh_name, shndx);
|
||||
gop.value_ptr.* = .{ .shndx = rela_shndx };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -698,11 +723,11 @@ pub fn getNavVAddr(
|
||||
const vaddr = this_sym.address(.{}, elf_file);
|
||||
const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
|
||||
const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
|
||||
try parent_atom.addReloc(elf_file, .{
|
||||
try parent_atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = reloc_info.offset,
|
||||
.r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
|
||||
.r_addend = reloc_info.addend,
|
||||
});
|
||||
}, self);
|
||||
return @intCast(vaddr);
|
||||
}
|
||||
|
||||
@ -717,11 +742,11 @@ pub fn getUavVAddr(
|
||||
const vaddr = sym.address(.{}, elf_file);
|
||||
const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
|
||||
const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
|
||||
try parent_atom.addReloc(elf_file, .{
|
||||
try parent_atom.addReloc(elf_file.base.comp.gpa, .{
|
||||
.r_offset = reloc_info.offset,
|
||||
.r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
|
||||
.r_addend = reloc_info.addend,
|
||||
});
|
||||
}, self);
|
||||
return @intCast(vaddr);
|
||||
}
|
||||
|
||||
@ -1068,7 +1093,7 @@ pub fn updateFunc(
|
||||
log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav });
|
||||
|
||||
const sym_index = try self.getOrCreateMetadataForNav(elf_file, func.owner_nav);
|
||||
self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
||||
self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
@ -1196,7 +1221,7 @@ pub fn updateNav(
|
||||
|
||||
if (nav_init != .none and Value.fromInterned(nav_init).typeOf(zcu).hasRuntimeBits(pt)) {
|
||||
const sym_index = try self.getOrCreateMetadataForNav(elf_file, nav_index);
|
||||
self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
||||
self.symbol(sym_index).atom(elf_file).?.freeRelocs(self);
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(zcu.gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user