| ... | @@ -141,34 +141,64 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { | ... | @@ -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 | try self.symtab.ensureUnusedCapacity(allocator, 1); | 148 | try self.symtab.ensureUnusedCapacity(allocator, 1); |
| 146 | const index = @as(Symbol.Index, @intCast(self.symtab.addOneAssumeCapacity())); | 149 | try self.symbols.ensureUnusedCapacity(allocator, 1); |
| 147 | self.symtab.set(index, .{ | 150 | try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra)); |
| 148 | .nlist = MachO.null_sym, | 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 | .size = 0, | 167 | .size = 0, |
| 150 | .atom = 0, | 168 | .atom = 0, |
| 151 | }); | 169 | }); |
| | 170 | symbol.nlist_idx = nlist_idx; |
| | 171 | |
| | 172 | self.globals.appendAssumeCapacity(0); |
| | 173 | |
| 152 | return index; | 174 | return index; |
| 153 | } | 175 | } |
| 154 | | 176 | |
| 155 | pub fn createAtomForDecl(self: *ZigObject, allocator: Allocator, macho_file: *MachO) !Symbol.Index { | 177 | fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Atom.Index { |
| 156 | const atom_index = try self.addAtom(allocator); | 178 | try self.atoms.ensureUnusedCapacity(allocator, 1); |
| 157 | const symbol_index = try self.addSymbol(allocator); | 179 | try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra)); |
| 158 | const nlist_index = try self.addNlist(allocator); | 180 | try self.atoms_indexes.ensureUnusedCapacity(allocator, 1); |
| 159 | self.symtab.items(.atom)[nlist_index] = atom_index; | 181 | try self.relocs.ensureUnusedCapacity(allocator, 1); |
| 160 | try self.atoms_indexes.append(allocator, atom_index); | 182 | |
| 161 | const symbol = &self.symbols.items[symbol_index]; | 183 | const index = self.addAtomAssumeCapacity(); |
| 162 | symbol.atom_ref = .{ .index = atom_index, .file = self.index }; | 184 | self.atoms_indexes.appendAssumeCapacity(index); |
| 163 | symbol.nlist_idx = nlist_index; | 185 | const atom = self.getAtom(index).?; |
| 164 | symbol.extra = try self.addSymbolExtra(allocator, .{}); | 186 | atom.name = name; |
| | 187 | |
| 165 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); | 188 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); |
| 166 | const relocs = try self.relocs.addOne(allocator); | 189 | self.relocs.addOneAssumeCapacity().* = .{}; |
| 167 | relocs.* = .{}; | | |
| 168 | const atom = self.getAtom(atom_index).?; | | |
| 169 | atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); | 190 | atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); |
| 170 | try self.globals.append(allocator, 0); | 191 | |
| 171 | return symbol_index; | 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 | pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void { | 204 | pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void { |
| ... | @@ -1079,27 +1109,19 @@ fn createTlvInitializer( | ... | @@ -1079,27 +1109,19 @@ fn createTlvInitializer( |
| 1079 | const gpa = macho_file.base.comp.gpa; | 1109 | const gpa = macho_file.base.comp.gpa; |
| 1080 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); | 1110 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); |
| 1081 | defer gpa.free(sym_name); | 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 | const sym = &self.symbols.items[sym_index]; | 1115 | const sym = &self.symbols.items[sym_index]; |
| 1085 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 1116 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 1086 | const atom = sym.getAtom(macho_file).?; | 1117 | const atom = sym.getAtom(macho_file).?; |
| 1087 | | | |
| 1088 | sym.out_n_sect = sect_index; | 1118 | sym.out_n_sect = sect_index; |
| 1089 | atom.out_n_sect = sect_index; | 1119 | atom.out_n_sect = sect_index; |
| 1090 | | | |
| 1091 | sym.value = 0; | | |
| 1092 | sym.name = try self.strtab.insert(gpa, sym_name); | | |
| 1093 | atom.flags.alive = true; | 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 | atom.alignment = alignment; | 1121 | atom.alignment = alignment; |
| 1102 | atom.size = code.len; | 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 | const slice = macho_file.sections.slice(); | 1126 | const slice = macho_file.sections.slice(); |
| 1105 | const header = slice.items(.header)[sect_index]; | 1127 | const header = slice.items(.header)[sect_index]; |
| ... | @@ -1293,7 +1315,8 @@ fn lowerConst( | ... | @@ -1293,7 +1315,8 @@ fn lowerConst( |
| 1293 | var code_buffer = std.ArrayList(u8).init(gpa); | 1315 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1294 | defer code_buffer.deinit(); | 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 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ | 1321 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1299 | .none = {}, | 1322 | .none = {}, |
| ... | @@ -1306,19 +1329,14 @@ fn lowerConst( | ... | @@ -1306,19 +1329,14 @@ fn lowerConst( |
| 1306 | }; | 1329 | }; |
| 1307 | | 1330 | |
| 1308 | const sym = &self.symbols.items[sym_index]; | 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 | sym.out_n_sect = output_section_index; | 1332 | sym.out_n_sect = output_section_index; |
| 1312 | | 1333 | |
| 1313 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 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 | nlist.n_sect = output_section_index + 1; | 1335 | nlist.n_sect = output_section_index + 1; |
| 1317 | self.symtab.items(.size)[sym.nlist_idx] = code.len; | 1336 | self.symtab.items(.size)[sym.nlist_idx] = code.len; |
| 1318 | | 1337 | |
| 1319 | const atom = sym.getAtom(macho_file).?; | 1338 | const atom = sym.getAtom(macho_file).?; |
| 1320 | atom.flags.alive = true; | 1339 | atom.flags.alive = true; |
| 1321 | atom.name = name_str_index; | | |
| 1322 | atom.alignment = required_alignment; | 1340 | atom.alignment = required_alignment; |
| 1323 | atom.size = code.len; | 1341 | atom.size = code.len; |
| 1324 | atom.out_n_sect = output_section_index; | 1342 | atom.out_n_sect = output_section_index; |
| ... | @@ -1327,9 +1345,6 @@ fn lowerConst( | ... | @@ -1327,9 +1345,6 @@ fn lowerConst( |
| 1327 | // TODO rename and re-audit this method | 1345 | // TODO rename and re-audit this method |
| 1328 | errdefer self.freeDeclMetadata(macho_file, sym_index); | 1346 | errdefer self.freeDeclMetadata(macho_file, sym_index); |
| 1329 | | 1347 | |
| 1330 | sym.value = 0; | | |
| 1331 | nlist.n_value = 0; | | |
| 1332 | | | |
| 1333 | const sect = macho_file.sections.items(.header)[output_section_index]; | 1348 | const sect = macho_file.sections.items(.header)[output_section_index]; |
| 1334 | const file_offset = sect.offset + atom.value; | 1349 | const file_offset = sect.offset + atom.value; |
| 1335 | try macho_file.base.file.?.pwriteAll(code, file_offset); | 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,17 +1575,9 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l |
| 1560 | const off = try self.strtab.insert(gpa, sym_name); | 1575 | const off = try self.strtab.insert(gpa, sym_name); |
| 1561 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); | 1576 | const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); |
| 1562 | if (!lookup_gop.found_existing) { | 1577 | if (!lookup_gop.found_existing) { |
| 1563 | const sym_index = try self.addSymbol(gpa); | 1578 | const sym_index = try self.newSymbol(gpa, off, .{}); |
| 1564 | const sym = &self.symbols.items[sym_index]; | 1579 | const sym = &self.symbols.items[sym_index]; |
| 1565 | const nlist_index = try self.addNlist(gpa); | 1580 | lookup_gop.value_ptr.* = sym.nlist_idx; |
| 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); | | |
| 1574 | } | 1581 | } |
| 1575 | return lookup_gop.value_ptr.*; | 1582 | return lookup_gop.value_ptr.*; |
| 1576 | } | 1583 | } |
| ... | @@ -1584,10 +1591,10 @@ pub fn getOrCreateMetadataForDecl( | ... | @@ -1584,10 +1591,10 @@ pub fn getOrCreateMetadataForDecl( |
| 1584 | const gop = try self.decls.getOrPut(gpa, decl_index); | 1591 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 1585 | if (!gop.found_existing) { | 1592 | if (!gop.found_existing) { |
| 1586 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; | 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 | const mod = macho_file.base.comp.module.?; | 1596 | const mod = macho_file.base.comp.module.?; |
| 1589 | const decl = mod.declPtr(decl_index); | 1597 | const decl = mod.declPtr(decl_index); |
| 1590 | const sym = &self.symbols.items[sym_index]; | | |
| 1591 | if (decl.getOwnedVariable(mod)) |variable| { | 1598 | if (decl.getOwnedVariable(mod)) |variable| { |
| 1592 | if (variable.is_threadlocal and any_non_single_threaded) { | 1599 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 1593 | sym.flags.tlv = true; | 1600 | sym.flags.tlv = true; |
| ... | @@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1627 | }; | 1634 | }; |
| 1628 | switch (metadata.state.*) { | 1635 | switch (metadata.state.*) { |
| 1629 | .unused => { | 1636 | .unused => { |
| 1630 | const symbol_index = try self.createAtomForDecl(gpa, macho_file); | 1637 | const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file); |
| 1631 | const sym = &self.symbols.items[symbol_index]; | 1638 | const sym = &self.symbols.items[symbol_index]; |
| 1632 | sym.flags.needs_zig_got = true; | 1639 | sym.flags.needs_zig_got = true; |
| 1633 | metadata.symbol_index.* = symbol_index; | 1640 | metadata.symbol_index.* = symbol_index; |
| ... | @@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1643 | } | 1650 | } |
| 1644 | | 1651 | |
| 1645 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { | 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 | const atom_index: Atom.Index = @intCast(self.atoms.items.len); | 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 | atom.* = .{ | 1661 | atom.* = .{ |
| 1649 | .file = self.index, | 1662 | .file = self.index, |
| 1650 | .atom_index = atom_index, | 1663 | .atom_index = atom_index, |
| 1651 | .extra = try self.addAtomExtra(allocator, .{}), | 1664 | .extra = self.addAtomExtraAssumeCapacity(.{}), |
| 1652 | }; | 1665 | }; |
| 1653 | return atom_index; | 1666 | return atom_index; |
| 1654 | } | 1667 | } |