| author | |
| committer | |
| log | 41b91442f4af293d4cbbabbe9e451bd31c5c5679 |
| tree | 97cf00b1e93bd90847f33ce905db1d5e87fd5e9d |
| parent | 4658d857de9198e825f13c136b2342d630e19e62 |
8 files changed, 88 insertions(+), 54 deletions(-)
src/arch/aarch64/CodeGen.zig+3-3| ... | @@ -3190,14 +3190,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3190,14 +3190,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3190 | lib_name, | 3190 | lib_name, |
| 3191 | }); | 3191 | }); |
| 3192 | } | 3192 | } |
| 3193 | const global_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); | 3193 | const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); |
| 3194 | 3194 | ||
| 3195 | _ = try self.addInst(.{ | 3195 | _ = try self.addInst(.{ |
| 3196 | .tag = .call_extern, | 3196 | .tag = .call_extern, |
| 3197 | .data = .{ | 3197 | .data = .{ |
| 3198 | .extern_fn = .{ | 3198 | .relocation = .{ |
| 3199 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, | 3199 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 3200 | .global_index = global_index, | 3200 | .sym_index = sym_index, |
| 3201 | }, | 3201 | }, |
| 3202 | }, | 3202 | }, |
| 3203 | }); | 3203 | }); |
src/arch/aarch64/Emit.zig+6-4| ... | @@ -649,7 +649,7 @@ fn mirDebugEpilogueBegin(self: *Emit) !void { | ... | @@ -649,7 +649,7 @@ fn mirDebugEpilogueBegin(self: *Emit) !void { |
| 649 | 649 | ||
| 650 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { | 650 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 651 | assert(emit.mir.instructions.items(.tag)[inst] == .call_extern); | 651 | assert(emit.mir.instructions.items(.tag)[inst] == .call_extern); |
| 652 | const extern_fn = emit.mir.instructions.items(.data)[inst].extern_fn; | 652 | const relocation = emit.mir.instructions.items(.data)[inst].relocation; |
| 653 | 653 | ||
| 654 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 654 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 655 | const offset = blk: { | 655 | const offset = blk: { |
| ... | @@ -659,11 +659,13 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { | ... | @@ -659,11 +659,13 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 659 | break :blk offset; | 659 | break :blk offset; |
| 660 | }; | 660 | }; |
| 661 | // Add relocation to the decl. | 661 | // Add relocation to the decl. |
| 662 | const atom = macho_file.atom_by_index_table.get(extern_fn.atom_index).?; | 662 | const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?; |
| 663 | const target = macho_file.globals.values()[extern_fn.global_index]; | ||
| 664 | try atom.relocs.append(emit.bin_file.allocator, .{ | 663 | try atom.relocs.append(emit.bin_file.allocator, .{ |
| 665 | .offset = offset, | 664 | .offset = offset, |
| 666 | .target = target, | 665 | .target = .{ |
| 666 | .sym_index = relocation.sym_index, | ||
| 667 | .file = null, | ||
| 668 | }, | ||
| 667 | .addend = 0, | 669 | .addend = 0, |
| 668 | .subtractor = null, | 670 | .subtractor = null, |
| 669 | .pcrel = true, | 671 | .pcrel = true, |
src/arch/aarch64/Mir.zig+5-3| ... | @@ -225,14 +225,16 @@ pub const Inst = struct { | ... | @@ -225,14 +225,16 @@ pub const Inst = struct { |
| 225 | /// | 225 | /// |
| 226 | /// Used by e.g. b | 226 | /// Used by e.g. b |
| 227 | inst: Index, | 227 | inst: Index, |
| 228 | /// An extern function | 228 | /// Relocation for the linker where: |
| 229 | /// * `atom_index` is the index of the source | ||
| 230 | /// * `sym_index` is the index of the target | ||
| 229 | /// | 231 | /// |
| 230 | /// Used by e.g. call_extern | 232 | /// Used by e.g. call_extern |
| 231 | extern_fn: struct { | 233 | relocation: struct { |
| 232 | /// Index of the containing atom. | 234 | /// Index of the containing atom. |
| 233 | atom_index: u32, | 235 | atom_index: u32, |
| 234 | /// Index into the linker's string table. | 236 | /// Index into the linker's string table. |
| 235 | global_index: u32, | 237 | sym_index: u32, |
| 236 | }, | 238 | }, |
| 237 | /// A 16-bit immediate value. | 239 | /// A 16-bit immediate value. |
| 238 | /// | 240 | /// |
src/arch/x86_64/CodeGen.zig+4-4| ... | @@ -2644,7 +2644,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue | ... | @@ -2644,7 +2644,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue |
| 2644 | .flags = flags, | 2644 | .flags = flags, |
| 2645 | }), | 2645 | }), |
| 2646 | .data = .{ | 2646 | .data = .{ |
| 2647 | .load_reloc = .{ | 2647 | .relocation = .{ |
| 2648 | .atom_index = fn_owner_decl.link.macho.sym_index, | 2648 | .atom_index = fn_owner_decl.link.macho.sym_index, |
| 2649 | .sym_index = sym_index, | 2649 | .sym_index = sym_index, |
| 2650 | }, | 2650 | }, |
| ... | @@ -3997,14 +3997,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. | ... | @@ -3997,14 +3997,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3997 | lib_name, | 3997 | lib_name, |
| 3998 | }); | 3998 | }); |
| 3999 | } | 3999 | } |
| 4000 | const global_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); | 4000 | const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); |
| 4001 | _ = try self.addInst(.{ | 4001 | _ = try self.addInst(.{ |
| 4002 | .tag = .call_extern, | 4002 | .tag = .call_extern, |
| 4003 | .ops = undefined, | 4003 | .ops = undefined, |
| 4004 | .data = .{ | 4004 | .data = .{ |
| 4005 | .extern_fn = .{ | 4005 | .relocation = .{ |
| 4006 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, | 4006 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4007 | .global_index = global_index, | 4007 | .sym_index = sym_index, |
| 4008 | }, | 4008 | }, |
| 4009 | }, | 4009 | }, |
| 4010 | }); | 4010 | }); |
src/arch/x86_64/Emit.zig+10-8| ... | @@ -982,7 +982,7 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ... | @@ -982,7 +982,7 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 982 | const tag = emit.mir.instructions.items(.tag)[inst]; | 982 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 983 | assert(tag == .lea_pie); | 983 | assert(tag == .lea_pie); |
| 984 | const ops = emit.mir.instructions.items(.ops)[inst].decode(); | 984 | const ops = emit.mir.instructions.items(.ops)[inst].decode(); |
| 985 | const load_reloc = emit.mir.instructions.items(.data)[inst].load_reloc; | 985 | const relocation = emit.mir.instructions.items(.data)[inst].relocation; |
| 986 | 986 | ||
| 987 | // lea reg1, [rip + reloc] | 987 | // lea reg1, [rip + reloc] |
| 988 | // RM | 988 | // RM |
| ... | @@ -1001,11 +1001,11 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ... | @@ -1001,11 +1001,11 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 1001 | 0b01 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), | 1001 | 0b01 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), |
| 1002 | else => return emit.fail("TODO unused LEA PIE variants 0b10 and 0b11", .{}), | 1002 | else => return emit.fail("TODO unused LEA PIE variants 0b10 and 0b11", .{}), |
| 1003 | }; | 1003 | }; |
| 1004 | const atom = macho_file.atom_by_index_table.get(load_reloc.atom_index).?; | 1004 | const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?; |
| 1005 | log.debug("adding reloc of type {} to local @{d}", .{ reloc_type, load_reloc.sym_index }); | 1005 | log.debug("adding reloc of type {} to local @{d}", .{ reloc_type, relocation.sym_index }); |
| 1006 | try atom.relocs.append(emit.bin_file.allocator, .{ | 1006 | try atom.relocs.append(emit.bin_file.allocator, .{ |
| 1007 | .offset = @intCast(u32, end_offset - 4), | 1007 | .offset = @intCast(u32, end_offset - 4), |
| 1008 | .target = .{ .sym_index = load_reloc.sym_index, .file = null }, | 1008 | .target = .{ .sym_index = relocation.sym_index, .file = null }, |
| 1009 | .addend = 0, | 1009 | .addend = 0, |
| 1010 | .subtractor = null, | 1010 | .subtractor = null, |
| 1011 | .pcrel = true, | 1011 | .pcrel = true, |
| ... | @@ -1116,7 +1116,7 @@ fn mirCmpFloatAvx(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { | ... | @@ -1116,7 +1116,7 @@ fn mirCmpFloatAvx(emit: *Emit, tag: Tag, inst: Mir.Inst.Index) InnerError!void { |
| 1116 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | 1116 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 1117 | const tag = emit.mir.instructions.items(.tag)[inst]; | 1117 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 1118 | assert(tag == .call_extern); | 1118 | assert(tag == .call_extern); |
| 1119 | const extern_fn = emit.mir.instructions.items(.data)[inst].extern_fn; | 1119 | const relocation = emit.mir.instructions.items(.data)[inst].relocation; |
| 1120 | 1120 | ||
| 1121 | const offset = blk: { | 1121 | const offset = blk: { |
| 1122 | // callq | 1122 | // callq |
| ... | @@ -1126,11 +1126,13 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { | ... | @@ -1126,11 +1126,13 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 1126 | 1126 | ||
| 1127 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | 1127 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 1128 | // Add relocation to the decl. | 1128 | // Add relocation to the decl. |
| 1129 | const atom = macho_file.atom_by_index_table.get(extern_fn.atom_index).?; | 1129 | const atom = macho_file.atom_by_index_table.get(relocation.atom_index).?; |
| 1130 | const target = macho_file.globals.values()[extern_fn.global_index]; | ||
| 1131 | try atom.relocs.append(emit.bin_file.allocator, .{ | 1130 | try atom.relocs.append(emit.bin_file.allocator, .{ |
| 1132 | .offset = offset, | 1131 | .offset = offset, |
| 1133 | .target = target, | 1132 | .target = .{ |
| 1133 | .sym_index = relocation.sym_index, | ||
| 1134 | .file = null, | ||
| 1135 | }, | ||
| 1134 | .addend = 0, | 1136 | .addend = 0, |
| 1135 | .subtractor = null, | 1137 | .subtractor = null, |
| 1136 | .pcrel = true, | 1138 | .pcrel = true, |
src/arch/x86_64/Mir.zig+6-11| ... | @@ -181,7 +181,7 @@ pub const Inst = struct { | ... | @@ -181,7 +181,7 @@ pub const Inst = struct { |
| 181 | /// 0b00 reg1, [rip + reloc] // via GOT emits X86_64_RELOC_GOT relocation | 181 | /// 0b00 reg1, [rip + reloc] // via GOT emits X86_64_RELOC_GOT relocation |
| 182 | /// 0b01 reg1, [rip + reloc] // direct load emits X86_64_RELOC_SIGNED relocation | 182 | /// 0b01 reg1, [rip + reloc] // direct load emits X86_64_RELOC_SIGNED relocation |
| 183 | /// Notes: | 183 | /// Notes: |
| 184 | /// * `Data` contains `load_reloc` | 184 | /// * `Data` contains `relocation` |
| 185 | lea_pie, | 185 | lea_pie, |
| 186 | 186 | ||
| 187 | /// ops flags: form: | 187 | /// ops flags: form: |
| ... | @@ -368,7 +368,7 @@ pub const Inst = struct { | ... | @@ -368,7 +368,7 @@ pub const Inst = struct { |
| 368 | /// Pseudo-instructions | 368 | /// Pseudo-instructions |
| 369 | /// call extern function | 369 | /// call extern function |
| 370 | /// Notes: | 370 | /// Notes: |
| 371 | /// * target of the call is stored as `extern_fn` in `Data` union. | 371 | /// * target of the call is stored as `relocation` in `Data` union. |
| 372 | call_extern, | 372 | call_extern, |
| 373 | 373 | ||
| 374 | /// end of prologue | 374 | /// end of prologue |
| ... | @@ -439,15 +439,10 @@ pub const Inst = struct { | ... | @@ -439,15 +439,10 @@ pub const Inst = struct { |
| 439 | /// A condition code for use with EFLAGS register. | 439 | /// A condition code for use with EFLAGS register. |
| 440 | cc: bits.Condition, | 440 | cc: bits.Condition, |
| 441 | }, | 441 | }, |
| 442 | /// An extern function. | 442 | /// Relocation for the linker where: |
| 443 | extern_fn: struct { | 443 | /// * `atom_index` is the index of the source |
| 444 | /// Index of the containing atom. | 444 | /// * `sym_index` is the index of the target |
| 445 | atom_index: u32, | 445 | relocation: struct { |
| 446 | /// Index into the linker's globals table. | ||
| 447 | global_index: u32, | ||
| 448 | }, | ||
| 449 | /// PIE load relocation. | ||
| 450 | load_reloc: struct { | ||
| 451 | /// Index of the containing atom. | 446 | /// Index of the containing atom. |
| 452 | atom_index: u32, | 447 | atom_index: u32, |
| 453 | /// Index into the linker's symbol table. | 448 | /// Index into the linker's symbol table. |
src/link/MachO.zig+52-17| ... | @@ -153,6 +153,13 @@ rustc_section_size: u64 = 0, | ... | @@ -153,6 +153,13 @@ rustc_section_size: u64 = 0, |
| 153 | 153 | ||
| 154 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 154 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 155 | globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{}, | 155 | globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{}, |
| 156 | // FIXME Jakub | ||
| 157 | // TODO storing index into globals might be dangerous if we delete a global | ||
| 158 | // while not having everything resolved. Actually, perhaps `unresolved` | ||
| 159 | // should not be stored at the global scope? Is this possible? | ||
| 160 | // Otherwise, audit if this can be a problem. | ||
| 161 | // An alternative, which I still need to investigate for perf reasons is to | ||
| 162 | // store all global names in an adapted with context strtab. | ||
| 156 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, | 163 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, |
| 157 | 164 | ||
| 158 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 165 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -2449,9 +2456,9 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { | ... | @@ -2449,9 +2456,9 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { |
| 2449 | 2456 | ||
| 2450 | const target_sym = self.getSymbol(target); | 2457 | const target_sym = self.getSymbol(target); |
| 2451 | if (target_sym.undf()) { | 2458 | if (target_sym.undf()) { |
| 2452 | const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); | 2459 | const global = self.globals.get(self.getSymbolName(target)).?; |
| 2453 | try atom.bindings.append(gpa, .{ | 2460 | try atom.bindings.append(gpa, .{ |
| 2454 | .global_index = global_index, | 2461 | .target = global, |
| 2455 | .offset = 0, | 2462 | .offset = 0, |
| 2456 | }); | 2463 | }); |
| 2457 | } else { | 2464 | } else { |
| ... | @@ -2483,9 +2490,10 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom { | ... | @@ -2483,9 +2490,10 @@ pub fn createTlvPtrAtom(self: *MachO, target: SymbolWithLoc) !*Atom { |
| 2483 | const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3); | 2490 | const atom = try MachO.createEmptyAtom(gpa, sym_index, @sizeOf(u64), 3); |
| 2484 | const target_sym = self.getSymbol(target); | 2491 | const target_sym = self.getSymbol(target); |
| 2485 | assert(target_sym.undf()); | 2492 | assert(target_sym.undf()); |
| 2486 | const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); | 2493 | |
| 2494 | const global = self.globals.get(self.getSymbolName(target)).?; | ||
| 2487 | try atom.bindings.append(gpa, .{ | 2495 | try atom.bindings.append(gpa, .{ |
| 2488 | .global_index = global_index, | 2496 | .target = global, |
| 2489 | .offset = 0, | 2497 | .offset = 0, |
| 2490 | }); | 2498 | }); |
| 2491 | 2499 | ||
| ... | @@ -2739,7 +2747,6 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -2739,7 +2747,6 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 2739 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !*Atom { | 2747 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !*Atom { |
| 2740 | const gpa = self.base.allocator; | 2748 | const gpa = self.base.allocator; |
| 2741 | const sym_index = @intCast(u32, self.locals.items.len); | 2749 | const sym_index = @intCast(u32, self.locals.items.len); |
| 2742 | const global_index = @intCast(u32, self.globals.getIndex(self.getSymbolName(target)).?); | ||
| 2743 | try self.locals.append(gpa, .{ | 2750 | try self.locals.append(gpa, .{ |
| 2744 | .n_strx = 0, | 2751 | .n_strx = 0, |
| 2745 | .n_type = macho.N_SECT, | 2752 | .n_type = macho.N_SECT, |
| ... | @@ -2762,8 +2769,10 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi | ... | @@ -2762,8 +2769,10 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi |
| 2762 | }, | 2769 | }, |
| 2763 | }); | 2770 | }); |
| 2764 | try atom.rebases.append(gpa, 0); | 2771 | try atom.rebases.append(gpa, 0); |
| 2772 | |||
| 2773 | const global = self.globals.get(self.getSymbolName(target)).?; | ||
| 2765 | try atom.lazy_bindings.append(gpa, .{ | 2774 | try atom.lazy_bindings.append(gpa, .{ |
| 2766 | .global_index = global_index, | 2775 | .target = global, |
| 2767 | .offset = 0, | 2776 | .offset = 0, |
| 2768 | }); | 2777 | }); |
| 2769 | 2778 | ||
| ... | @@ -4149,6 +4158,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void { | ... | @@ -4149,6 +4158,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 4149 | const sym = self.getSymbolPtr(sym_loc); | 4158 | const sym = self.getSymbolPtr(sym_loc); |
| 4150 | const sym_name = self.getSymbolName(sym_loc); | 4159 | const sym_name = self.getSymbolName(sym_loc); |
| 4151 | log.debug("deleting export '{s}'", .{sym_name}); | 4160 | log.debug("deleting export '{s}'", .{sym_name}); |
| 4161 | assert(sym.sect() and sym.ext()); | ||
| 4152 | sym.* = .{ | 4162 | sym.* = .{ |
| 4153 | .n_strx = 0, | 4163 | .n_strx = 0, |
| 4154 | .n_type = 0, | 4164 | .n_type = 0, |
| ... | @@ -5307,7 +5317,9 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { | ... | @@ -5307,7 +5317,9 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { |
| 5307 | defer if (gop.found_existing) gpa.free(sym_name); | 5317 | defer if (gop.found_existing) gpa.free(sym_name); |
| 5308 | 5318 | ||
| 5309 | if (gop.found_existing) { | 5319 | if (gop.found_existing) { |
| 5310 | return @intCast(u32, self.globals.getIndex(sym_name).?); | 5320 | // TODO audit this: can we ever reference anything from outside the Zig module? |
| 5321 | assert(gop.value_ptr.file == null); | ||
| 5322 | return gop.value_ptr.sym_index; | ||
| 5311 | } | 5323 | } |
| 5312 | 5324 | ||
| 5313 | const sym_index = @intCast(u32, self.locals.items.len); | 5325 | const sym_index = @intCast(u32, self.locals.items.len); |
| ... | @@ -5324,7 +5336,7 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { | ... | @@ -5324,7 +5336,7 @@ pub fn getGlobalSymbol(self: *MachO, name: []const u8) !u32 { |
| 5324 | }; | 5336 | }; |
| 5325 | try self.unresolved.putNoClobber(gpa, global_index, true); | 5337 | try self.unresolved.putNoClobber(gpa, global_index, true); |
| 5326 | 5338 | ||
| 5327 | return global_index; | 5339 | return sym_index; |
| 5328 | } | 5340 | } |
| 5329 | 5341 | ||
| 5330 | fn getSegmentAllocBase(self: MachO, indices: []const ?u16) struct { vmaddr: u64, fileoff: u64 } { | 5342 | fn getSegmentAllocBase(self: MachO, indices: []const ?u16) struct { vmaddr: u64, fileoff: u64 } { |
| ... | @@ -5690,6 +5702,8 @@ fn updateSectionOrdinals(self: *MachO) !void { | ... | @@ -5690,6 +5702,8 @@ fn updateSectionOrdinals(self: *MachO) !void { |
| 5690 | } | 5702 | } |
| 5691 | } | 5703 | } |
| 5692 | 5704 | ||
| 5705 | // FIXME Jakub | ||
| 5706 | // TODO no need for duping work here; simply walk the atom graph | ||
| 5693 | for (self.locals.items) |*sym| { | 5707 | for (self.locals.items) |*sym| { |
| 5694 | if (sym.undf()) continue; | 5708 | if (sym.undf()) continue; |
| 5695 | if (sym.n_sect == 0) continue; | 5709 | if (sym.n_sect == 0) continue; |
| ... | @@ -5735,11 +5749,12 @@ fn writeDyldInfoData(self: *MachO) !void { | ... | @@ -5735,11 +5749,12 @@ fn writeDyldInfoData(self: *MachO) !void { |
| 5735 | log.debug("dyld info for {s},{s}", .{ sect.segName(), sect.sectName() }); | 5749 | log.debug("dyld info for {s},{s}", .{ sect.segName(), sect.sectName() }); |
| 5736 | 5750 | ||
| 5737 | while (true) { | 5751 | while (true) { |
| 5738 | log.debug(" ATOM %{d}", .{atom.sym_index}); | 5752 | log.debug(" ATOM(%{d}, '{s}')", .{ atom.sym_index, atom.getName(self) }); |
| 5739 | const sym = atom.getSymbol(self); | 5753 | const sym = atom.getSymbol(self); |
| 5740 | const base_offset = sym.n_value - seg.inner.vmaddr; | 5754 | const base_offset = sym.n_value - seg.inner.vmaddr; |
| 5741 | 5755 | ||
| 5742 | for (atom.rebases.items) |offset| { | 5756 | for (atom.rebases.items) |offset| { |
| 5757 | log.debug(" | rebase at {x}", .{base_offset + offset}); | ||
| 5743 | try rebase_pointers.append(.{ | 5758 | try rebase_pointers.append(.{ |
| 5744 | .offset = base_offset + offset, | 5759 | .offset = base_offset + offset, |
| 5745 | .segment_id = match.seg, | 5760 | .segment_id = match.seg, |
| ... | @@ -5747,33 +5762,53 @@ fn writeDyldInfoData(self: *MachO) !void { | ... | @@ -5747,33 +5762,53 @@ fn writeDyldInfoData(self: *MachO) !void { |
| 5747 | } | 5762 | } |
| 5748 | 5763 | ||
| 5749 | for (atom.bindings.items) |binding| { | 5764 | for (atom.bindings.items) |binding| { |
| 5750 | const global = self.globals.values()[binding.global_index]; | 5765 | const bind_sym = self.getSymbol(binding.target); |
| 5751 | const bind_sym = self.getSymbol(global); | 5766 | const bind_sym_name = self.getSymbolName(binding.target); |
| 5767 | const dylib_ordinal = @divTrunc( | ||
| 5768 | @bitCast(i16, bind_sym.n_desc), | ||
| 5769 | macho.N_SYMBOL_RESOLVER, | ||
| 5770 | ); | ||
| 5752 | var flags: u4 = 0; | 5771 | var flags: u4 = 0; |
| 5772 | log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{ | ||
| 5773 | binding.offset + base_offset, | ||
| 5774 | bind_sym_name, | ||
| 5775 | dylib_ordinal, | ||
| 5776 | }); | ||
| 5753 | if (bind_sym.weakRef()) { | 5777 | if (bind_sym.weakRef()) { |
| 5778 | log.debug(" | marking as weak ref ", .{}); | ||
| 5754 | flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); | 5779 | flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); |
| 5755 | } | 5780 | } |
| 5756 | try bind_pointers.append(.{ | 5781 | try bind_pointers.append(.{ |
| 5757 | .offset = binding.offset + base_offset, | 5782 | .offset = binding.offset + base_offset, |
| 5758 | .segment_id = match.seg, | 5783 | .segment_id = match.seg, |
| 5759 | .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), | 5784 | .dylib_ordinal = dylib_ordinal, |
| 5760 | .name = self.getSymbolName(global), | 5785 | .name = bind_sym_name, |
| 5761 | .bind_flags = flags, | 5786 | .bind_flags = flags, |
| 5762 | }); | 5787 | }); |
| 5763 | } | 5788 | } |
| 5764 | 5789 | ||
| 5765 | for (atom.lazy_bindings.items) |binding| { | 5790 | for (atom.lazy_bindings.items) |binding| { |
| 5766 | const global = self.globals.values()[binding.global_index]; | 5791 | const bind_sym = self.getSymbol(binding.target); |
| 5767 | const bind_sym = self.getSymbol(global); | 5792 | const bind_sym_name = self.getSymbolName(binding.target); |
| 5793 | const dylib_ordinal = @divTrunc( | ||
| 5794 | @bitCast(i16, bind_sym.n_desc), | ||
| 5795 | macho.N_SYMBOL_RESOLVER, | ||
| 5796 | ); | ||
| 5768 | var flags: u4 = 0; | 5797 | var flags: u4 = 0; |
| 5798 | log.debug(" | lazy bind at {x} import('{s}') ord({d})", .{ | ||
| 5799 | binding.offset + base_offset, | ||
| 5800 | bind_sym_name, | ||
| 5801 | dylib_ordinal, | ||
| 5802 | }); | ||
| 5769 | if (bind_sym.weakRef()) { | 5803 | if (bind_sym.weakRef()) { |
| 5804 | log.debug(" | marking as weak ref ", .{}); | ||
| 5770 | flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); | 5805 | flags |= @truncate(u4, macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT); |
| 5771 | } | 5806 | } |
| 5772 | try lazy_bind_pointers.append(.{ | 5807 | try lazy_bind_pointers.append(.{ |
| 5773 | .offset = binding.offset + base_offset, | 5808 | .offset = binding.offset + base_offset, |
| 5774 | .segment_id = match.seg, | 5809 | .segment_id = match.seg, |
| 5775 | .dylib_ordinal = @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER), | 5810 | .dylib_ordinal = dylib_ordinal, |
| 5776 | .name = self.getSymbolName(global), | 5811 | .name = bind_sym_name, |
| 5777 | .bind_flags = flags, | 5812 | .bind_flags = flags, |
| 5778 | }); | 5813 | }); |
| 5779 | } | 5814 | } |
src/link/MachO/Atom.zig+2-4| ... | @@ -71,7 +71,7 @@ dbg_info_atom: Dwarf.Atom, | ... | @@ -71,7 +71,7 @@ dbg_info_atom: Dwarf.Atom, |
| 71 | dirty: bool = true, | 71 | dirty: bool = true, |
| 72 | 72 | ||
| 73 | pub const Binding = struct { | 73 | pub const Binding = struct { |
| 74 | global_index: u32, | 74 | target: SymbolWithLoc, |
| 75 | offset: u64, | 75 | offset: u64, |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| ... | @@ -536,10 +536,8 @@ fn addPtrBindingOrRebase( | ... | @@ -536,10 +536,8 @@ fn addPtrBindingOrRebase( |
| 536 | const gpa = context.macho_file.base.allocator; | 536 | const gpa = context.macho_file.base.allocator; |
| 537 | const sym = context.macho_file.getSymbol(target); | 537 | const sym = context.macho_file.getSymbol(target); |
| 538 | if (sym.undf()) { | 538 | if (sym.undf()) { |
| 539 | const sym_name = context.macho_file.getSymbolName(target); | ||
| 540 | const global_index = @intCast(u32, context.macho_file.globals.getIndex(sym_name).?); | ||
| 541 | try self.bindings.append(gpa, .{ | 539 | try self.bindings.append(gpa, .{ |
| 542 | .global_index = global_index, | 540 | .target = target, |
| 543 | .offset = @intCast(u32, rel.r_address - context.base_offset), | 541 | .offset = @intCast(u32, rel.r_address - context.base_offset), |
| 544 | }); | 542 | }); |
| 545 | } else { | 543 | } else { |