Commit e5b83056ae

Jakub Konka <kubkon@jakubkonka.com>
2021-04-19 22:29:13
zld: resolve symbols as globals before resolving locals
1 parent 8943a0a
Changed files (1)
src
link
MachO
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();