| author | |
| committer | |
| log | 7f74b3562deaa0dedfc2945a702fe82dbd103aa2 |
| tree | 1febb87377211d897c3d7e76baa0484985f5a769 |
| parent | ef0d35e00cd1320b5f0ffde718422a69be54fe80 |
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 | } |
| 1412 | 1412 | ||
| 1413 | pub fn createAtom(self: *MachO) !Atom.Index { | 1413 | const CreateAtomOpts = struct { |
| 1414 | size: u64 = 0, | ||
| 1415 | alignment: u32 = 0, | ||
| 1416 | }; | ||
| 1417 | |||
| 1418 | pub 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 | } |
| 1432 | 1429 | ||
| 1433 | fn createDyldPrivateAtom(self: *MachO) !void { | 1430 | fn createDyldPrivateAtom(self: *MachO) !void { |
| 1434 | if (self.dyld_private_atom_index != null) return; | 1431 | if (self.dyld_private_atom_index != null) return; |
| 1435 | 1432 | ||
| 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); |
| 1439 | 1438 | ||
| ... | @@ -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; |
| 1457 | 1458 | ||
| 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 |
| 1936 | 1937 | ||
| 1937 | log.debug("allocating symbol indexes for {s}", .{name}); | 1938 | log.debug("allocating symbol indexes for {s}", .{name}); |
| 1938 | 1939 | ||
| 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); | ||
| 1940 | 1943 | ||
| 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 |
| 2250 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { | 2257 | pub 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 or | 5 | /// 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. |
| 7 | sym_index: u32, | 7 | sym_index: u32 = 0, |
| 8 | 8 | ||
| 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 using | 11 | /// Prefer using `getFile()` helper to get the file index out rather than using |
| 12 | /// the field directly. | 12 | /// the field directly. |
| 13 | file: u32, | 13 | file: u32 = 0, |
| 14 | 14 | ||
| 15 | /// If this Atom is not a synthetic Atom, i.e., references a subsection in an | 15 | /// 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 if | 16 | /// 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 used | 18 | /// 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 split | 19 | /// 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. |
| 21 | inner_sym_index: u32, | 21 | inner_sym_index: u32 = 0, |
| 22 | inner_nsyms_trailing: u32, | 22 | inner_nsyms_trailing: u32 = 0, |
| 23 | 23 | ||
| 24 | /// Size and alignment of this atom | 24 | /// Size and alignment of this atom |
| 25 | /// Unlike in Elf, we need to store the size of this symbol as part of | 25 | /// 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. |
| 27 | size: u64, | 27 | size: u64 = 0, |
| 28 | 28 | ||
| 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. |
| 31 | alignment: u32, | 31 | alignment: u32 = 0, |
| 32 | 32 | ||
| 33 | /// Points to the previous and next neighbours | 33 | /// Points to the previous and next neighbours |
| 34 | /// TODO use the same trick as with symbols: reserve index 0 as null atom | 34 | /// TODO use the same trick as with symbols: reserve index 0 as null atom |
| 35 | next_index: ?Index, | 35 | next_index: ?Index = null, |
| 36 | prev_index: ?Index, | 36 | prev_index: ?Index = null, |
| 37 | 37 | ||
| 38 | pub const Index = u32; | 38 | pub const Index = u32; |
| 39 | 39 |
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( |
| 342 | 342 | ||
| 343 | fn createThunkAtom(zld: *Zld) !Atom.Index { | 343 | fn 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 | } |
| 114 | 114 | ||
| 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 | } |
| 137 | 131 | ||
| 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; |
| 143 | 137 | ||
| ... | @@ -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 | }; |
| 178 | 172 | ||
| 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; |
| 182 | 179 |