authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-19 22:29:13+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-20 16:55:32+02:00
loge5b83056ae335b12caf5b8912ec40e9962ce27f7
tree9ac1c4f41a5d181abd5f69aaa05809903f07d321
parent8943a0aaaab1cda1285d3732ccc525ea5da8e794

zld: resolve symbols as globals before resolving locals


1 files changed, 43 insertions(+), 35 deletions(-)

src/link/MachO/Zld.zig+43-35
...@@ -1396,20 +1396,20 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1396,20 +1396,20 @@ fn resolveSymbols(self: *Zld) !void {
1396 .file = 0,1396 .file = 0,
1397 });1397 });
13981398
1399 {1399 // {
1400 log.debug("symtab", .{});1400 // log.warn("symtab", .{});
1401 for (self.symtab.items()) |sym| {1401 // for (self.symtab.items()) |sym| {
1402 switch (sym.value.tag) {1402 // switch (sym.value.tag) {
1403 .weak, .strong => {1403 // .weak, .strong => {
1404 log.debug(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? });1404 // log.warn(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? });
1405 },1405 // },
1406 .import => {1406 // .import => {
1407 log.debug(" | {s} => libSystem.B.dylib", .{sym.key});1407 // log.warn(" | {s} => libSystem.B.dylib", .{sym.key});
1408 },1408 // },
1409 else => unreachable,1409 // else => unreachable,
1410 }1410 // }
1411 }1411 // }
1412 }1412 // }
1413}1413}
14141414
1415fn resolveStubsAndGotEntries(self: *Zld) !void {1415fn resolveStubsAndGotEntries(self: *Zld) !void {
...@@ -1654,7 +1654,31 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)...@@ -1654,7 +1654,31 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)
1654 const sym = object.symtab.items[sym_id];1654 const sym = object.symtab.items[sym_id];
1655 const sym_name = object.getString(sym.n_strx);1655 const sym_name = object.getString(sym.n_strx);
16561656
1657 if (Symbol.isSect(sym)) {1657 if (self.symtab.get(sym_name)) |global| {
1658 switch (global.tag) {
1659 .weak, .strong => {
1660 log.debug(" | global symbol '{s}'", .{sym_name});
1661 break :blk global.address;
1662 },
1663 .import => {
1664 if (self.stubs.get(sym_name)) |index| {
1665 log.debug(" | symbol stub '{s}'", .{sym_name});
1666 const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1667 const stubs = segment.sections.items[self.stubs_section_index.?];
1668 break :blk stubs.addr + index * stubs.reserved2;
1669 } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) {
1670 log.debug(" | symbol '__tlv_bootstrap'", .{});
1671 const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1672 const tlv = segment.sections.items[self.tlv_section_index.?];
1673 break :blk tlv.addr;
1674 } else {
1675 log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name});
1676 return error.FailedToResolveRelocationTarget;
1677 }
1678 },
1679 else => unreachable,
1680 }
1681 } else if (Symbol.isSect(sym)) {
1658 log.debug(" | local symbol '{s}'", .{sym_name});1682 log.debug(" | local symbol '{s}'", .{sym_name});
1659 if (object.locals.get(sym_name)) |local| {1683 if (object.locals.get(sym_name)) |local| {
1660 break :blk local.address;1684 break :blk local.address;
...@@ -1674,24 +1698,8 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)...@@ -1674,24 +1698,8 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target)
1674 const target_addr = target_sect.addr + target_mapping.offset;1698 const target_addr = target_sect.addr + target_mapping.offset;
1675 break :blk sym.n_value - source_sect.addr + target_addr;1699 break :blk sym.n_value - source_sect.addr + target_addr;
1676 } else {1700 } else {
1677 if (self.stubs.get(sym_name)) |index| {1701 log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name});
1678 log.debug(" | symbol stub '{s}'", .{sym_name});1702 return error.FailedToResolveRelocationTarget;
1679 const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1680 const stubs = segment.sections.items[self.stubs_section_index.?];
1681 break :blk stubs.addr + index * stubs.reserved2;
1682 } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) {
1683 log.debug(" | symbol '__tlv_bootstrap'", .{});
1684 const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1685 const tlv = segment.sections.items[self.tlv_section_index.?];
1686 break :blk tlv.addr;
1687 } else {
1688 const global = self.symtab.get(sym_name) orelse {
1689 log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name});
1690 return error.FailedToResolveRelocationTarget;
1691 };
1692 log.debug(" | global symbol '{s}'", .{sym_name});
1693 break :blk global.address;
1694 }
1695 }1703 }
1696 },1704 },
1697 .section => |sect_id| {1705 .section => |sect_id| {
...@@ -2148,7 +2156,7 @@ fn flush(self: *Zld) !void {...@@ -2148,7 +2156,7 @@ fn flush(self: *Zld) !void {
21482156
2149 var buffer = try self.allocator.alloc(u8, self.cpp_initializers.items().len * @sizeOf(u64));2157 var buffer = try self.allocator.alloc(u8, self.cpp_initializers.items().len * @sizeOf(u64));
2150 defer self.allocator.free(buffer);2158 defer self.allocator.free(buffer);
2151 2159
2152 var stream = std.io.fixedBufferStream(buffer);2160 var stream = std.io.fixedBufferStream(buffer);
2153 var writer = stream.writer();2161 var writer = stream.writer();
21542162
...@@ -2166,7 +2174,7 @@ fn flush(self: *Zld) !void {...@@ -2166,7 +2174,7 @@ fn flush(self: *Zld) !void {
21662174
2167 var buffer = try self.allocator.alloc(u8, self.cpp_finalizers.items().len * @sizeOf(u64));2175 var buffer = try self.allocator.alloc(u8, self.cpp_finalizers.items().len * @sizeOf(u64));
2168 defer self.allocator.free(buffer);2176 defer self.allocator.free(buffer);
2169 2177
2170 var stream = std.io.fixedBufferStream(buffer);2178 var stream = std.io.fixedBufferStream(buffer);
2171 var writer = stream.writer();2179 var writer = stream.writer();
21722180