| ... | @@ -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 | } |
| 1348 | | 1349 | |
| 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 | }); |
| 1430 | | 1431 | |
| 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 | } |
| 1446 | | 1447 | |
| 1447 | fn resolveStubsAndGotEntries(self: *Zld) !void { | 1448 | fn 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); |
| 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 | 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; |