| ... | ... | @@ -1340,13 +1340,14 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1340 | 1340 | .strong => { |
| 1341 | 1341 | if (!is_weak) { |
| 1342 | 1342 | log.debug("strong symbol '{s}' defined multiple times", .{sym_name}); |
| 1343 | return error.MultipleSymbolDefinitions; |
| 1343 | 1344 | } |
| 1344 | 1345 | continue; |
| 1345 | 1346 | }, |
| 1346 | 1347 | else => {}, |
| 1347 | 1348 | } |
| 1348 | 1349 | |
| 1349 | | global.value.tag = .strong; |
| 1350 | global.value.tag = if (is_weak) .weak else .strong; |
| 1350 | 1351 | global.value.file = object_id; |
| 1351 | 1352 | global.value.index = @intCast(u32, sym_id); |
| 1352 | 1353 | } else if (Symbol.isUndef(sym)) { |
| ... | ... | @@ -1428,20 +1429,20 @@ fn resolveSymbols(self: *Zld) !void { |
| 1428 | 1429 | .file = 0, |
| 1429 | 1430 | }); |
| 1430 | 1431 | |
| 1431 | | // { |
| 1432 | | // log.warn("symtab", .{}); |
| 1433 | | // for (self.symtab.items()) |sym| { |
| 1434 | | // switch (sym.value.tag) { |
| 1435 | | // .weak, .strong => { |
| 1436 | | // log.warn(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? }); |
| 1437 | | // }, |
| 1438 | | // .import => { |
| 1439 | | // log.warn(" | {s} => libSystem.B.dylib", .{sym.key}); |
| 1440 | | // }, |
| 1441 | | // else => unreachable, |
| 1442 | | // } |
| 1443 | | // } |
| 1444 | | // } |
| 1432 | { |
| 1433 | log.debug("symtab", .{}); |
| 1434 | for (self.symtab.items()) |sym| { |
| 1435 | switch (sym.value.tag) { |
| 1436 | .weak, .strong => { |
| 1437 | log.debug(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? }); |
| 1438 | }, |
| 1439 | .import => { |
| 1440 | log.debug(" | {s} => libSystem.B.dylib", .{sym.key}); |
| 1441 | }, |
| 1442 | else => unreachable, |
| 1443 | } |
| 1444 | } |
| 1445 | } |
| 1445 | 1446 | } |
| 1446 | 1447 | |
| 1447 | 1448 | fn resolveStubsAndGotEntries(self: *Zld) !void { |
| ... | ... | @@ -1687,7 +1688,26 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) |
| 1687 | 1688 | const sym = object.symtab.items[sym_id]; |
| 1688 | 1689 | const sym_name = object.getString(sym.n_strx); |
| 1689 | 1690 | |
| 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 | 1711 | switch (global.tag) { |
| 1692 | 1712 | .weak, .strong => { |
| 1693 | 1713 | log.debug(" | global symbol '{s}'", .{sym_name}); |
| ... | ... | @@ -1711,25 +1731,6 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) |
| 1711 | 1731 | }, |
| 1712 | 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 | 1734 | } else { |
| 1734 | 1735 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); |
| 1735 | 1736 | return error.FailedToResolveRelocationTarget; |