elf: correctly format output .eh_frame when emitting relocatable
This commit is contained in:
@@ -1446,8 +1446,6 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
|
||||
// Now, we are ready to resolve the symbols across all input files.
|
||||
// We will first resolve the files in the ZigObject, next in the parsed
|
||||
// input Object files.
|
||||
// Any qualifing unresolved symbol will be upgraded to an absolute, weak
|
||||
// symbol for potential resolution at load-time.
|
||||
self.resolveSymbols();
|
||||
self.markEhFrameAtomsDead();
|
||||
self.claimUnresolvedObject();
|
||||
@@ -4037,11 +4035,10 @@ fn sortShdrs(self: *Elf) !void {
|
||||
shdr.sh_info = self.plt_section_index.?;
|
||||
}
|
||||
|
||||
for (self.shdrs.items) |*shdr| {
|
||||
if (shdr.sh_type == elf.SHT_RELA and shdr.sh_flags & elf.SHF_INFO_LINK != 0) {
|
||||
shdr.sh_link = self.symtab_section_index.?;
|
||||
shdr.sh_info = backlinks[shdr.sh_info];
|
||||
}
|
||||
if (self.eh_frame_rela_section_index) |index| {
|
||||
const shdr = &self.shdrs.items[index];
|
||||
shdr.sh_link = self.symtab_section_index.?;
|
||||
shdr.sh_info = self.eh_frame_section_index.?;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -4122,6 +4119,12 @@ fn sortShdrs(self: *Elf) !void {
|
||||
global.output_section_index = backlinks[out_shndx];
|
||||
}
|
||||
}
|
||||
|
||||
for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| {
|
||||
const shdr = &self.shdrs.items[sec.shndx];
|
||||
shdr.sh_link = self.symtab_section_index.?;
|
||||
shdr.sh_info = shndx;
|
||||
}
|
||||
}
|
||||
|
||||
fn updateSectionSizes(self: *Elf) !void {
|
||||
@@ -5009,7 +5012,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
|
||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size);
|
||||
defer buffer.deinit();
|
||||
try eh_frame.writeEhFrame(self, buffer.writer());
|
||||
try eh_frame.writeEhFrameObject(self, buffer.writer());
|
||||
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
|
||||
}
|
||||
if (self.eh_frame_rela_section_index) |shndx| {
|
||||
|
||||
@@ -687,7 +687,6 @@ pub fn initRelaSections(self: Object, elf_file: *Elf) !void {
|
||||
const out_shdr = &elf_file.shdrs.items[out_shndx];
|
||||
out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela);
|
||||
out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela);
|
||||
out_shdr.sh_info = self.initOutputSection(elf_file, atom.inputShdr(elf_file)) catch unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,13 +694,18 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void {
|
||||
for (self.atoms.items) |atom_index| {
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const shndx = atom.relocsShndx() orelse continue;
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
const out_shndx = self.initOutputSection(elf_file, shdr) catch unreachable;
|
||||
const shndx = blk: {
|
||||
const shndx = atom.relocsShndx() orelse continue;
|
||||
const shdr = self.shdrs.items[shndx];
|
||||
break :blk self.initOutputSection(elf_file, shdr) catch unreachable;
|
||||
};
|
||||
const shdr = &elf_file.shdrs.items[shndx];
|
||||
shdr.sh_info = atom.outputShndx().?;
|
||||
shdr.sh_link = elf_file.symtab_section_index.?;
|
||||
|
||||
const gpa = elf_file.base.allocator;
|
||||
const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom.outputShndx().?);
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = out_shndx };
|
||||
if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx };
|
||||
try gop.value_ptr.atom_list.append(gpa, atom_index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +268,11 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize {
|
||||
}
|
||||
}
|
||||
|
||||
return offset + 4; // NULL terminator
|
||||
if (!elf_file.isRelocatable()) {
|
||||
offset += 4; // NULL terminator
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
pub fn calcEhFrameHdrSize(elf_file: *Elf) usize {
|
||||
@@ -373,6 +377,39 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
|
||||
try writer.writeInt(u32, 0, .little);
|
||||
}
|
||||
|
||||
pub fn writeEhFrameObject(elf_file: *Elf, writer: anytype) !void {
|
||||
const gpa = elf_file.base.allocator;
|
||||
|
||||
for (elf_file.objects.items) |index| {
|
||||
const object = elf_file.file(index).?.object;
|
||||
|
||||
for (object.cies.items) |cie| {
|
||||
if (!cie.alive) continue;
|
||||
try writer.writeAll(cie.data(elf_file));
|
||||
}
|
||||
}
|
||||
|
||||
for (elf_file.objects.items) |index| {
|
||||
const object = elf_file.file(index).?.object;
|
||||
|
||||
for (object.fdes.items) |fde| {
|
||||
if (!fde.alive) continue;
|
||||
|
||||
const contents = try gpa.dupe(u8, fde.data(elf_file));
|
||||
defer gpa.free(contents);
|
||||
|
||||
std.mem.writeInt(
|
||||
i32,
|
||||
contents[4..8],
|
||||
@truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset))),
|
||||
.little,
|
||||
);
|
||||
|
||||
try writer.writeAll(contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela {
|
||||
const r_offset = rec.address(elf_file) + rel.r_offset - rec.offset;
|
||||
const r_type = rel.r_type();
|
||||
|
||||
Reference in New Issue
Block a user