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 {
30473047 .seg = self.text_segment_cmd_index.?,
30483048 .sect = self.text_section_index.?,
30493049 };
3050 const seg = self.load_commands.items[match.seg].segment;
3051 const sect = seg.sections.items[match.sect];
3052
30503053 const n_strx = try self.makeString("__mh_execute_header");
30513054 const local_sym_index = @intCast(u32, self.locals.items.len);
30523055 var nlist = macho.nlist_64{
......@@ -3054,29 +3057,42 @@ fn createMhExecuteHeaderAtom(self: *MachO) !void {
30543057 .n_type = macho.N_SECT,
30553058 .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1),
30563059 .n_desc = 0,
3057 .n_value = 0,
3060 .n_value = sect.addr,
30583061 };
30593062 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;
3062 const global_sym_index = @intCast(u32, self.globals.items.len);
3063 try self.globals.append(self.base.allocator, nlist);
3064 try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{
3065 .where = .global,
3066 .where_index = global_sym_index,
3067 .local_sym_index = local_sym_index,
3068 .file = null,
3069 });
3065 if (self.symbol_resolver.getPtr(n_strx)) |resolv| {
3066 const global = &self.globals.items[resolv.where_index];
3067 if (!(global.weakDef() or !global.pext())) {
3068 log.err("symbol '__mh_execute_header' defined multiple times", .{});
3069 return error.MultipleSymbolDefinitions;
3070 }
3071 resolv.local_sym_index = local_sym_index;
3072 } else {
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
30713085 const atom = try self.createEmptyAtom(local_sym_index, 0, 0);
3072
3073 if (self.needs_prealloc) {
3074 const sym = &self.locals.items[local_sym_index];
3075 const vaddr = try self.allocateAtom(atom, 0, 1, match);
3076 sym.n_value = vaddr;
3077 } else try self.addAtomToSection(atom, match);
3078
3079 self.mh_execute_header_index = local_sym_index;
3086 if (self.atoms.get(match)) |last| {
3087 var first = last;
3088 while (first.prev) |prev| {
3089 first = prev;
3090 }
3091 atom.next = first;
3092 first.prev = atom;
3093 } else {
3094 try self.atoms.putNoClobber(self.base.allocator, match, atom);
3095 }
30803096}
30813097
30823098fn resolveDyldStubBinder(self: *MachO) !void {