authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-07-15 15:04:45+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-07-22 16:58:20+02:00
log61b4119a7d5862f58fc4a34024456e3feca292a5
tree2a092db743c902df7e746bc99f2dde18621af70e
parent35a5a4a0e45b4a92d6f7d0428fe1a4b64815edb9

macho: link atom starting section by orig section id

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.

2 files changed, 30 insertions(+), 7 deletions(-)

src/link/MachO/Atom.zig+4-7
......@@ -659,13 +659,10 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void {
659659 // If there is no atom for target, we still need to check for special, atom-less
660660 // symbols such as `___dso_handle`.
661661 const target_name = macho_file.getSymbolName(rel.target);
662 if (macho_file.globals.contains(target_name)) {
663 const atomless_sym = macho_file.getSymbol(rel.target);
664 log.debug(" | atomless target '{s}'", .{target_name});
665 break :blk atomless_sym.n_value;
666 }
667 log.debug(" | undef target '{s}'", .{target_name});
668 break :blk 0;
662 assert(macho_file.globals.contains(target_name));
663 const atomless_sym = macho_file.getSymbol(rel.target);
664 log.debug(" | atomless target '{s}'", .{target_name});
665 break :blk atomless_sym.n_value;
669666 };
670667 log.debug(" | target ATOM(%{d}, '{s}') in object({d})", .{
671668 target_atom.sym_index,
src/link/MachO/Object.zig+26
......@@ -425,6 +425,7 @@ pub fn splitIntoAtomsOneShot(self: *Object, macho_file: *MachO, object_id: u32)
425425 macho_file.getSection(match).sectName(),
426426 });
427427
428 const arch = macho_file.base.options.target.cpu.arch;
428429 const is_zerofill = blk: {
429430 const section_type = sect.type_();
430431 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)
538539 match,
539540 sect,
540541 );
542
543 if (arch == .x86_64 and addr == sect.addr) {
544 // In x86_64 relocs, it can so happen that the compiler refers to the same
545 // atom by both the actual assigned symbol and the start of the section. In this
546 // case, we need to link the two together so add an alias.
547 const alias = self.sections_as_symbols.get(sect_id) orelse blk: {
548 const alias = @intCast(u32, self.symtab.items.len);
549 try self.symtab.append(gpa, .{
550 .n_strx = 0,
551 .n_type = macho.N_SECT,
552 .n_sect = macho_file.getSectionOrdinal(match),
553 .n_desc = 0,
554 .n_value = addr,
555 });
556 try self.sections_as_symbols.putNoClobber(gpa, sect_id, alias);
557 break :blk alias;
558 };
559 try atom.contained.append(gpa, .{
560 .sym_index = alias,
561 .offset = 0,
562 .stab = null,
563 });
564 try self.atom_by_index_table.put(gpa, alias, atom);
565 }
566
541567 try macho_file.addAtomToSection(atom, match);
542568 }
543569 } else {