authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 18:42:07+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-23 19:10:40+01:00
log897a5a4735d5e72c53529a9a3f3a815943568214
treec9ab32038efef948c28d1b56678c87fe3e0bb9bd
parentacec06cfaf9a82ec8037a23993ff36fa72eb6e82

macho: synthesising __mh_execute_header needs to work with incremental

Prior to this change, the routine would assume it is called first, before any symbol was created, thus precluding an option that in the incremental setting, we might have already pulled a suitably defined and exported symbol that could collide and/or be replaced by the symbol synthesised by the linker.

1 files changed, 34 insertions(+), 18 deletions(-)

src/link/MachO.zig+34-18
...@@ -3047,6 +3047,9 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {...@@ -3047,6 +3047,9 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {
3047 .seg = self.text_segment_cmd_index.?,3047 .seg = self.text_segment_cmd_index.?,
3048 .sect = self.text_section_index.?,3048 .sect = self.text_section_index.?,
3049 };3049 };
3050 const seg = self.load_commands.items[match.seg].segment;
3051 const sect = seg.sections.items[match.sect];
3052
3050 const n_strx = try self.makeString("__mh_execute_header");3053 const n_strx = try self.makeString("__mh_execute_header");
3051 const local_sym_index = @intCast(u32, self.locals.items.len);3054 const local_sym_index = @intCast(u32, self.locals.items.len);
3052 var nlist = macho.nlist_64{3055 var nlist = macho.nlist_64{
...@@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {...@@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {
3054 .n_type = macho.N_SECT,3057 .n_type = macho.N_SECT,
3055 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),3058 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
3056 .n_desc = 0,3059 .n_desc = 0,
3057 .n_value = 0,3060 .n_value = sect.addr,
3058 };3061 };
3059 try self.locals.append(self.base.allocator, nlist);3062 try self.locals.append(self.base.allocator, nlist);
3063 self.mh_execute_header_index = local_sym_index;
30603064
3061 nlist.n_type |= macho.N_EXT;3065 if (self.symbol_resolver.getPtr(n_strx)) |resolv| {
3062 const global_sym_index = @intCast(u32, self.globals.items.len);3066 const global = &self.globals.items[resolv.where_index];
3063 try self.globals.append(self.base.allocator, nlist);3067 if (!(global.weakDef() or !global.pext())) {
3064 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{3068 log.err("symbol '__mh_execute_header' defined multiple times", .{});
3065 .where = .global,3069 return error.MultipleSymbolDefinitions;
3066 .where_index = global_sym_index,3070 }
3067 .local_sym_index = local_sym_index,3071 resolv.local_sym_index = local_sym_index;
3068 .file = null,3072 } else {
3069 });3073 const global_sym_index = @intCast(u32, self.globals.items.len);
3074 nlist.n_type |= macho.N_EXT;
3075 try self.globals.append(self.base.allocator, nlist);
3076 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
3077 .where = .global,
3078 .where_index = global_sym_index,
3079 .local_sym_index = local_sym_index,
3080 .file = null,
3081 });
3082 }
30703083
3084 // We always set the __mh_execute_header to point to the beginning of the __TEXT,__text section
3071 const atom = try self.createEmptyAtom(local_sym_index, 0, 0);3085 const atom = try self.createEmptyAtom(local_sym_index, 0, 0);
30723086 if (self.atoms.get(match)) |last| {
3073 if (self.needs_prealloc) {3087 var first = last;
3074 const sym = &self.locals.items[local_sym_index];3088 while (first.prev) |prev| {
3075 const vaddr = try self.allocateAtom(atom, 0, 1, match);3089 first = prev;
3076 sym.n_value = vaddr;3090 }
3077 } else try self.addAtomToSection(atom, match);3091 atom.next = first;
30783092 first.prev = atom;
3079 self.mh_execute_header_index = local_sym_index;3093 } else {
3094 try self.atoms.putNoClobber(self.base.allocator, match, atom);
3095 }
3080}3096}
30813097
3082fn resolveDyldStubBinder(self: *MachO) !void {3098fn resolveDyldStubBinder(self: *MachO) !void {