| ... | ... | @@ -141,34 +141,64 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 141 | 141 | } |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | | fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| 144 | fn 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 { |
| 145 | 148 | 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 | }, |
| 149 | 167 | .size = 0, |
| 150 | 168 | .atom = 0, |
| 151 | 169 | }); |
| 170 | symbol.nlist_idx = nlist_idx; |
| 171 | |
| 172 | self.globals.appendAssumeCapacity(0); |
| 173 | |
| 152 | 174 | return index; |
| 153 | 175 | } |
| 154 | 176 | |
| 155 | | pub 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, .{}); |
| 177 | fn 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 | |
| 165 | 188 | 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().* = .{}; |
| 169 | 190 | 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 | |
| 195 | fn 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; |
| 172 | 202 | } |
| 173 | 203 | |
| 174 | 204 | pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void { |
| ... | ... | @@ -1079,27 +1109,19 @@ fn createTlvInitializer( |
| 1079 | 1109 | const gpa = macho_file.base.comp.gpa; |
| 1080 | 1110 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); |
| 1081 | 1111 | defer gpa.free(sym_name); |
| 1112 | const off = try self.strtab.insert(gpa, sym_name); |
| 1082 | 1113 | |
| 1083 | | const sym_index = try self.createAtomForDecl(gpa, macho_file); |
| 1114 | const sym_index = try self.newSymbolWithAtom(gpa, off, macho_file); |
| 1084 | 1115 | const sym = &self.symbols.items[sym_index]; |
| 1085 | 1116 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 1086 | 1117 | const atom = sym.getAtom(macho_file).?; |
| 1087 | | |
| 1088 | 1118 | sym.out_n_sect = sect_index; |
| 1089 | 1119 | atom.out_n_sect = sect_index; |
| 1090 | | |
| 1091 | | sym.value = 0; |
| 1092 | | sym.name = try self.strtab.insert(gpa, sym_name); |
| 1093 | 1120 | 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 | | |
| 1101 | 1121 | atom.alignment = alignment; |
| 1102 | 1122 | atom.size = code.len; |
| 1123 | nlist.n_sect = sect_index + 1; |
| 1124 | self.symtab.items(.size)[sym.nlist_idx] = code.len; |
| 1103 | 1125 | |
| 1104 | 1126 | const slice = macho_file.sections.slice(); |
| 1105 | 1127 | const header = slice.items(.header)[sect_index]; |
| ... | ... | @@ -1293,7 +1315,8 @@ fn lowerConst( |
| 1293 | 1315 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1294 | 1316 | defer code_buffer.deinit(); |
| 1295 | 1317 | |
| 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); |
| 1297 | 1320 | |
| 1298 | 1321 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1299 | 1322 | .none = {}, |
| ... | ... | @@ -1306,19 +1329,14 @@ fn lowerConst( |
| 1306 | 1329 | }; |
| 1307 | 1330 | |
| 1308 | 1331 | const sym = &self.symbols.items[sym_index]; |
| 1309 | | const name_str_index = try self.strtab.insert(gpa, name); |
| 1310 | | sym.name = name_str_index; |
| 1311 | 1332 | sym.out_n_sect = output_section_index; |
| 1312 | 1333 | |
| 1313 | 1334 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 1314 | | nlist.n_strx = name_str_index; |
| 1315 | | nlist.n_type = macho.N_SECT; |
| 1316 | 1335 | nlist.n_sect = output_section_index + 1; |
| 1317 | 1336 | self.symtab.items(.size)[sym.nlist_idx] = code.len; |
| 1318 | 1337 | |
| 1319 | 1338 | const atom = sym.getAtom(macho_file).?; |
| 1320 | 1339 | atom.flags.alive = true; |
| 1321 | | atom.name = name_str_index; |
| 1322 | 1340 | atom.alignment = required_alignment; |
| 1323 | 1341 | atom.size = code.len; |
| 1324 | 1342 | atom.out_n_sect = output_section_index; |
| ... | ... | @@ -1327,9 +1345,6 @@ fn lowerConst( |
| 1327 | 1345 | // TODO rename and re-audit this method |
| 1328 | 1346 | errdefer self.freeDeclMetadata(macho_file, sym_index); |
| 1329 | 1347 | |
| 1330 | | sym.value = 0; |
| 1331 | | nlist.n_value = 0; |
| 1332 | | |
| 1333 | 1348 | const sect = macho_file.sections.items(.header)[output_section_index]; |
| 1334 | 1349 | const file_offset = sect.offset + atom.value; |
| 1335 | 1350 | 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 |
| 1560 | 1575 | const off = try self.strtab.insert(gpa, sym_name); |
| 1561 | 1576 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); |
| 1562 | 1577 | if (!lookup_gop.found_existing) { |
| 1563 | | const sym_index = try self.addSymbol(gpa); |
| 1578 | const sym_index = try self.newSymbol(gpa, off, .{}); |
| 1564 | 1579 | 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; |
| 1574 | 1581 | } |
| 1575 | 1582 | return lookup_gop.value_ptr.*; |
| 1576 | 1583 | } |
| ... | ... | @@ -1584,10 +1591,10 @@ pub fn getOrCreateMetadataForDecl( |
| 1584 | 1591 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 1585 | 1592 | if (!gop.found_existing) { |
| 1586 | 1593 | 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]; |
| 1588 | 1596 | const mod = macho_file.base.comp.module.?; |
| 1589 | 1597 | const decl = mod.declPtr(decl_index); |
| 1590 | | const sym = &self.symbols.items[sym_index]; |
| 1591 | 1598 | if (decl.getOwnedVariable(mod)) |variable| { |
| 1592 | 1599 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 1593 | 1600 | sym.flags.tlv = true; |
| ... | ... | @@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1627 | 1634 | }; |
| 1628 | 1635 | switch (metadata.state.*) { |
| 1629 | 1636 | .unused => { |
| 1630 | | const symbol_index = try self.createAtomForDecl(gpa, macho_file); |
| 1637 | const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file); |
| 1631 | 1638 | const sym = &self.symbols.items[symbol_index]; |
| 1632 | 1639 | sym.flags.needs_zig_got = true; |
| 1633 | 1640 | metadata.symbol_index.* = symbol_index; |
| ... | ... | @@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1643 | 1650 | } |
| 1644 | 1651 | |
| 1645 | 1652 | fn 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 | |
| 1658 | fn addAtomAssumeCapacity(self: *ZigObject) Atom.Index { |
| 1646 | 1659 | const atom_index: Atom.Index = @intCast(self.atoms.items.len); |
| 1647 | | const atom = try self.atoms.addOne(allocator); |
| 1660 | const atom = self.atoms.addOneAssumeCapacity(); |
| 1648 | 1661 | atom.* = .{ |
| 1649 | 1662 | .file = self.index, |
| 1650 | 1663 | .atom_index = atom_index, |
| 1651 | | .extra = try self.addAtomExtra(allocator, .{}), |
| 1664 | .extra = self.addAtomExtraAssumeCapacity(.{}), |
| 1652 | 1665 | }; |
| 1653 | 1666 | return atom_index; |
| 1654 | 1667 | } |