diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-09-15 16:57:10 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-09-16 12:38:47 +0200 |
| commit | 983d6dcd9ea75e05abd8ce2bd247bbad3960acd7 (patch) | |
| tree | c5767d15a29bcc1e3704ca37e3dc0ddf54eca376 /src/link/MachO/Atom.zig | |
| parent | 506f24cac2f5226210f9ce505d5b93c47b7b8c87 (diff) | |
| download | zig-983d6dcd9ea75e05abd8ce2bd247bbad3960acd7.tar.gz zig-983d6dcd9ea75e05abd8ce2bd247bbad3960acd7.zip | |
macho: implement object relinking in stage2
* In watch mode, when changing the C source, we will trigger complete
relinking of objects, dylibs and archives (atoms coming from the
incremental updates stay put however). This means, we need to undo
metadata populated when linking in objects, archives and dylibs.
* Remove unused splitting section into atoms bit. This optimisation
will probably be best rewritten from scratch once self-hosted
matures so parking the idea for now. Also, for easier management
of atoms spawned from the Object file, keep the atoms subgraph as
part of the Object file struct.
* Remove obsolete ref to static initializers in object struct.
* Implement handling of global symbol collision in updateDeclExports.
Diffstat (limited to 'src/link/MachO/Atom.zig')
| -rw-r--r-- | src/link/MachO/Atom.zig | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index 298855934e..6dbe853451 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -645,7 +645,6 @@ const RelocContext = struct { allocator: *Allocator, object: *Object, macho_file: *MachO, - parsed_atoms: *Object.ParsedAtoms, }; fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Relocation { @@ -877,12 +876,16 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC .sect = context.macho_file.got_section_index.?, }; - if (context.parsed_atoms.getPtr(match)) |last| { + if (!context.object.start_atoms.contains(match)) { + try context.object.start_atoms.putNoClobber(context.allocator, match, atom); + } + + if (context.object.end_atoms.getPtr(match)) |last| { last.*.next = atom; atom.prev = last.*; last.* = atom; } else { - try context.parsed_atoms.putNoClobber(match, atom); + try context.object.end_atoms.putNoClobber(context.allocator, match, atom); } } else if (parsed_rel.payload == .unsigned) { switch (parsed_rel.where) { @@ -939,52 +942,63 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC if (parsed_rel.where != .undef) break :blk; if (context.macho_file.stubs_map.contains(parsed_rel.where_index)) break :blk; - const stub_helper_atom = try context.macho_file.createStubHelperAtom(); - const laptr_atom = try context.macho_file.createLazyPointerAtom( - stub_helper_atom.local_sym_index, - parsed_rel.where_index, - ); - const stub_atom = try context.macho_file.createStubAtom(laptr_atom.local_sym_index); - try context.macho_file.stubs_map.putNoClobber(context.allocator, parsed_rel.where_index, stub_atom); // TODO clean this up! - if (context.parsed_atoms.getPtr(.{ - .seg = context.macho_file.text_segment_cmd_index.?, - .sect = context.macho_file.stub_helper_section_index.?, - })) |last| { - last.*.next = stub_helper_atom; - stub_helper_atom.prev = last.*; - last.* = stub_helper_atom; - } else { - try context.parsed_atoms.putNoClobber(.{ + const stub_helper_atom = atom: { + const atom = try context.macho_file.createStubHelperAtom(); + const match = MachO.MatchingSection{ .seg = context.macho_file.text_segment_cmd_index.?, .sect = context.macho_file.stub_helper_section_index.?, - }, stub_helper_atom); - } - if (context.parsed_atoms.getPtr(.{ - .seg = context.macho_file.text_segment_cmd_index.?, - .sect = context.macho_file.stubs_section_index.?, - })) |last| { - last.*.next = stub_atom; - stub_atom.prev = last.*; - last.* = stub_atom; - } else { - try context.parsed_atoms.putNoClobber(.{ - .seg = context.macho_file.text_segment_cmd_index.?, - .sect = context.macho_file.stubs_section_index.?, - }, stub_atom); - } - if (context.parsed_atoms.getPtr(.{ - .seg = context.macho_file.data_segment_cmd_index.?, - .sect = context.macho_file.la_symbol_ptr_section_index.?, - })) |last| { - last.*.next = laptr_atom; - laptr_atom.prev = last.*; - last.* = laptr_atom; - } else { - try context.parsed_atoms.putNoClobber(.{ + }; + if (!context.object.start_atoms.contains(match)) { + try context.object.start_atoms.putNoClobber(context.allocator, match, atom); + } + if (context.object.end_atoms.getPtr(match)) |last| { + last.*.next = atom; + atom.prev = last.*; + last.* = atom; + } else { + try context.object.end_atoms.putNoClobber(context.allocator, match, atom); + } + break :atom atom; + }; + const laptr_atom = atom: { + const atom = try context.macho_file.createLazyPointerAtom( + stub_helper_atom.local_sym_index, + parsed_rel.where_index, + ); + const match = MachO.MatchingSection{ .seg = context.macho_file.data_segment_cmd_index.?, .sect = context.macho_file.la_symbol_ptr_section_index.?, - }, laptr_atom); + }; + if (!context.object.start_atoms.contains(match)) { + try context.object.start_atoms.putNoClobber(context.allocator, match, atom); + } + if (context.object.end_atoms.getPtr(match)) |last| { + last.*.next = atom; + atom.prev = last.*; + last.* = atom; + } else { + try context.object.end_atoms.putNoClobber(context.allocator, match, atom); + } + break :atom atom; + }; + { + const atom = try context.macho_file.createStubAtom(laptr_atom.local_sym_index); + const match = MachO.MatchingSection{ + .seg = context.macho_file.text_segment_cmd_index.?, + .sect = context.macho_file.stubs_section_index.?, + }; + if (!context.object.start_atoms.contains(match)) { + try context.object.start_atoms.putNoClobber(context.allocator, match, atom); + } + if (context.object.end_atoms.getPtr(match)) |last| { + last.*.next = atom; + atom.prev = last.*; + last.* = atom; + } else { + try context.object.end_atoms.putNoClobber(context.allocator, match, atom); + } + try context.macho_file.stubs_map.putNoClobber(context.allocator, parsed_rel.where_index, atom); } } } |
