authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-15 18:26:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
log103c16c87955facd373bd20435100fa7eb322349
treee0c905217bc9b8d2ecfdfdf774b2b62ea2238adc
parente117e05768be08078a8484eaf982cfa5347a674e

macho: clean up atom+symbol creation logic in ZigObject


2 files changed, 79 insertions(+), 66 deletions(-)

src/link/MachO/InternalObject.zig+11-11
......@@ -52,8 +52,8 @@ pub fn init(self: *InternalObject, allocator: Allocator) !void {
5252}
5353
5454pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
55 const createSymbol = struct {
56 fn createSymbol(obj: *InternalObject, name: u32, args: struct {
55 const newSymbolAssumeCapacity = struct {
56 fn newSymbolAssumeCapacity(obj: *InternalObject, name: u32, args: struct {
5757 type: u8 = macho.N_UNDF | macho.N_EXT,
5858 desc: u16 = 0,
5959 }) Symbol.Index {
......@@ -78,7 +78,7 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
7878 symbol.nlist_idx = nlist_idx;
7979 return index;
8080 }
81 }.createSymbol;
81 }.newSymbolAssumeCapacity;
8282
8383 const gpa = macho_file.base.comp.gpa;
8484 var nsyms = macho_file.base.comp.force_undefined_symbols.keys().len;
......@@ -102,28 +102,28 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
102102
103103 try self.force_undefined.ensureTotalCapacityPrecise(gpa, macho_file.base.comp.force_undefined_symbols.keys().len);
104104 for (macho_file.base.comp.force_undefined_symbols.keys()) |name| {
105 self.force_undefined.addOneAssumeCapacity().* = createSymbol(self, try self.addString(gpa, name), .{});
105 self.force_undefined.addOneAssumeCapacity().* = newSymbolAssumeCapacity(self, try self.addString(gpa, name), .{});
106106 }
107107
108 self.dyld_stub_binder_index = createSymbol(self, try self.addString(gpa, "dyld_stub_binder"), .{});
109 self.objc_msg_send_index = createSymbol(self, try self.addString(gpa, "_objc_msgSend"), .{});
108 self.dyld_stub_binder_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_stub_binder"), .{});
109 self.objc_msg_send_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_objc_msgSend"), .{});
110110
111111 if (!macho_file.base.isDynLib()) {
112 self.entry_index = createSymbol(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{});
113 self.mh_execute_header_index = createSymbol(self, try self.addString(gpa, "__mh_execute_header"), .{
112 self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{});
113 self.mh_execute_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_execute_header"), .{
114114 .type = macho.N_SECT | macho.N_EXT,
115115 .desc = macho.REFERENCED_DYNAMICALLY,
116116 });
117117 } else {
118 self.mh_dylib_header_index = createSymbol(self, try self.addString(gpa, "__mh_dylib_header"), .{
118 self.mh_dylib_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_dylib_header"), .{
119119 .type = macho.N_SECT | macho.N_EXT,
120120 });
121121 }
122122
123 self.dso_handle_index = createSymbol(self, try self.addString(gpa, "___dso_handle"), .{
123 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "___dso_handle"), .{
124124 .type = macho.N_SECT | macho.N_EXT,
125125 });
126 self.dyld_private_index = createSymbol(self, try self.addString(gpa, "dyld_private"), .{
126 self.dyld_private_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_private"), .{
127127 .type = macho.N_SECT,
128128 });
129129}
src/link/MachO/ZigObject.zig+68-55
......@@ -141,34 +141,64 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
141141 }
142142}
143143
144fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
144fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {
145 type: u8 = macho.N_UNDF | macho.N_EXT,
146 desc: u16 = 0,
147}) !Symbol.Index {
145148 try self.symtab.ensureUnusedCapacity(allocator, 1);
146 const index = @as(Symbol.Index, @intCast(self.symtab.addOneAssumeCapacity()));
147 self.symtab.set(index, .{
148 .nlist = MachO.null_sym,
149 try self.symbols.ensureUnusedCapacity(allocator, 1);
150 try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra));
151 try self.globals.ensureUnusedCapacity(allocator, 1);
152
153 const index = self.addSymbolAssumeCapacity();
154 const symbol = &self.symbols.items[index];
155 symbol.name = name;
156 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
157
158 const nlist_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
159 self.symtab.set(nlist_idx, .{
160 .nlist = .{
161 .n_strx = name,
162 .n_type = args.type,
163 .n_sect = 0,
164 .n_desc = args.desc,
165 .n_value = 0,
166 },
149167 .size = 0,
150168 .atom = 0,
151169 });
170 symbol.nlist_idx = nlist_idx;
171
172 self.globals.appendAssumeCapacity(0);
173
152174 return index;
153175}
154176
155pub fn createAtomForDecl(self: *ZigObject, allocator: Allocator, macho_file: *MachO) !Symbol.Index {
156 const atom_index = try self.addAtom(allocator);
157 const symbol_index = try self.addSymbol(allocator);
158 const nlist_index = try self.addNlist(allocator);
159 self.symtab.items(.atom)[nlist_index] = atom_index;
160 try self.atoms_indexes.append(allocator, atom_index);
161 const symbol = &self.symbols.items[symbol_index];
162 symbol.atom_ref = .{ .index = atom_index, .file = self.index };
163 symbol.nlist_idx = nlist_index;
164 symbol.extra = try self.addSymbolExtra(allocator, .{});
177fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Atom.Index {
178 try self.atoms.ensureUnusedCapacity(allocator, 1);
179 try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra));
180 try self.atoms_indexes.ensureUnusedCapacity(allocator, 1);
181 try self.relocs.ensureUnusedCapacity(allocator, 1);
182
183 const index = self.addAtomAssumeCapacity();
184 self.atoms_indexes.appendAssumeCapacity(index);
185 const atom = self.getAtom(index).?;
186 atom.name = name;
187
165188 const relocs_index = @as(u32, @intCast(self.relocs.items.len));
166 const relocs = try self.relocs.addOne(allocator);
167 relocs.* = .{};
168 const atom = self.getAtom(atom_index).?;
189 self.relocs.addOneAssumeCapacity().* = .{};
169190 atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
170 try self.globals.append(allocator, 0);
171 return symbol_index;
191
192 return index;
193}
194
195fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Symbol.Index {
196 const atom_index = try self.newAtom(allocator, name, macho_file);
197 const sym_index = try self.newSymbol(allocator, name, .{ .type = macho.N_SECT });
198 const sym = &self.symbols.items[sym_index];
199 sym.atom_ref = .{ .index = atom_index, .file = self.index };
200 self.symtab.items(.atom)[sym.nlist_idx] = atom_index;
201 return sym_index;
172202}
173203
174204pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void {
......@@ -1079,27 +1109,19 @@ fn createTlvInitializer(
10791109 const gpa = macho_file.base.comp.gpa;
10801110 const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name});
10811111 defer gpa.free(sym_name);
1112 const off = try self.strtab.insert(gpa, sym_name);
10821113
1083 const sym_index = try self.createAtomForDecl(gpa, macho_file);
1114 const sym_index = try self.newSymbolWithAtom(gpa, off, macho_file);
10841115 const sym = &self.symbols.items[sym_index];
10851116 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
10861117 const atom = sym.getAtom(macho_file).?;
1087
10881118 sym.out_n_sect = sect_index;
10891119 atom.out_n_sect = sect_index;
1090
1091 sym.value = 0;
1092 sym.name = try self.strtab.insert(gpa, sym_name);
10931120 atom.flags.alive = true;
1094 atom.name = sym.name;
1095 nlist.n_strx = sym.name;
1096 nlist.n_sect = sect_index + 1;
1097 nlist.n_type = macho.N_SECT;
1098 nlist.n_value = 0;
1099 self.symtab.items(.size)[sym.nlist_idx] = code.len;
1100
11011121 atom.alignment = alignment;
11021122 atom.size = code.len;
1123 nlist.n_sect = sect_index + 1;
1124 self.symtab.items(.size)[sym.nlist_idx] = code.len;
11031125
11041126 const slice = macho_file.sections.slice();
11051127 const header = slice.items(.header)[sect_index];
......@@ -1293,7 +1315,8 @@ fn lowerConst(
12931315 var code_buffer = std.ArrayList(u8).init(gpa);
12941316 defer code_buffer.deinit();
12951317
1296 const sym_index = try self.createAtomForDecl(gpa, macho_file);
1318 const name_str_index = try self.strtab.insert(gpa, name);
1319 const sym_index = try self.newSymbolWithAtom(gpa, name_str_index, macho_file);
12971320
12981321 const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
12991322 .none = {},
......@@ -1306,19 +1329,14 @@ fn lowerConst(
13061329 };
13071330
13081331 const sym = &self.symbols.items[sym_index];
1309 const name_str_index = try self.strtab.insert(gpa, name);
1310 sym.name = name_str_index;
13111332 sym.out_n_sect = output_section_index;
13121333
13131334 const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
1314 nlist.n_strx = name_str_index;
1315 nlist.n_type = macho.N_SECT;
13161335 nlist.n_sect = output_section_index + 1;
13171336 self.symtab.items(.size)[sym.nlist_idx] = code.len;
13181337
13191338 const atom = sym.getAtom(macho_file).?;
13201339 atom.flags.alive = true;
1321 atom.name = name_str_index;
13221340 atom.alignment = required_alignment;
13231341 atom.size = code.len;
13241342 atom.out_n_sect = output_section_index;
......@@ -1327,9 +1345,6 @@ fn lowerConst(
13271345 // TODO rename and re-audit this method
13281346 errdefer self.freeDeclMetadata(macho_file, sym_index);
13291347
1330 sym.value = 0;
1331 nlist.n_value = 0;
1332
13331348 const sect = macho_file.sections.items(.header)[output_section_index];
13341349 const file_offset = sect.offset + atom.value;
13351350 try macho_file.base.file.?.pwriteAll(code, file_offset);
......@@ -1560,17 +1575,9 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
15601575 const off = try self.strtab.insert(gpa, sym_name);
15611576 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
15621577 if (!lookup_gop.found_existing) {
1563 const sym_index = try self.addSymbol(gpa);
1578 const sym_index = try self.newSymbol(gpa, off, .{});
15641579 const sym = &self.symbols.items[sym_index];
1565 const nlist_index = try self.addNlist(gpa);
1566 const nlist = &self.symtab.items(.nlist)[nlist_index];
1567 nlist.n_strx = off;
1568 nlist.n_type = macho.N_EXT;
1569 sym.name = off;
1570 sym.nlist_idx = nlist_index;
1571 sym.extra = try self.addSymbolExtra(gpa, .{});
1572 lookup_gop.value_ptr.* = nlist_index;
1573 try self.globals.append(gpa, 0);
1580 lookup_gop.value_ptr.* = sym.nlist_idx;
15741581 }
15751582 return lookup_gop.value_ptr.*;
15761583}
......@@ -1584,10 +1591,10 @@ pub fn getOrCreateMetadataForDecl(
15841591 const gop = try self.decls.getOrPut(gpa, decl_index);
15851592 if (!gop.found_existing) {
15861593 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
1587 const sym_index = try self.createAtomForDecl(gpa, macho_file);
1594 const sym_index = try self.newSymbolWithAtom(gpa, 0, macho_file);
1595 const sym = &self.symbols.items[sym_index];
15881596 const mod = macho_file.base.comp.module.?;
15891597 const decl = mod.declPtr(decl_index);
1590 const sym = &self.symbols.items[sym_index];
15911598 if (decl.getOwnedVariable(mod)) |variable| {
15921599 if (variable.is_threadlocal and any_non_single_threaded) {
15931600 sym.flags.tlv = true;
......@@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol(
16271634 };
16281635 switch (metadata.state.*) {
16291636 .unused => {
1630 const symbol_index = try self.createAtomForDecl(gpa, macho_file);
1637 const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file);
16311638 const sym = &self.symbols.items[symbol_index];
16321639 sym.flags.needs_zig_got = true;
16331640 metadata.symbol_index.* = symbol_index;
......@@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol(
16431650}
16441651
16451652fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {
1653 try self.atoms.ensureUnusedCapacity(allocator, 1);
1654 try self.atoms_extra.ensureUnusedCapacity(allocator, 1);
1655 return self.addAtomAssumeCapacity();
1656}
1657
1658fn addAtomAssumeCapacity(self: *ZigObject) Atom.Index {
16461659 const atom_index: Atom.Index = @intCast(self.atoms.items.len);
1647 const atom = try self.atoms.addOne(allocator);
1660 const atom = self.atoms.addOneAssumeCapacity();
16481661 atom.* = .{
16491662 .file = self.index,
16501663 .atom_index = atom_index,
1651 .extra = try self.addAtomExtra(allocator, .{}),
1664 .extra = self.addAtomExtraAssumeCapacity(.{}),
16521665 };
16531666 return atom_index;
16541667}