diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index d58e898848..ecf2f10149 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -659,13 +659,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { // If there is no atom for target, we still need to check for special, atom-less // symbols such as `___dso_handle`. const target_name = macho_file.getSymbolName(rel.target); - if (macho_file.globals.contains(target_name)) { - const atomless_sym = macho_file.getSymbol(rel.target); - log.debug(" | atomless target '{s}'", .{target_name}); - break :blk atomless_sym.n_value; - } - log.debug(" | undef target '{s}'", .{target_name}); - break :blk 0; + assert(macho_file.globals.contains(target_name)); + const atomless_sym = macho_file.getSymbol(rel.target); + log.debug(" | atomless target '{s}'", .{target_name}); + break :blk atomless_sym.n_value; }; log.debug(" | target ATOM(%{d}, '{s}') in object({d})", .{ target_atom.sym_index, diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 91e2169b7d..2737b5e164 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -425,6 +425,7 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32) macho_file.getSection(match).sectName(), }); + const arch = macho_file.base.options.target.cpu.arch; const is_zerofill = blk: { const section_type = sect.type_(); break :blk section_type == macho.S_ZEROFILL or section_type == macho.S_THREAD_LOCAL_ZEROFILL; @@ -538,6 +539,31 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32) match, sect, ); + + if (arch == .x86_64 and addr == sect.addr) { + // In x86_64 relocs, it can so happen that the compiler refers to the same + // atom by both the actual assigned symbol and the start of the section. In this + // case, we need to link the two together so add an alias. + const alias = self.sections_as_symbols.get(sect_id) orelse blk: { + const alias = @intCast(u32, self.symtab.items.len); + try self.symtab.append(gpa, .{ + .n_strx = 0, + .n_type = macho.N_SECT, + .n_sect = macho_file.getSectionOrdinal(match), + .n_desc = 0, + .n_value = addr, + }); + try self.sections_as_symbols.putNoClobber(gpa, sect_id, alias); + break :blk alias; + }; + try atom.contained.append(gpa, .{ + .sym_index = alias, + .offset = 0, + .stab = null, + }); + try self.atom_by_index_table.put(gpa, alias, atom); + } + try macho_file.addAtomToSection(atom, match); } } else {