mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
zld: add/fix more issues
* fix debug info for static archives * allow handling of empty object files * fix some relocs for GOT loads
This commit is contained in:
parent
de209afbba
commit
ac0c669473
@ -202,13 +202,17 @@ fn readObject(self: *Archive, arch: std.Target.Cpu.Arch, ar_name: []const u8, re
|
||||
var object = Object{
|
||||
.allocator = self.allocator,
|
||||
.name = object_name,
|
||||
.ar_name = try mem.dupe(self.allocator, u8, ar_name),
|
||||
.file = new_file,
|
||||
.header = header,
|
||||
};
|
||||
|
||||
try object.readLoadCommands(reader, .{ .offset = offset });
|
||||
try object.readSymtab();
|
||||
try object.readStrtab();
|
||||
|
||||
if (object.symtab_cmd.index != null) {
|
||||
try object.readSymtab();
|
||||
try object.readStrtab();
|
||||
}
|
||||
|
||||
if (object.data_in_code_cmd_index != null) try object.readDataInCode();
|
||||
|
||||
|
@ -16,6 +16,7 @@ usingnamespace @import("commands.zig");
|
||||
allocator: *Allocator,
|
||||
file: fs.File,
|
||||
name: []u8,
|
||||
ar_name: ?[]u8 = null,
|
||||
|
||||
header: macho.mach_header_64,
|
||||
|
||||
@ -49,6 +50,9 @@ pub fn deinit(self: *Object) void {
|
||||
self.strtab.deinit(self.allocator);
|
||||
self.data_in_code_entries.deinit(self.allocator);
|
||||
self.allocator.free(self.name);
|
||||
if (self.ar_name) |v| {
|
||||
self.allocator.free(v);
|
||||
}
|
||||
self.file.close();
|
||||
}
|
||||
|
||||
@ -85,8 +89,11 @@ pub fn initFromFile(allocator: *Allocator, arch: std.Target.Cpu.Arch, name: []co
|
||||
};
|
||||
|
||||
try self.readLoadCommands(reader, .{});
|
||||
try self.readSymtab();
|
||||
try self.readStrtab();
|
||||
|
||||
if (self.symtab_cmd_index != null) {
|
||||
try self.readSymtab();
|
||||
try self.readStrtab();
|
||||
}
|
||||
|
||||
if (self.data_in_code_cmd_index != null) try self.readDataInCode();
|
||||
|
||||
|
@ -767,7 +767,9 @@ fn resolveImports(self: *Zld) !void {
|
||||
mem.eql(u8, sym_name, "___stderrp") or
|
||||
mem.eql(u8, sym_name, "___stdinp") or
|
||||
mem.eql(u8, sym_name, "___stack_chk_guard") or
|
||||
mem.eql(u8, sym_name, "_environ"))
|
||||
mem.eql(u8, sym_name, "_environ") or
|
||||
mem.eql(u8, sym_name, "__DefaultRuneLocale") or
|
||||
mem.eql(u8, sym_name, "_mach_task_self_"))
|
||||
{
|
||||
log.debug("writing nonlazy symbol '{s}'", .{sym_name});
|
||||
const index = @intCast(u32, self.nonlazy_imports.items().len);
|
||||
@ -1192,6 +1194,8 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void {
|
||||
fn resolveSymbols(self: *Zld) !void {
|
||||
for (self.objects.items) |object, object_id| {
|
||||
const seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
|
||||
log.debug("\n\n", .{});
|
||||
log.debug("resolving symbols in {s}", .{object.name});
|
||||
|
||||
for (object.symtab.items) |sym| {
|
||||
if (isImport(&sym)) continue;
|
||||
@ -1219,8 +1223,10 @@ fn resolveSymbols(self: *Zld) !void {
|
||||
if (tt == .Global) {
|
||||
for (locs.entry.value.items) |ss| {
|
||||
if (ss.tt == .Global) {
|
||||
log.err("symbol '{s}' defined multiple times", .{sym_name});
|
||||
return error.MultipleSymbolDefinitions;
|
||||
log.debug("symbol already defined '{s}'", .{sym_name});
|
||||
continue;
|
||||
// log.err("symbol '{s}' defined multiple times: {}", .{ sym_name, sym });
|
||||
// return error.MultipleSymbolDefinitions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1589,8 +1595,28 @@ fn doRelocs(self: *Zld) !void {
|
||||
),
|
||||
inst,
|
||||
);
|
||||
|
||||
const ta = if (addend) |a| target_addr + a else target_addr;
|
||||
const narrowed = @truncate(u12, ta);
|
||||
log.debug(" | narrowed 0x{x}", .{narrowed});
|
||||
log.debug(" | parsed.size 0x{x}", .{parsed.size});
|
||||
|
||||
if (rel_type == .ARM64_RELOC_GOT_LOAD_PAGEOFF12) blk: {
|
||||
const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
|
||||
const got = data_const_seg.sections.items[self.got_section_index.?];
|
||||
if (got.addr <= target_addr and target_addr < got.addr + got.size) break :blk;
|
||||
|
||||
log.debug(" | rewriting to add", .{});
|
||||
mem.writeIntLittle(u32, inst, aarch64.Instruction.add(
|
||||
@intToEnum(aarch64.Register, parsed.rt),
|
||||
@intToEnum(aarch64.Register, parsed.rn),
|
||||
narrowed,
|
||||
false,
|
||||
).toU32());
|
||||
addend = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
const offset: u12 = blk: {
|
||||
if (parsed.size == 0) {
|
||||
if (parsed.v == 1) {
|
||||
@ -2628,8 +2654,16 @@ fn writeDebugInfo(self: *Zld) !void {
|
||||
});
|
||||
// Path to object file with debug info
|
||||
var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const path = object.name;
|
||||
const full_path = try std.os.realpath(path, &buffer);
|
||||
const full_path = blk: {
|
||||
if (object.ar_name) |prefix| {
|
||||
const path = try std.os.realpath(prefix, &buffer);
|
||||
break :blk try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ path, object.name });
|
||||
} else {
|
||||
const path = try std.os.realpath(object.name, &buffer);
|
||||
break :blk try mem.dupe(self.allocator, u8, path);
|
||||
}
|
||||
};
|
||||
defer self.allocator.free(full_path);
|
||||
const stat = try object.file.stat();
|
||||
const mtime = @intCast(u64, @divFloor(stat.mtime, 1_000_000_000));
|
||||
try stabs.append(.{
|
||||
@ -2640,6 +2674,7 @@ fn writeDebugInfo(self: *Zld) !void {
|
||||
.n_value = mtime,
|
||||
});
|
||||
}
|
||||
log.debug("analyzing debug info in '{s}'", .{object.name});
|
||||
|
||||
for (object.symtab.items) |source_sym| {
|
||||
const symname = object.getString(source_sym.n_strx);
|
||||
|
Loading…
Reference in New Issue
Block a user