authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-20 16:55:08+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-20 16:55:32+02:00
logd64c76e8f1faf493d5fa6f3c0d9324f05f99d68f
treec8ca7fb3acc4047d00dc60096e8856c99d98efa6
parent7bc6554a58274730f762bffb1f031af8dcfdb1fb

zld: fix parsing of weak symbols


2 files changed, 37 insertions(+), 36 deletions(-)

src/link/MachO/Symbol.zig+1-1
...@@ -52,7 +52,7 @@ pub fn isUndf(sym: macho.nlist_64) bool {...@@ -52,7 +52,7 @@ pub fn isUndf(sym: macho.nlist_64) bool {
52}52}
5353
54pub fn isWeakDef(sym: macho.nlist_64) bool {54pub fn isWeakDef(sym: macho.nlist_64) bool {
55 return sym.n_desc == macho.N_WEAK_DEF;55 return (sym.n_desc & macho.N_WEAK_DEF) != 0;
56}56}
5757
58/// Symbol is local if it is defined and not an extern.58/// Symbol is local if it is defined and not an extern.
src/link/MachO/Zld.zig+36-35
...@@ -1340,13 +1340,14 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void {...@@ -1340,13 +1340,14 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void {
1340 .strong => {1340 .strong => {
1341 if (!is_weak) {1341 if (!is_weak) {
1342 log.debug("strong symbol '{s}' defined multiple times", .{sym_name});1342 log.debug("strong symbol '{s}' defined multiple times", .{sym_name});
1343 return error.MultipleSymbolDefinitions;
1343 }1344 }
1344 continue;1345 continue;
1345 },1346 },
1346 else => {},1347 else => {},
1347 }1348 }
13481349
1349 global.value.tag = .strong;1350 global.value.tag = if (is_weak) .weak else .strong;
1350 global.value.file = object_id;1351 global.value.file = object_id;
1351 global.value.index = @intCast(u32, sym_id);1352 global.value.index = @intCast(u32, sym_id);
1352 } else if (Symbol.isUndef(sym)) {1353 } else if (Symbol.isUndef(sym)) {
...@@ -1428,20 +1429,20 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1428,20 +1429,20 @@ fn resolveSymbols(self: *Zld) !void {
1428 .file = 0,1429 .file = 0,
1429 });1430 });
14301431
1431 // {1432 {
1432 // log.warn("symtab", .{});1433 log.debug("symtab", .{});
1433 // for (self.symtab.items()) |sym| {1434 for (self.symtab.items()) |sym| {
1434 // switch (sym.value.tag) {1435 switch (sym.value.tag) {
1435 // .weak, .strong => {1436 .weak, .strong => {
1436 // log.warn(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? });1437 log.debug(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? });
1437 // },1438 },
1438 // .import => {1439 .import => {
1439 // log.warn(" | {s} => libSystem.B.dylib", .{sym.key});1440 log.debug(" | {s} => libSystem.B.dylib", .{sym.key});
1440 // },1441 },
1441 // else => unreachable,1442 else => unreachable,
1442 // }1443 }
1443 // }1444 }
1444 // }1445 }
1445}1446}
14461447
1447fn resolveStubsAndGotEntries(self: *Zld) !void {1448fn resolveStubsAndGotEntries(self: *Zld) !void {
...@@ -1687,7 +1688,26 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)...@@ -1687,7 +1688,26 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)
1687 const sym = object.symtab.items[sym_id];1688 const sym = object.symtab.items[sym_id];
1688 const sym_name = object.getString(sym.n_strx);1689 const sym_name = object.getString(sym.n_strx);
16891690
1690 if (self.symtab.get(sym_name)) |global| {1691 if (Symbol.isSect(sym)) {
1692 log.debug(" | local symbol '{s}'", .{sym_name});
1693 if (object.locals.get(sym_name)) |local| {
1694 break :blk local.address;
1695 }
1696 // For temp locals, i.e., symbols prefixed with l... we relocate
1697 // based on section addressing.
1698 const source_sect_id = sym.n_sect - 1;
1699 const target_mapping = self.mappings.get(.{
1700 .object_id = object_id,
1701 .source_sect_id = source_sect_id,
1702 }) orelse unreachable;
1703
1704 const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
1705 const source_sect = source_seg.sections.items[source_sect_id];
1706 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
1707 const target_sect = target_seg.sections.items[target_mapping.target_sect_id];
1708 const target_addr = target_sect.addr + target_mapping.offset;
1709 break :blk sym.n_value - source_sect.addr + target_addr;
1710 } else if (self.symtab.get(sym_name)) |global| {
1691 switch (global.tag) {1711 switch (global.tag) {
1692 .weak, .strong => {1712 .weak, .strong => {
1693 log.debug(" | global symbol '{s}'", .{sym_name});1713 log.debug(" | global symbol '{s}'", .{sym_name});
...@@ -1711,25 +1731,6 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)...@@ -1711,25 +1731,6 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)
1711 },1731 },
1712 else => unreachable,1732 else => unreachable,
1713 }1733 }
1714 } else if (Symbol.isSect(sym)) {
1715 log.debug(" | local symbol '{s}'", .{sym_name});
1716 if (object.locals.get(sym_name)) |local| {
1717 break :blk local.address;
1718 }
1719 // For temp locals, i.e., symbols prefixed with l... we relocate
1720 // based on section addressing.
1721 const source_sect_id = sym.n_sect - 1;
1722 const target_mapping = self.mappings.get(.{
1723 .object_id = object_id,
1724 .source_sect_id = source_sect_id,
1725 }) orelse unreachable;
1726
1727 const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment;
1728 const source_sect = source_seg.sections.items[source_sect_id];
1729 const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment;
1730 const target_sect = target_seg.sections.items[target_mapping.target_sect_id];
1731 const target_addr = target_sect.addr + target_mapping.offset;
1732 break :blk sym.n_value - source_sect.addr + target_addr;
1733 } else {1734 } else {
1734 log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name});1735 log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name});
1735 return error.FailedToResolveRelocationTarget;1736 return error.FailedToResolveRelocationTarget;