zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit ef8a666797d6fb2849762dd157379ca227762c90 (tree)
parent ad33e34836866e0528ca7601155c5dafe538347b
Author: Jakub Konka <kubkon@jakubkonka.com>
Date:   Wed,  5 May 2021 09:21:32 +0200

zld: cleanup relocs and flag errors on unhandled symbol types

Diffstat:
Msrc/link/MachO/Object.zig | 24++++++++++++++++++++----
Msrc/link/MachO/Symbol.zig | 10++++++++++
Msrc/link/MachO/Zld.zig | 9+++++++++
Msrc/link/MachO/reloc/aarch64.zig | 2+-
4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig @@ -343,14 +343,22 @@ pub fn parseSymbols(self: *Object) !void { _ = try self.file.?.preadAll(strtab, symtab_cmd.stroff); for (slice) |sym| { + const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx)); + if (Symbol.isStab(sym)) { - log.err("TODO handle stabs embedded within object files", .{}); - return error.HandleStabsInObjects; + log.err("stab {s} in {s}", .{ sym_name, self.name.? }); + return error.UnhandledSymbolType; + } + if (Symbol.isIndr(sym)) { + log.err("indirect symbol {s} in {s}", .{ sym_name, self.name.? }); + return error.UnhandledSymbolType; + } + if (Symbol.isAbs(sym)) { + log.err("absolute symbol {s} in {s}", .{ sym_name, self.name.? }); + return error.UnhandledSymbolType; } - const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx)); const name = try self.allocator.dupe(u8, sym_name); - const symbol: *Symbol = symbol: { if (Symbol.isSect(sym)) { const linkage: Symbol.Regular.Linkage = linkage: { @@ -374,6 +382,14 @@ pub fn parseSymbols(self: *Object) !void { break :symbol &regular.base; } + if (sym.n_value != 0) { + log.err("common symbol {s} in {s}", .{ sym_name, self.name.? }); + return error.UnhandledSymbolType; + // const comm_size = sym.n_value; + // const comm_align = (sym.n_desc >> 8) & 0x0f; + // log.warn("Common symbol: size 0x{x}, align 0x{x}", .{ comm_size, comm_align }); + } + const undef = try self.allocator.create(Symbol.Unresolved); errdefer self.allocator.destroy(undef); undef.* = .{ diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig @@ -133,6 +133,16 @@ pub fn isUndf(sym: macho.nlist_64) bool { return type_ == macho.N_UNDF; } +pub fn isIndr(sym: macho.nlist_64) bool { + const type_ = macho.N_TYPE & sym.n_type; + return type_ == macho.N_INDR; +} + +pub fn isAbs(sym: macho.nlist_64) bool { + const type_ = macho.N_TYPE & sym.n_type; + return type_ == macho.N_ABS; +} + pub fn isWeakDef(sym: macho.nlist_64) bool { return (sym.n_desc & macho.N_WEAK_DEF) != 0; } diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig @@ -1553,9 +1553,16 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { // TLV is handled via a separate offset mechanism. // Calculate the offset to the initializer. if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { + log.warn("HIT", .{}); + log.warn(" | rel {any}", .{rel.cast(reloc.Unsigned).?}); + log.warn(" | name {s}", .{rel.target.symbol.name}); + log.warn(" | target address 0x{x}", .{args.target_addr}); + // TODO we don't want to save offset to tlv_bootstrap if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv; + log.warn(" | object {s}", .{rel.target.symbol.cast(Symbol.Regular).?.file.name.?}); + const base_addr = blk: { if (self.tlv_data_section_index) |index| { const tlv_data = target_seg.sections.items[index]; @@ -1565,6 +1572,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { break :blk tlv_bss.addr; } }; + log.warn(" | base address 0x{x}", .{base_addr}); + log.warn(" | offset 0x{x}", .{args.target_addr - base_addr}); // Since we require TLV data to always preceed TLV bss section, we calculate // offsets wrt to the former if it is defined; otherwise, wrt to the latter. try self.threadlocal_offsets.append(self.allocator, args.target_addr - base_addr); diff --git a/src/link/MachO/reloc/aarch64.zig b/src/link/MachO/reloc/aarch64.zig @@ -25,7 +25,7 @@ pub const Branch = struct { log.debug(" | displacement 0x{x}", .{displacement}); var inst = branch.inst; - inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement) >> 2); + inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement >> 2)); mem.writeIntLittle(u32, branch.base.code[0..4], inst.toU32()); } };