diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-04-19 22:29:13 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-04-20 16:55:32 +0200 |
| commit | e5b83056ae335b12caf5b8912ec40e9962ce27f7 (patch) | |
| tree | 9ac1c4f41a5d181abd5f69aaa05809903f07d321 /src | |
| parent | 8943a0aaaab1cda1285d3732ccc525ea5da8e794 (diff) | |
| download | zig-e5b83056ae335b12caf5b8912ec40e9962ce27f7.tar.gz zig-e5b83056ae335b12caf5b8912ec40e9962ce27f7.zip | |
zld: resolve symbols as globals before resolving locals
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO/Zld.zig | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index 52761ef048..4bdb419ffc 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -1396,20 +1396,20 @@ fn resolveSymbols(self: *Zld) !void { .file = 0, }); - { - log.debug("symtab", .{}); - for (self.symtab.items()) |sym| { - switch (sym.value.tag) { - .weak, .strong => { - log.debug(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? }); - }, - .import => { - log.debug(" | {s} => libSystem.B.dylib", .{sym.key}); - }, - else => unreachable, - } - } - } + // { + // log.warn("symtab", .{}); + // for (self.symtab.items()) |sym| { + // switch (sym.value.tag) { + // .weak, .strong => { + // log.warn(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? }); + // }, + // .import => { + // log.warn(" | {s} => libSystem.B.dylib", .{sym.key}); + // }, + // else => unreachable, + // } + // } + // } } fn resolveStubsAndGotEntries(self: *Zld) !void { @@ -1654,7 +1654,31 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) const sym = object.symtab.items[sym_id]; const sym_name = object.getString(sym.n_strx); - if (Symbol.isSect(sym)) { + if (self.symtab.get(sym_name)) |global| { + switch (global.tag) { + .weak, .strong => { + log.debug(" | global symbol '{s}'", .{sym_name}); + break :blk global.address; + }, + .import => { + if (self.stubs.get(sym_name)) |index| { + log.debug(" | symbol stub '{s}'", .{sym_name}); + const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; + const stubs = segment.sections.items[self.stubs_section_index.?]; + break :blk stubs.addr + index * stubs.reserved2; + } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { + log.debug(" | symbol '__tlv_bootstrap'", .{}); + const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; + const tlv = segment.sections.items[self.tlv_section_index.?]; + break :blk tlv.addr; + } else { + log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); + return error.FailedToResolveRelocationTarget; + } + }, + else => unreachable, + } + } else if (Symbol.isSect(sym)) { log.debug(" | local symbol '{s}'", .{sym_name}); if (object.locals.get(sym_name)) |local| { break :blk local.address; @@ -1674,24 +1698,8 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: reloc.Relocation.Target) const target_addr = target_sect.addr + target_mapping.offset; break :blk sym.n_value - source_sect.addr + target_addr; } else { - if (self.stubs.get(sym_name)) |index| { - log.debug(" | symbol stub '{s}'", .{sym_name}); - const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; - const stubs = segment.sections.items[self.stubs_section_index.?]; - break :blk stubs.addr + index * stubs.reserved2; - } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { - log.debug(" | symbol '__tlv_bootstrap'", .{}); - const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; - const tlv = segment.sections.items[self.tlv_section_index.?]; - break :blk tlv.addr; - } else { - const global = self.symtab.get(sym_name) orelse { - log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); - return error.FailedToResolveRelocationTarget; - }; - log.debug(" | global symbol '{s}'", .{sym_name}); - break :blk global.address; - } + log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); + return error.FailedToResolveRelocationTarget; } }, .section => |sect_id| { @@ -2148,7 +2156,7 @@ fn flush(self: *Zld) !void { var buffer = try self.allocator.alloc(u8, self.cpp_initializers.items().len * @sizeOf(u64)); defer self.allocator.free(buffer); - + var stream = std.io.fixedBufferStream(buffer); var writer = stream.writer(); @@ -2166,7 +2174,7 @@ fn flush(self: *Zld) !void { var buffer = try self.allocator.alloc(u8, self.cpp_finalizers.items().len * @sizeOf(u64)); defer self.allocator.free(buffer); - + var stream = std.io.fixedBufferStream(buffer); var writer = stream.writer(); |
