aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Atom.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-09-15 16:57:10 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-09-16 12:38:47 +0200
commit983d6dcd9ea75e05abd8ce2bd247bbad3960acd7 (patch)
treec5767d15a29bcc1e3704ca37e3dc0ddf54eca376 /src/link/MachO/Atom.zig
parent506f24cac2f5226210f9ce505d5b93c47b7b8c87 (diff)
downloadzig-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.zig102
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);
}
}
}