Commit d8f2103545

Jakub Konka <kubkon@jakubkonka.com>
2022-09-09 23:30:31
macho+coff: return index into global table from getGlobalSymbol
1 parent bac065c
Changed files (3)
src
arch
x86_64
link
src/arch/x86_64/Emit.zig
@@ -1024,7 +1024,11 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
                 0b10 => .imports,
                 else => unreachable,
             },
-            .target = .{ .sym_index = relocation.sym_index, .file = null },
+            .target = switch (ops.flags) {
+                0b00, 0b01 => .{ .sym_index = relocation.sym_index, .file = null },
+                0b10 => coff_file.getGlobalByIndex(relocation.sym_index),
+                else => unreachable,
+            },
             .offset = @intCast(u32, end_offset - 4),
             .addend = 0,
             .pcrel = true,
@@ -1142,12 +1146,10 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
     if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
         // Add relocation to the decl.
         const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?;
+        const target = macho_file.getGlobalByIndex(relocation.sym_index);
         try atom.relocs.append(emit.bin_file.allocator, .{
             .offset = offset,
-            .target = .{
-                .sym_index = relocation.sym_index,
-                .file = null,
-            },
+            .target = target,
             .addend = 0,
             .subtractor = null,
             .pcrel = true,
@@ -1157,16 +1159,17 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
     } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
         // Add relocation to the decl.
         const atom = coff_file.atom_by_index_table.get(relocation.atom_index).?;
+        const target = coff_file.getGlobalByIndex(relocation.sym_index);
         try atom.addRelocation(coff_file, .{
             .@"type" = .direct,
-            .target = .{ .sym_index = relocation.sym_index, .file = null },
+            .target = target,
             .offset = offset,
             .addend = 0,
             .pcrel = true,
             .length = 2,
         });
     } else {
-        return emit.fail("TODO implement call_extern for linking backends different than MachO", .{});
+        return emit.fail("TODO implement call_extern for linking backends different than MachO and COFF", .{});
     }
 }
 
src/link/Coff.zig
@@ -1544,9 +1544,10 @@ pub fn getDeclVAddr(
 
 pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {
     const gop = try self.getOrPutGlobalPtr(name);
+    const global_index = self.getGlobalIndex(name).?;
 
     if (gop.found_existing) {
-        return gop.value_ptr.sym_index;
+        return global_index;
     }
 
     const sym_index = try self.allocateSymbol();
@@ -1559,9 +1560,9 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {
     try self.setSymbolName(sym, sym_name);
     sym.storage_class = .EXTERNAL;
 
-    try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(name).?, true);
+    try self.unresolved.putNoClobber(gpa, global_index, true);
 
-    return sym_index;
+    return global_index;
 }
 
 pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl: *Module.Decl) !void {
@@ -2077,6 +2078,12 @@ pub fn getGlobalIndex(self: *const Coff, name: []const u8) ?u32 {
     return self.resolver.get(name);
 }
 
+/// Returns global entry at `index`.
+pub fn getGlobalByIndex(self: *const Coff, index: u32) SymbolWithLoc {
+    assert(index < self.globals.items.len);
+    return self.globals.items[index];
+}
+
 const GetOrPutGlobalPtrResult = struct {
     found_existing: bool,
     value_ptr: *SymbolWithLoc,
src/link/MachO.zig
@@ -4890,9 +4890,10 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 {
     const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
     defer gpa.free(sym_name);
     const gop = try self.getOrPutGlobalPtr(sym_name);
+    const global_index = self.getGlobalIndex(sym_name).?;
 
     if (gop.found_existing) {
-        return gop.value_ptr.sym_index;
+        return global_index;
     }
 
     const sym_index = try self.allocateSymbol();
@@ -4902,9 +4903,9 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 {
     const sym = self.getSymbolPtr(sym_loc);
     sym.n_strx = try self.strtab.insert(gpa, sym_name);
 
-    try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, true);
+    try self.unresolved.putNoClobber(gpa, global_index, true);
 
-    return sym_index;
+    return global_index;
 }
 
 fn getSegmentAllocBase(self: MachO, indices: []const ?u8) struct { vmaddr: u64, fileoff: u64 } {
@@ -5830,6 +5831,12 @@ pub fn getGlobalIndex(self: *const MachO, name: []const u8) ?u32 {
     return self.resolver.get(name);
 }
 
+/// Returns global entry at `index`.
+pub fn getGlobalByIndex(self: *const MachO, index: u32) SymbolWithLoc {
+    assert(index < self.globals.items.len);
+    return self.globals.items[index];
+}
+
 const GetOrPutGlobalPtrResult = struct {
     found_existing: bool,
     value_ptr: *SymbolWithLoc,