authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-05 09:21:32+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-06 17:09:58+02:00
logef8a666797d6fb2849762dd157379ca227762c90
tree53e7ddeef1dc091efad1ad53665b448ceba2c94f
parentad33e34836866e0528ca7601155c5dafe538347b

zld: cleanup relocs and flag errors on unhandled symbol types


4 files changed, 40 insertions(+), 5 deletions(-)

src/link/MachO/Object.zig+20-4
...@@ -343,14 +343,22 @@ pub fn parseSymbols(self: *Object) !void {...@@ -343,14 +343,22 @@ pub fn parseSymbols(self: *Object) !void {
343 _ = try self.file.?.preadAll(strtab, symtab_cmd.stroff);343 _ = try self.file.?.preadAll(strtab, symtab_cmd.stroff);
344344
345 for (slice) |sym| {345 for (slice) |sym| {
346 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx));
347
346 if (Symbol.isStab(sym)) {348 if (Symbol.isStab(sym)) {
347 log.err("TODO handle stabs embedded within object files", .{});349 log.err("stab {s} in {s}", .{ sym_name, self.name.? });
348 return error.HandleStabsInObjects;350 return error.UnhandledSymbolType;
351 }
352 if (Symbol.isIndr(sym)) {
353 log.err("indirect symbol {s} in {s}", .{ sym_name, self.name.? });
354 return error.UnhandledSymbolType;
355 }
356 if (Symbol.isAbs(sym)) {
357 log.err("absolute symbol {s} in {s}", .{ sym_name, self.name.? });
358 return error.UnhandledSymbolType;
349 }359 }
350360
351 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx));
352 const name = try self.allocator.dupe(u8, sym_name);361 const name = try self.allocator.dupe(u8, sym_name);
353
354 const symbol: *Symbol = symbol: {362 const symbol: *Symbol = symbol: {
355 if (Symbol.isSect(sym)) {363 if (Symbol.isSect(sym)) {
356 const linkage: Symbol.Regular.Linkage = linkage: {364 const linkage: Symbol.Regular.Linkage = linkage: {
...@@ -374,6 +382,14 @@ pub fn parseSymbols(self: *Object) !void {...@@ -374,6 +382,14 @@ pub fn parseSymbols(self: *Object) !void {
374 break :symbol &regular.base;382 break :symbol &regular.base;
375 }383 }
376384
385 if (sym.n_value != 0) {
386 log.err("common symbol {s} in {s}", .{ sym_name, self.name.? });
387 return error.UnhandledSymbolType;
388 // const comm_size = sym.n_value;
389 // const comm_align = (sym.n_desc >> 8) & 0x0f;
390 // log.warn("Common symbol: size 0x{x}, align 0x{x}", .{ comm_size, comm_align });
391 }
392
377 const undef = try self.allocator.create(Symbol.Unresolved);393 const undef = try self.allocator.create(Symbol.Unresolved);
378 errdefer self.allocator.destroy(undef);394 errdefer self.allocator.destroy(undef);
379 undef.* = .{395 undef.* = .{
src/link/MachO/Symbol.zig+10
...@@ -133,6 +133,16 @@ pub fn isUndf(sym: macho.nlist_64) bool {...@@ -133,6 +133,16 @@ pub fn isUndf(sym: macho.nlist_64) bool {
133 return type_ == macho.N_UNDF;133 return type_ == macho.N_UNDF;
134}134}
135135
136pub fn isIndr(sym: macho.nlist_64) bool {
137 const type_ = macho.N_TYPE & sym.n_type;
138 return type_ == macho.N_INDR;
139}
140
141pub fn isAbs(sym: macho.nlist_64) bool {
142 const type_ = macho.N_TYPE & sym.n_type;
143 return type_ == macho.N_ABS;
144}
145
136pub fn isWeakDef(sym: macho.nlist_64) bool {146pub fn isWeakDef(sym: macho.nlist_64) bool {
137 return (sym.n_desc & macho.N_WEAK_DEF) != 0;147 return (sym.n_desc & macho.N_WEAK_DEF) != 0;
138}148}
src/link/MachO/Zld.zig+9
...@@ -1553,9 +1553,16 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1553,9 +1553,16 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1553 // TLV is handled via a separate offset mechanism.1553 // TLV is handled via a separate offset mechanism.
1554 // Calculate the offset to the initializer.1554 // Calculate the offset to the initializer.
1555 if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: {1555 if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: {
1556 log.warn("HIT", .{});
1557 log.warn(" | rel {any}", .{rel.cast(reloc.Unsigned).?});
1558 log.warn(" | name {s}", .{rel.target.symbol.name});
1559 log.warn(" | target address 0x{x}", .{args.target_addr});
1560
1556 // TODO we don't want to save offset to tlv_bootstrap1561 // TODO we don't want to save offset to tlv_bootstrap
1557 if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv;1562 if (mem.eql(u8, rel.target.symbol.name, "__tlv_bootstrap")) break :tlv;
15581563
1564 log.warn(" | object {s}", .{rel.target.symbol.cast(Symbol.Regular).?.file.name.?});
1565
1559 const base_addr = blk: {1566 const base_addr = blk: {
1560 if (self.tlv_data_section_index) |index| {1567 if (self.tlv_data_section_index) |index| {
1561 const tlv_data = target_seg.sections.items[index];1568 const tlv_data = target_seg.sections.items[index];
...@@ -1565,6 +1572,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {...@@ -1565,6 +1572,8 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void {
1565 break :blk tlv_bss.addr;1572 break :blk tlv_bss.addr;
1566 }1573 }
1567 };1574 };
1575 log.warn(" | base address 0x{x}", .{base_addr});
1576 log.warn(" | offset 0x{x}", .{args.target_addr - base_addr});
1568 // Since we require TLV data to always preceed TLV bss section, we calculate1577 // Since we require TLV data to always preceed TLV bss section, we calculate
1569 // offsets wrt to the former if it is defined; otherwise, wrt to the latter.1578 // offsets wrt to the former if it is defined; otherwise, wrt to the latter.
1570 try self.threadlocal_offsets.append(self.allocator, args.target_addr - base_addr);1579 try self.threadlocal_offsets.append(self.allocator, args.target_addr - base_addr);
src/link/MachO/reloc/aarch64.zig+1-1
...@@ -25,7 +25,7 @@ pub const Branch = struct {...@@ -25,7 +25,7 @@ pub const Branch = struct {
25 log.debug(" | displacement 0x{x}", .{displacement});25 log.debug(" | displacement 0x{x}", .{displacement});
2626
27 var inst = branch.inst;27 var inst = branch.inst;
28 inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement) >> 2);28 inst.unconditional_branch_immediate.imm26 = @truncate(u26, @bitCast(u28, displacement >> 2));
29 mem.writeIntLittle(u32, branch.base.code[0..4], inst.toU32());29 mem.writeIntLittle(u32, branch.base.code[0..4], inst.toU32());
30 }30 }
31};31};