authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-26 22:05:42+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:39:35+02:00
log7f74b3562deaa0dedfc2945a702fe82dbd103aa2
tree1febb87377211d897c3d7e76baa0484985f5a769
parentef0d35e00cd1320b5f0ffde718422a69be54fe80

macho: unify creating atoms


5 files changed, 55 insertions(+), 48 deletions(-)

src/link/MachO.zig+31-21
...@@ -1410,30 +1410,29 @@ pub fn allocateSpecialSymbols(self: anytype) !void {...@@ -1410,30 +1410,29 @@ pub fn allocateSpecialSymbols(self: anytype) !void {
1410 }1410 }
1411}1411}
14121412
1413pub fn createAtom(self: *MachO) !Atom.Index {1413const CreateAtomOpts = struct {
1414 size: u64 = 0,
1415 alignment: u32 = 0,
1416};
1417
1418pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Index {
1414 const gpa = self.base.allocator;1419 const gpa = self.base.allocator;
1415 const atom_index = @as(Atom.Index, @intCast(self.atoms.items.len));1420 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
1416 const atom = try self.atoms.addOne(gpa);1421 const atom = try self.atoms.addOne(gpa);
1417 const sym_index = try self.allocateSymbol();1422 atom.* = .{};
1418 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);1423 atom.sym_index = sym_index;
1419 atom.* = .{1424 atom.size = opts.size;
1420 .sym_index = sym_index,1425 atom.alignment = opts.alignment;
1421 .inner_sym_index = 0,1426 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, index });
1422 .inner_nsyms_trailing = 0,1427 return index;
1423 .file = 0,
1424 .size = 0,
1425 .alignment = 0,
1426 .prev_index = null,
1427 .next_index = null,
1428 };
1429 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index });
1430 return atom_index;
1431}1428}
14321429
1433fn createDyldPrivateAtom(self: *MachO) !void {1430fn createDyldPrivateAtom(self: *MachO) !void {
1434 if (self.dyld_private_atom_index != null) return;1431 if (self.dyld_private_atom_index != null) return;
14351432
1436 const atom_index = try self.createAtom();1433 const sym_index = try self.allocateSymbol();
1434 const atom_index = try self.createAtom(sym_index, .{});
1435 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
1437 const atom = self.getAtomPtr(atom_index);1436 const atom = self.getAtomPtr(atom_index);
1438 atom.size = @sizeOf(u64);1437 atom.size = @sizeOf(u64);
14391438
...@@ -1452,7 +1451,9 @@ fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: S...@@ -1452,7 +1451,9 @@ fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: S
1452 const gpa = self.base.allocator;1451 const gpa = self.base.allocator;
1453 const size = 3 * @sizeOf(u64);1452 const size = 3 * @sizeOf(u64);
1454 const required_alignment: u32 = 1;1453 const required_alignment: u32 = 1;
1455 const atom_index = try self.createAtom();1454 const sym_index = try self.allocateSymbol();
1455 const atom_index = try self.createAtom(sym_index, .{});
1456 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
1456 self.getAtomPtr(atom_index).size = size;1457 self.getAtomPtr(atom_index).size = size;
14571458
1458 const sym = self.getAtom(atom_index).getSymbolPtr(self);1459 const sym = self.getAtom(atom_index).getSymbolPtr(self);
...@@ -1936,7 +1937,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu...@@ -1936,7 +1937,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
19361937
1937 log.debug("allocating symbol indexes for {s}", .{name});1938 log.debug("allocating symbol indexes for {s}", .{name});
19381939
1939 const atom_index = try self.createAtom();1940 const sym_index = try self.allocateSymbol();
1941 const atom_index = try self.createAtom(sym_index, .{});
1942 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
19401943
1941 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), typed_value, &code_buffer, .none, .{1944 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), typed_value, &code_buffer, .none, .{
1942 .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,1945 .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
...@@ -2138,7 +2141,11 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In...@@ -2138,7 +2141,11 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
2138 },2141 },
2139 };2142 };
2140 switch (metadata.state.*) {2143 switch (metadata.state.*) {
2141 .unused => metadata.atom.* = try self.createAtom(),2144 .unused => {
2145 const sym_index = try self.allocateSymbol();
2146 metadata.atom.* = try self.createAtom(sym_index, .{});
2147 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, metadata.atom.*);
2148 },
2142 .pending_flush => return metadata.atom.*,2149 .pending_flush => return metadata.atom.*,
2143 .flushed => {},2150 .flushed => {},
2144 }2151 }
...@@ -2250,8 +2257,11 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D...@@ -2250,8 +2257,11 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
2250pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {2257pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {
2251 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);2258 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
2252 if (!gop.found_existing) {2259 if (!gop.found_existing) {
2260 const sym_index = try self.allocateSymbol();
2261 const atom_index = try self.createAtom(sym_index, .{});
2262 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
2253 gop.value_ptr.* = .{2263 gop.value_ptr.* = .{
2254 .atom = try self.createAtom(),2264 .atom = atom_index,
2255 .section = self.getDeclOutputSection(decl_index),2265 .section = self.getDeclOutputSection(decl_index),
2256 .exports = .{},2266 .exports = .{},
2257 };2267 };
src/link/MachO/Atom.zig+8-8
...@@ -4,13 +4,13 @@...@@ -4,13 +4,13 @@
4/// a stub trampoline, it can be found in the linkers `locals` arraylist.4/// a stub trampoline, it can be found in the linkers `locals` arraylist.
5/// If this field is 0 and file is 0, it means the codegen size = 0 and there is no symbol or5/// If this field is 0 and file is 0, it means the codegen size = 0 and there is no symbol or
6/// offset table entry.6/// offset table entry.
7sym_index: u32,7sym_index: u32 = 0,
88
9/// 0 means an Atom is a synthetic Atom such as a GOT cell defined by the linker.9/// 0 means an Atom is a synthetic Atom such as a GOT cell defined by the linker.
10/// Otherwise, it is the index into appropriate object file (indexing from 1).10/// Otherwise, it is the index into appropriate object file (indexing from 1).
11/// Prefer using `getFile()` helper to get the file index out rather than using11/// Prefer using `getFile()` helper to get the file index out rather than using
12/// the field directly.12/// the field directly.
13file: u32,13file: u32 = 0,
1414
15/// If this Atom is not a synthetic Atom, i.e., references a subsection in an15/// If this Atom is not a synthetic Atom, i.e., references a subsection in an
16/// Object file, `inner_sym_index` and `inner_nsyms_trailing` tell where and if16/// Object file, `inner_sym_index` and `inner_nsyms_trailing` tell where and if
...@@ -18,22 +18,22 @@ file: u32,...@@ -18,22 +18,22 @@ file: u32,
18/// address range. These could for example be an alias symbol which can be used18/// address range. These could for example be an alias symbol which can be used
19/// internally by the relocation records, or if the Object file couldn't be split19/// internally by the relocation records, or if the Object file couldn't be split
20/// into subsections, this Atom may encompass an entire input section.20/// into subsections, this Atom may encompass an entire input section.
21inner_sym_index: u32,21inner_sym_index: u32 = 0,
22inner_nsyms_trailing: u32,22inner_nsyms_trailing: u32 = 0,
2323
24/// Size and alignment of this atom24/// Size and alignment of this atom
25/// Unlike in Elf, we need to store the size of this symbol as part of25/// Unlike in Elf, we need to store the size of this symbol as part of
26/// the atom since macho.nlist_64 lacks this information.26/// the atom since macho.nlist_64 lacks this information.
27size: u64,27size: u64 = 0,
2828
29/// Alignment of this atom as a power of 2.29/// Alignment of this atom as a power of 2.
30/// For instance, aligmment of 0 should be read as 2^0 = 1 byte aligned.30/// For instance, aligmment of 0 should be read as 2^0 = 1 byte aligned.
31alignment: u32,31alignment: u32 = 0,
3232
33/// Points to the previous and next neighbours33/// Points to the previous and next neighbours
34/// TODO use the same trick as with symbols: reserve index 0 as null atom34/// TODO use the same trick as with symbols: reserve index 0 as null atom
35next_index: ?Index,35next_index: ?Index = null,
36prev_index: ?Index,36prev_index: ?Index = null,
3737
38pub const Index = u32;38pub const Index = u32;
3939
src/link/MachO/Object.zig+1-1
...@@ -573,7 +573,7 @@ fn createAtomFromSubsection(...@@ -573,7 +573,7 @@ fn createAtomFromSubsection(
573 out_sect_id: u8,573 out_sect_id: u8,
574) !Atom.Index {574) !Atom.Index {
575 const gpa = zld.gpa;575 const gpa = zld.gpa;
576 const atom_index = try zld.createEmptyAtom(sym_index, size, alignment);576 const atom_index = try zld.createAtom(sym_index, .{ .size = size, .alignment = alignment });
577 const atom = zld.getAtomPtr(atom_index);577 const atom = zld.getAtomPtr(atom_index);
578 atom.inner_sym_index = inner_sym_index;578 atom.inner_sym_index = inner_sym_index;
579 atom.inner_nsyms_trailing = inner_nsyms_trailing;579 atom.inner_nsyms_trailing = inner_nsyms_trailing;
src/link/MachO/thunks.zig+1-1
...@@ -342,7 +342,7 @@ fn isReachable(...@@ -342,7 +342,7 @@ fn isReachable(
342342
343fn createThunkAtom(zld: *Zld) !Atom.Index {343fn createThunkAtom(zld: *Zld) !Atom.Index {
344 const sym_index = try zld.allocateSymbol();344 const sym_index = try zld.allocateSymbol();
345 const atom_index = try zld.createEmptyAtom(sym_index, @sizeOf(u32) * 3, 2);345 const atom_index = try zld.createAtom(sym_index, .{ .size = @sizeOf(u32) * 3, .alignment = 2 });
346 const sym = zld.getSymbolPtr(.{ .sym_index = sym_index });346 const sym = zld.getSymbolPtr(.{ .sym_index = sym_index });
347 sym.n_type = macho.N_SECT;347 sym.n_type = macho.N_SECT;
348 sym.n_sect = zld.text_section_index.? + 1;348 sym.n_sect = zld.text_section_index.? + 1;
src/link/MachO/zld.zig+14-17
...@@ -112,32 +112,26 @@ pub const Zld = struct {...@@ -112,32 +112,26 @@ pub const Zld = struct {
112 self.sections.set(sym.n_sect - 1, section);112 self.sections.set(sym.n_sect - 1, section);
113 }113 }
114114
115 pub fn createEmptyAtom(self: *Zld, sym_index: u32, size: u64, alignment: u32) !Atom.Index {115 const CreateAtomOpts = struct {
116 size: u64 = 0,
117 alignment: u32 = 0,
118 };
119
120 pub fn createAtom(self: *Zld, sym_index: u32, opts: CreateAtomOpts) !Atom.Index {
116 const gpa = self.gpa;121 const gpa = self.gpa;
117 const index = @as(Atom.Index, @intCast(self.atoms.items.len));122 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
118 const atom = try self.atoms.addOne(gpa);123 const atom = try self.atoms.addOne(gpa);
119 atom.* = .{124 atom.* = .{};
120 .sym_index = 0,
121 .inner_sym_index = 0,
122 .inner_nsyms_trailing = 0,
123 .file = 0,
124 .size = 0,
125 .alignment = 0,
126 .prev_index = null,
127 .next_index = null,
128 };
129 atom.sym_index = sym_index;125 atom.sym_index = sym_index;
130 atom.size = size;126 atom.size = opts.size;
131 atom.alignment = alignment;127 atom.alignment = opts.alignment;
132
133 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, index });128 log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, index });
134
135 return index;129 return index;
136 }130 }
137131
138 fn createDyldPrivateAtom(self: *Zld) !void {132 fn createDyldPrivateAtom(self: *Zld) !void {
139 const sym_index = try self.allocateSymbol();133 const sym_index = try self.allocateSymbol();
140 const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3);134 const atom_index = try self.createAtom(sym_index, .{ .size = @sizeOf(u64), .alignment = 3 });
141 const sym = self.getSymbolPtr(.{ .sym_index = sym_index });135 const sym = self.getSymbolPtr(.{ .sym_index = sym_index });
142 sym.n_type = macho.N_SECT;136 sym.n_type = macho.N_SECT;
143137
...@@ -176,7 +170,10 @@ pub const Zld = struct {...@@ -176,7 +170,10 @@ pub const Zld = struct {
176 .n_value = 0,170 .n_value = 0,
177 };171 };
178172
179 const atom_index = try self.createEmptyAtom(global.sym_index, size, alignment);173 const atom_index = try self.createAtom(global.sym_index, .{
174 .size = size,
175 .alignment = alignment,
176 });
180 const atom = self.getAtomPtr(atom_index);177 const atom = self.getAtomPtr(atom_index);
181 atom.file = global.file;178 atom.file = global.file;
182179