Commit 775a161794
Changed files (2)
src
link
src/link/Elf/eh_frame.zig
@@ -317,7 +317,7 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
});
switch (cpu_arch) {
- .x86_64 => x86_64.resolveReloc(rel, P, S + A, contents[offset..]),
+ .x86_64 => try x86_64.resolveReloc(rec, elf_file, rel, P, S + A, contents[offset..]),
else => return error.UnsupportedCpuArch,
}
}
@@ -325,6 +325,8 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
+ var has_reloc_errors = false;
+
for (elf_file.objects.items) |index| {
const object = elf_file.file(index).?.object;
@@ -335,7 +337,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
for (cie.relocs(elf_file)) |rel| {
const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
- try resolveReloc(cie, sym, rel, elf_file, contents);
+ resolveReloc(cie, sym, rel, elf_file, contents) catch |err| switch (err) {
+ error.RelocFailure => has_reloc_errors = true,
+ else => |e| return e,
+ };
}
try writer.writeAll(contents);
@@ -359,7 +364,10 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
for (fde.relocs(elf_file)) |rel| {
const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
- try resolveReloc(fde, sym, rel, elf_file, contents);
+ resolveReloc(fde, sym, rel, elf_file, contents) catch |err| switch (err) {
+ error.RelocFailure => has_reloc_errors = true,
+ else => |e| return e,
+ };
}
try writer.writeAll(contents);
@@ -367,6 +375,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
}
try writer.writeInt(u32, 0, .little);
+
+ if (has_reloc_errors) return error.RelocFailure;
}
pub fn writeEhFrameObject(elf_file: *Elf, writer: anytype) !void {
@@ -540,18 +550,29 @@ const EH_PE = struct {
};
const x86_64 = struct {
- fn resolveReloc(rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) void {
+ fn resolveReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) !void {
const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
switch (r_type) {
+ .NONE => {},
.@"32" => std.mem.writeInt(i32, data[0..4], @as(i32, @truncate(target)), .little),
.@"64" => std.mem.writeInt(i64, data[0..8], target, .little),
.PC32 => std.mem.writeInt(i32, data[0..4], @as(i32, @intCast(target - source)), .little),
.PC64 => std.mem.writeInt(i64, data[0..8], target - source, .little),
- else => unreachable,
+ else => try reportInvalidReloc(rec, elf_file, rel),
}
}
};
+fn reportInvalidReloc(rec: anytype, elf_file: *Elf, rel: elf.Elf64_Rela) !void {
+ var err = try elf_file.addErrorWithNotes(1);
+ try err.addMsg(elf_file, "invalid relocation type {} at offset 0x{x}", .{
+ relocation.fmtRelocType(rel.r_type(), elf_file.getTarget().cpu.arch),
+ rel.r_offset,
+ });
+ try err.addNote(elf_file, "in {}:.eh_frame", .{elf_file.file(rec.file_index).?.fmtPath()});
+ return error.RelocFailure;
+}
+
const std = @import("std");
const assert = std.debug.assert;
const elf = std.elf;
src/link/Elf.zig
@@ -1371,14 +1371,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node)
try self.writePhdrTable();
try self.writeShdrTable();
try self.writeAtoms();
-
- self.writeSyntheticSections() catch |err| switch (err) {
- error.UnsupportedCpuArch => {
- try self.reportUnsupportedCpuArch();
- return error.FlushFailure;
- },
- else => |e| return e,
- };
+ try self.writeSyntheticSections();
if (self.entry_index == null and self.base.isExe()) {
log.debug("flushing. no_entry_point_found = true", .{});
@@ -4689,7 +4682,14 @@ fn writeSyntheticSections(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());
+ eh_frame.writeEhFrame(self, buffer.writer()) catch |err| switch (err) {
+ error.RelocFailure => return error.FlushFailure,
+ error.UnsupportedCpuArch => {
+ try self.reportUnsupportedCpuArch();
+ return error.FlushFailure;
+ },
+ else => |e| return e,
+ };
try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset);
}