| ... | @@ -6,9 +6,15 @@ index: File.Index, | ... | @@ -6,9 +6,15 @@ index: File.Index, |
| 6 | symtab: std.MultiArrayList(Nlist) = .{}, | 6 | symtab: std.MultiArrayList(Nlist) = .{}, |
| 7 | strtab: StringTable = .{}, | 7 | strtab: StringTable = .{}, |
| 8 | | 8 | |
| 9 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | 9 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 10 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | 10 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 11 | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, | 11 | globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{}, |
| | 12 | /// Maps string index (so name) into nlist index for the global symbol defined within this |
| | 13 | /// module. |
| | 14 | globals_lookup: std.AutoHashMapUnmanaged(u32, u32) = .{}, |
| | 15 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| | 16 | atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| | 17 | atoms_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 12 | | 18 | |
| 13 | /// Table of tracked LazySymbols. | 19 | /// Table of tracked LazySymbols. |
| 14 | lazy_syms: LazySymbolTable = .{}, | 20 | lazy_syms: LazySymbolTable = .{}, |
| ... | @@ -58,10 +64,13 @@ debug_info_header_dirty: bool = false, | ... | @@ -58,10 +64,13 @@ debug_info_header_dirty: bool = false, |
| 58 | debug_line_header_dirty: bool = false, | 64 | debug_line_header_dirty: bool = false, |
| 59 | | 65 | |
| 60 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { | 66 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { |
| | 67 | const tracy = trace(@src()); |
| | 68 | defer tracy.end(); |
| | 69 | |
| 61 | const comp = macho_file.base.comp; | 70 | const comp = macho_file.base.comp; |
| 62 | const gpa = comp.gpa; | 71 | const gpa = comp.gpa; |
| 63 | | 72 | |
| 64 | try self.atoms.append(gpa, 0); // null input section | 73 | try self.atoms.append(gpa, .{ .extra = try self.addAtomExtra(gpa, .{}) }); // null input section |
| 65 | try self.strtab.buffer.append(gpa, 0); | 74 | try self.strtab.buffer.append(gpa, 0); |
| 66 | | 75 | |
| 67 | switch (comp.config.debug_format) { | 76 | switch (comp.config.debug_format) { |
| ... | @@ -84,8 +93,12 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { | ... | @@ -84,8 +93,12 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 84 | self.symtab.deinit(allocator); | 93 | self.symtab.deinit(allocator); |
| 85 | self.strtab.deinit(allocator); | 94 | self.strtab.deinit(allocator); |
| 86 | self.symbols.deinit(allocator); | 95 | self.symbols.deinit(allocator); |
| 87 | self.atoms.deinit(allocator); | 96 | self.symbols_extra.deinit(allocator); |
| | 97 | self.globals.deinit(allocator); |
| 88 | self.globals_lookup.deinit(allocator); | 98 | self.globals_lookup.deinit(allocator); |
| | 99 | self.atoms.deinit(allocator); |
| | 100 | self.atoms_indexes.deinit(allocator); |
| | 101 | self.atoms_extra.deinit(allocator); |
| 89 | | 102 | |
| 90 | { | 103 | { |
| 91 | var it = self.decls.iterator(); | 104 | var it = self.decls.iterator(); |
| ... | @@ -139,32 +152,21 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { | ... | @@ -139,32 +152,21 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| 139 | return index; | 152 | return index; |
| 140 | } | 153 | } |
| 141 | | 154 | |
| 142 | pub fn addAtom(self: *ZigObject, macho_file: *MachO) !Symbol.Index { | 155 | pub fn createAtomForDecl(self: *ZigObject, allocator: Allocator, macho_file: *MachO) !Symbol.Index { |
| 143 | const gpa = macho_file.base.comp.gpa; | 156 | const atom_index = try self.addAtom(allocator); |
| 144 | const atom_index = try macho_file.addAtom(); | 157 | const symbol_index = try self.addSymbol(allocator); |
| 145 | const symbol_index = try macho_file.addSymbol(); | 158 | const nlist_index = try self.addNlist(allocator); |
| 146 | const nlist_index = try self.addNlist(gpa); | | |
| 147 | | | |
| 148 | try self.atoms.append(gpa, atom_index); | | |
| 149 | try self.symbols.append(gpa, symbol_index); | | |
| 150 | | | |
| 151 | const atom = macho_file.getAtom(atom_index).?; | | |
| 152 | atom.file = self.index; | | |
| 153 | atom.atom_index = atom_index; | | |
| 154 | | | |
| 155 | const symbol = macho_file.getSymbol(symbol_index); | | |
| 156 | symbol.file = self.index; | | |
| 157 | symbol.atom = atom_index; | | |
| 158 | | | |
| 159 | self.symtab.items(.atom)[nlist_index] = atom_index; | 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 }; |
| 160 | symbol.nlist_idx = nlist_index; | 163 | symbol.nlist_idx = nlist_index; |
| 161 | | 164 | symbol.extra = try self.addSymbolExtra(allocator, .{}); |
| 162 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); | 165 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); |
| 163 | const relocs = try self.relocs.addOne(gpa); | 166 | const relocs = try self.relocs.addOne(allocator); |
| 164 | relocs.* = .{}; | 167 | relocs.* = .{}; |
| 165 | try atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); | 168 | const atom = self.getAtom(atom_index).?; |
| 166 | atom.flags.relocs = true; | 169 | atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); |
| 167 | | | |
| 168 | return symbol_index; | 170 | return symbol_index; |
| 169 | } | 171 | } |
| 170 | | 172 | |
| ... | @@ -191,89 +193,51 @@ pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8 | ... | @@ -191,89 +193,51 @@ pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8 |
| 191 | } | 193 | } |
| 192 | | 194 | |
| 193 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) []const Relocation { | 195 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) []const Relocation { |
| 194 | if (!atom.flags.relocs) return &[0]Relocation{}; | 196 | const extra = atom.getExtra(macho_file); |
| 195 | const extra = atom.getExtra(macho_file).?; | | |
| 196 | const relocs = self.relocs.items[extra.rel_index]; | 197 | const relocs = self.relocs.items[extra.rel_index]; |
| 197 | return relocs.items[0..extra.rel_count]; | 198 | return relocs.items[0..extra.rel_count]; |
| 198 | } | 199 | } |
| 199 | | 200 | |
| 200 | pub fn freeAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) void { | 201 | pub fn freeAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) void { |
| 201 | if (atom.flags.relocs) { | 202 | const extra = atom.getExtra(macho_file); |
| 202 | const extra = atom.getExtra(macho_file).?; | 203 | self.relocs.items[extra.rel_index].clearRetainingCapacity(); |
| 203 | self.relocs.items[extra.rel_index].clearRetainingCapacity(); | | |
| 204 | } | | |
| 205 | } | 204 | } |
| 206 | | 205 | |
| 207 | pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void { | 206 | pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) !void { |
| 208 | const tracy = trace(@src()); | 207 | const tracy = trace(@src()); |
| 209 | defer tracy.end(); | 208 | defer tracy.end(); |
| 210 | | 209 | |
| 211 | for (self.symbols.items, 0..) |index, i| { | 210 | const gpa = macho_file.base.comp.gpa; |
| 212 | const nlist_idx = @as(Symbol.Index, @intCast(i)); | | |
| 213 | const nlist = self.symtab.items(.nlist)[nlist_idx]; | | |
| 214 | const atom_index = self.symtab.items(.atom)[nlist_idx]; | | |
| 215 | | 211 | |
| | 212 | for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| { |
| 216 | if (!nlist.ext()) continue; | 213 | if (!nlist.ext()) continue; |
| 217 | if (nlist.undf() and !nlist.tentative()) continue; | | |
| 218 | if (nlist.sect()) { | 214 | if (nlist.sect()) { |
| 219 | const atom = macho_file.getAtom(atom_index).?; | 215 | const atom = self.getAtom(atom_index).?; |
| 220 | if (!atom.flags.alive) continue; | 216 | if (!atom.flags.alive) continue; |
| 221 | } | 217 | } |
| 222 | | 218 | |
| 223 | const symbol = macho_file.getSymbol(index); | 219 | const gop = try macho_file.resolver.getOrPut(gpa, .{ |
| | 220 | .index = @intCast(i), |
| | 221 | .file = self.index, |
| | 222 | }, macho_file); |
| | 223 | if (!gop.found_existing) { |
| | 224 | gop.ref.* = .{ .index = 0, .file = 0 }; |
| | 225 | } |
| | 226 | global.* = gop.index; |
| | 227 | |
| | 228 | if (nlist.undf() and !nlist.tentative()) continue; |
| | 229 | if (gop.ref.getFile(macho_file) == null) { |
| | 230 | gop.ref.* = .{ .index = @intCast(i), .file = self.index }; |
| | 231 | continue; |
| | 232 | } |
| | 233 | |
| 224 | if (self.asFile().getSymbolRank(.{ | 234 | if (self.asFile().getSymbolRank(.{ |
| 225 | .archive = false, | 235 | .archive = false, |
| 226 | .weak = nlist.weakDef(), | 236 | .weak = nlist.weakDef(), |
| 227 | .tentative = nlist.tentative(), | 237 | .tentative = nlist.tentative(), |
| 228 | }) < symbol.getSymbolRank(macho_file)) { | 238 | }) < gop.ref.getSymbol(macho_file).?.getSymbolRank(macho_file)) { |
| 229 | const value = if (nlist.sect()) blk: { | 239 | gop.ref.* = .{ .index = @intCast(i), .file = self.index }; |
| 230 | const atom = macho_file.getAtom(atom_index).?; | | |
| 231 | break :blk nlist.n_value - atom.getInputAddress(macho_file); | | |
| 232 | } else nlist.n_value; | | |
| 233 | const out_n_sect = if (nlist.sect()) macho_file.getAtom(atom_index).?.out_n_sect else 0; | | |
| 234 | symbol.value = value; | | |
| 235 | symbol.atom = atom_index; | | |
| 236 | symbol.out_n_sect = out_n_sect; | | |
| 237 | symbol.nlist_idx = nlist_idx; | | |
| 238 | symbol.file = self.index; | | |
| 239 | symbol.flags.weak = nlist.weakDef(); | | |
| 240 | symbol.flags.abs = nlist.abs(); | | |
| 241 | symbol.flags.tentative = nlist.tentative(); | | |
| 242 | symbol.flags.weak_ref = false; | | |
| 243 | symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0; | | |
| 244 | symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip(); | | |
| 245 | // TODO: symbol.flags.interposable = macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext(); | | |
| 246 | symbol.flags.interposable = false; | | |
| 247 | | | |
| 248 | if (nlist.sect() and | | |
| 249 | macho_file.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES) | | |
| 250 | { | | |
| 251 | symbol.flags.tlv = true; | | |
| 252 | } | | |
| 253 | } | 240 | } |
| 254 | | | |
| 255 | // Regardless of who the winner is, we still merge symbol visibility here. | | |
| 256 | if (nlist.pext() or (nlist.weakDef() and nlist.weakRef())) { | | |
| 257 | if (symbol.visibility != .global) { | | |
| 258 | symbol.visibility = .hidden; | | |
| 259 | } | | |
| 260 | } else { | | |
| 261 | symbol.visibility = .global; | | |
| 262 | } | | |
| 263 | } | | |
| 264 | } | | |
| 265 | | | |
| 266 | pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void { | | |
| 267 | for (self.symbols.items, 0..) |sym_index, nlist_idx| { | | |
| 268 | if (!self.symtab.items(.nlist)[nlist_idx].ext()) continue; | | |
| 269 | const sym = macho_file.getSymbol(sym_index); | | |
| 270 | const name = sym.name; | | |
| 271 | const global = sym.flags.global; | | |
| 272 | const weak_ref = sym.flags.weak_ref; | | |
| 273 | sym.* = .{}; | | |
| 274 | sym.name = name; | | |
| 275 | sym.flags.global = global; | | |
| 276 | sym.flags.weak_ref = weak_ref; | | |
| 277 | } | 241 | } |
| 278 | } | 242 | } |
| 279 | | 243 | |
| ... | @@ -281,12 +245,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { | ... | @@ -281,12 +245,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { |
| 281 | const tracy = trace(@src()); | 245 | const tracy = trace(@src()); |
| 282 | defer tracy.end(); | 246 | defer tracy.end(); |
| 283 | | 247 | |
| 284 | for (self.symbols.items, 0..) |index, nlist_idx| { | 248 | for (0..self.symbols.items.len) |i| { |
| 285 | const nlist = self.symtab.items(.nlist)[nlist_idx]; | 249 | const nlist = self.symtab.items(.nlist)[i]; |
| 286 | if (!nlist.ext()) continue; | 250 | if (!nlist.ext()) continue; |
| 287 | | 251 | |
| 288 | const sym = macho_file.getSymbol(index); | 252 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 289 | const file = sym.getFile(macho_file) orelse continue; | 253 | const file = ref.getFile(macho_file) orelse continue; |
| | 254 | const sym = ref.getSymbol(macho_file).?; |
| 290 | const should_keep = nlist.undf() or (nlist.tentative() and !sym.flags.tentative); | 255 | const should_keep = nlist.undf() or (nlist.tentative() and !sym.flags.tentative); |
| 291 | if (should_keep and file == .object and !file.object.alive) { | 256 | if (should_keep and file == .object and !file.object.alive) { |
| 292 | file.object.alive = true; | 257 | file.object.alive = true; |
| ... | @@ -295,24 +260,41 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { | ... | @@ -295,24 +260,41 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void { |
| 295 | } | 260 | } |
| 296 | } | 261 | } |
| 297 | | 262 | |
| 298 | pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void { | 263 | pub fn mergeSymbolVisibility(self: *ZigObject, macho_file: *MachO) void { |
| 299 | for (self.symbols.items, 0..) |index, nlist_idx| { | 264 | const tracy = trace(@src()); |
| 300 | const sym = macho_file.getSymbol(index); | 265 | defer tracy.end(); |
| 301 | if (sym.visibility != .global) continue; | 266 | |
| 302 | const file = sym.getFile(macho_file) orelse continue; | 267 | for (self.symbols.items, 0..) |sym, i| { |
| 303 | if (file.getIndex() == self.index) continue; | 268 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 304 | | 269 | const global = ref.getSymbol(macho_file) orelse continue; |
| 305 | const nlist = self.symtab.items(.nlist)[nlist_idx]; | 270 | if (global.visibility != .global) { |
| 306 | if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) { | 271 | global.visibility = sym.visibility; |
| 307 | const gop = try dupes.getOrPut(index); | 272 | } |
| 308 | if (!gop.found_existing) { | 273 | if (sym.flags.weak_ref) { |
| 309 | gop.value_ptr.* = .{}; | 274 | global.flags.weak_ref = true; |
| 310 | } | | |
| 311 | try gop.value_ptr.append(macho_file.base.comp.gpa, self.index); | | |
| 312 | } | 275 | } |
| 313 | } | 276 | } |
| 314 | } | 277 | } |
| 315 | | 278 | |
| | 279 | // TODO |
| | 280 | // pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void { |
| | 281 | // for (self.symbols.items, 0..) |index, nlist_idx| { |
| | 282 | // const sym = macho_file.getSymbol(index); |
| | 283 | // if (sym.visibility != .global) continue; |
| | 284 | // const file = sym.getFile(macho_file) orelse continue; |
| | 285 | // if (file.getIndex() == self.index) continue; |
| | 286 | |
| | 287 | // const nlist = self.symtab.items(.nlist)[nlist_idx]; |
| | 288 | // if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) { |
| | 289 | // const gop = try dupes.getOrPut(index); |
| | 290 | // if (!gop.found_existing) { |
| | 291 | // gop.value_ptr.* = .{}; |
| | 292 | // } |
| | 293 | // try gop.value_ptr.append(macho_file.base.comp.gpa, self.index); |
| | 294 | // } |
| | 295 | // } |
| | 296 | // } |
| | 297 | |
| 316 | pub fn resolveLiterals(self: *ZigObject, lp: *MachO.LiteralPool, macho_file: *MachO) !void { | 298 | pub fn resolveLiterals(self: *ZigObject, lp: *MachO.LiteralPool, macho_file: *MachO) !void { |
| 317 | _ = self; | 299 | _ = self; |
| 318 | _ = lp; | 300 | _ = lp; |
| ... | @@ -362,8 +344,8 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi | ... | @@ -362,8 +344,8 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi |
| 362 | } | 344 | } |
| 363 | | 345 | |
| 364 | pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { | 346 | pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { |
| 365 | for (self.atoms.items) |atom_index| { | 347 | for (self.getAtoms()) |atom_index| { |
| 366 | const atom = macho_file.getAtom(atom_index) orelse continue; | 348 | const atom = self.getAtom(atom_index) orelse continue; |
| 367 | if (!atom.flags.alive) continue; | 349 | if (!atom.flags.alive) continue; |
| 368 | const sect = atom.getInputSection(macho_file); | 350 | const sect = atom.getInputSection(macho_file); |
| 369 | if (sect.isZerofill()) continue; | 351 | if (sect.isZerofill()) continue; |
| ... | @@ -371,46 +353,49 @@ pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { | ... | @@ -371,46 +353,49 @@ pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { |
| 371 | } | 353 | } |
| 372 | } | 354 | } |
| 373 | | 355 | |
| 374 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { | 356 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { |
| 375 | const tracy = trace(@src()); | 357 | const tracy = trace(@src()); |
| 376 | defer tracy.end(); | 358 | defer tracy.end(); |
| 377 | | 359 | |
| 378 | for (self.symbols.items) |sym_index| { | 360 | for (self.symbols.items, 0..) |*sym, i| { |
| 379 | const sym = macho_file.getSymbol(sym_index); | 361 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 380 | const file = sym.getFile(macho_file) orelse continue; | 362 | const file = ref.getFile(macho_file) orelse continue; |
| 381 | if (file.getIndex() != self.index) continue; | 363 | if (file.getIndex() != self.index) continue; |
| 382 | if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue; | 364 | if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue; |
| 383 | sym.flags.output_symtab = true; | 365 | sym.flags.output_symtab = true; |
| 384 | if (sym.isLocal()) { | 366 | if (sym.isLocal()) { |
| 385 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file); | 367 | sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file); |
| 386 | self.output_symtab_ctx.nlocals += 1; | 368 | self.output_symtab_ctx.nlocals += 1; |
| 387 | } else if (sym.flags.@"export") { | 369 | } else if (sym.flags.@"export") { |
| 388 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file); | 370 | sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file); |
| 389 | self.output_symtab_ctx.nexports += 1; | 371 | self.output_symtab_ctx.nexports += 1; |
| 390 | } else { | 372 | } else { |
| 391 | assert(sym.flags.import); | 373 | assert(sym.flags.import); |
| 392 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file); | 374 | sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file); |
| 393 | self.output_symtab_ctx.nimports += 1; | 375 | self.output_symtab_ctx.nimports += 1; |
| 394 | } | 376 | } |
| 395 | self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1)); | 377 | self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1)); |
| 396 | } | 378 | } |
| 397 | } | 379 | } |
| 398 | | 380 | |
| 399 | pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void { | 381 | pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { |
| 400 | const tracy = trace(@src()); | 382 | const tracy = trace(@src()); |
| 401 | defer tracy.end(); | 383 | defer tracy.end(); |
| 402 | | 384 | |
| 403 | for (self.symbols.items) |sym_index| { | 385 | var n_strx = self.output_symtab_ctx.stroff; |
| 404 | const sym = macho_file.getSymbol(sym_index); | 386 | for (self.symbols.items, 0..) |sym, i| { |
| 405 | const file = sym.getFile(macho_file) orelse continue; | 387 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| | 388 | const file = ref.getFile(macho_file) orelse continue; |
| 406 | if (file.getIndex() != self.index) continue; | 389 | if (file.getIndex() != self.index) continue; |
| 407 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; | 390 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 408 | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); | 391 | const out_sym = &macho_file.symtab.items[idx]; |
| 409 | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | | |
| 410 | ctx.strtab.appendAssumeCapacity(0); | | |
| 411 | const out_sym = &ctx.symtab.items[idx]; | | |
| 412 | out_sym.n_strx = n_strx; | 392 | out_sym.n_strx = n_strx; |
| 413 | sym.setOutputSym(macho_file, out_sym); | 393 | sym.setOutputSym(macho_file, out_sym); |
| | 394 | const name = sym.getName(macho_file); |
| | 395 | @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name); |
| | 396 | n_strx += @intCast(name.len); |
| | 397 | macho_file.strtab.items[n_strx] = 0; |
| | 398 | n_strx += 1; |
| 414 | } | 399 | } |
| 415 | } | 400 | } |
| 416 | | 401 | |
| ... | @@ -523,9 +508,9 @@ pub fn getDeclVAddr( | ... | @@ -523,9 +508,9 @@ pub fn getDeclVAddr( |
| 523 | reloc_info: link.File.RelocInfo, | 508 | reloc_info: link.File.RelocInfo, |
| 524 | ) !u64 { | 509 | ) !u64 { |
| 525 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); | 510 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 526 | const sym = macho_file.getSymbol(sym_index); | 511 | const sym = self.symbols.items[sym_index]; |
| 527 | const vaddr = sym.getAddress(.{}, macho_file); | 512 | const vaddr = sym.getAddress(.{}, macho_file); |
| 528 | const parent_atom = macho_file.getSymbol(reloc_info.parent_atom_index).getAtom(macho_file).?; | 513 | const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?; |
| 529 | try parent_atom.addReloc(macho_file, .{ | 514 | try parent_atom.addReloc(macho_file, .{ |
| 530 | .tag = .@"extern", | 515 | .tag = .@"extern", |
| 531 | .offset = @intCast(reloc_info.offset), | 516 | .offset = @intCast(reloc_info.offset), |
| ... | @@ -549,9 +534,9 @@ pub fn getAnonDeclVAddr( | ... | @@ -549,9 +534,9 @@ pub fn getAnonDeclVAddr( |
| 549 | reloc_info: link.File.RelocInfo, | 534 | reloc_info: link.File.RelocInfo, |
| 550 | ) !u64 { | 535 | ) !u64 { |
| 551 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; | 536 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; |
| 552 | const sym = macho_file.getSymbol(sym_index); | 537 | const sym = self.symbols.items[sym_index]; |
| 553 | const vaddr = sym.getAddress(.{}, macho_file); | 538 | const vaddr = sym.getAddress(.{}, macho_file); |
| 554 | const parent_atom = macho_file.getSymbol(reloc_info.parent_atom_index).getAtom(macho_file).?; | 539 | const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?; |
| 555 | try parent_atom.addReloc(macho_file, .{ | 540 | try parent_atom.addReloc(macho_file, .{ |
| 556 | .tag = .@"extern", | 541 | .tag = .@"extern", |
| 557 | .offset = @intCast(reloc_info.offset), | 542 | .offset = @intCast(reloc_info.offset), |
| ... | @@ -584,7 +569,7 @@ pub fn lowerAnonDecl( | ... | @@ -584,7 +569,7 @@ pub fn lowerAnonDecl( |
| 584 | else => explicit_alignment, | 569 | else => explicit_alignment, |
| 585 | }; | 570 | }; |
| 586 | if (self.anon_decls.get(decl_val)) |metadata| { | 571 | if (self.anon_decls.get(decl_val)) |metadata| { |
| 587 | const existing_alignment = macho_file.getSymbol(metadata.symbol_index).getAtom(macho_file).?.alignment; | 572 | const existing_alignment = self.symbols.items[metadata.symbol_index].getAtom(macho_file).?.alignment; |
| 588 | if (decl_alignment.order(existing_alignment).compare(.lte)) | 573 | if (decl_alignment.order(existing_alignment).compare(.lte)) |
| 589 | return .ok; | 574 | return .ok; |
| 590 | } | 575 | } |
| ... | @@ -628,13 +613,10 @@ fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPoo | ... | @@ -628,13 +613,10 @@ fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPoo |
| 628 | } | 613 | } |
| 629 | | 614 | |
| 630 | fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { | 615 | fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { |
| 631 | _ = self; | 616 | const sym = self.symbols.items[sym_index]; |
| 632 | const gpa = macho_file.base.comp.gpa; | | |
| 633 | const sym = macho_file.getSymbol(sym_index); | | |
| 634 | sym.getAtom(macho_file).?.free(macho_file); | 617 | sym.getAtom(macho_file).?.free(macho_file); |
| 635 | log.debug("adding %{d} to local symbols free list", .{sym_index}); | 618 | log.debug("adding %{d} to local symbols free list", .{sym_index}); |
| 636 | macho_file.symbols_free_list.append(gpa, sym_index) catch {}; | 619 | // TODO redo this |
| 637 | macho_file.symbols.items[sym_index] = .{}; | | |
| 638 | // TODO free GOT entry here | 620 | // TODO free GOT entry here |
| 639 | } | 621 | } |
| 640 | | 622 | |
| ... | @@ -675,7 +657,7 @@ pub fn updateFunc( | ... | @@ -675,7 +657,7 @@ pub fn updateFunc( |
| 675 | | 657 | |
| 676 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); | 658 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 677 | self.freeUnnamedConsts(macho_file, decl_index); | 659 | self.freeUnnamedConsts(macho_file, decl_index); |
| 678 | macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file); | 660 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); |
| 679 | | 661 | |
| 680 | var code_buffer = std.ArrayList(u8).init(gpa); | 662 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 681 | defer code_buffer.deinit(); | 663 | defer code_buffer.deinit(); |
| ... | @@ -708,7 +690,7 @@ pub fn updateFunc( | ... | @@ -708,7 +690,7 @@ pub fn updateFunc( |
| 708 | try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code); | 690 | try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code); |
| 709 | | 691 | |
| 710 | if (decl_state) |*ds| { | 692 | if (decl_state) |*ds| { |
| 711 | const sym = macho_file.getSymbol(sym_index); | 693 | const sym = self.symbols.items[sym_index]; |
| 712 | try self.dwarf.?.commitDeclState( | 694 | try self.dwarf.?.commitDeclState( |
| 713 | pt, | 695 | pt, |
| 714 | decl_index, | 696 | decl_index, |
| ... | @@ -743,13 +725,13 @@ pub fn updateDecl( | ... | @@ -743,13 +725,13 @@ pub fn updateDecl( |
| 743 | const name = decl.name.toSlice(&mod.intern_pool); | 725 | const name = decl.name.toSlice(&mod.intern_pool); |
| 744 | const lib_name = variable.lib_name.toSlice(&mod.intern_pool); | 726 | const lib_name = variable.lib_name.toSlice(&mod.intern_pool); |
| 745 | const index = try self.getGlobalSymbol(macho_file, name, lib_name); | 727 | const index = try self.getGlobalSymbol(macho_file, name, lib_name); |
| 746 | const actual_index = self.symbols.items[index]; | 728 | const sym = &self.symbols.items[index]; |
| 747 | macho_file.getSymbol(actual_index).flags.needs_got = true; | 729 | sym.flags.needs_got = true; |
| 748 | return; | 730 | return; |
| 749 | } | 731 | } |
| 750 | | 732 | |
| 751 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); | 733 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 752 | macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file); | 734 | self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file); |
| 753 | | 735 | |
| 754 | const gpa = macho_file.base.comp.gpa; | 736 | const gpa = macho_file.base.comp.gpa; |
| 755 | var code_buffer = std.ArrayList(u8).init(gpa); | 737 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | @@ -784,7 +766,7 @@ pub fn updateDecl( | ... | @@ -784,7 +766,7 @@ pub fn updateDecl( |
| 784 | } | 766 | } |
| 785 | | 767 | |
| 786 | if (decl_state) |*ds| { | 768 | if (decl_state) |*ds| { |
| 787 | const sym = macho_file.getSymbol(sym_index); | 769 | const sym = self.symbols.items[sym_index]; |
| 788 | try self.dwarf.?.commitDeclState( | 770 | try self.dwarf.?.commitDeclState( |
| 789 | pt, | 771 | pt, |
| 790 | decl_index, | 772 | decl_index, |
| ... | @@ -816,7 +798,7 @@ fn updateDeclCode( | ... | @@ -816,7 +798,7 @@ fn updateDeclCode( |
| 816 | const required_alignment = decl.getAlignment(pt); | 798 | const required_alignment = decl.getAlignment(pt); |
| 817 | | 799 | |
| 818 | const sect = &macho_file.sections.items(.header)[sect_index]; | 800 | const sect = &macho_file.sections.items(.header)[sect_index]; |
| 819 | const sym = macho_file.getSymbol(sym_index); | 801 | const sym = &self.symbols.items[sym_index]; |
| 820 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 802 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 821 | const atom = sym.getAtom(macho_file).?; | 803 | const atom = sym.getAtom(macho_file).?; |
| 822 | | 804 | |
| ... | @@ -850,13 +832,13 @@ fn updateDeclCode( | ... | @@ -850,13 +832,13 @@ fn updateDeclCode( |
| 850 | if (!macho_file.base.isRelocatable()) { | 832 | if (!macho_file.base.isRelocatable()) { |
| 851 | log.debug(" (updating offset table entry)", .{}); | 833 | log.debug(" (updating offset table entry)", .{}); |
| 852 | assert(sym.flags.has_zig_got); | 834 | assert(sym.flags.has_zig_got); |
| 853 | const extra = sym.getExtra(macho_file).?; | 835 | const extra = sym.getExtra(macho_file); |
| 854 | try macho_file.zig_got.writeOne(macho_file, extra.zig_got); | 836 | try macho_file.zig_got.writeOne(macho_file, extra.zig_got); |
| 855 | } | 837 | } |
| 856 | } | 838 | } |
| 857 | } else if (code.len < old_size) { | 839 | } else if (code.len < old_size) { |
| 858 | atom.shrink(macho_file); | 840 | atom.shrink(macho_file); |
| 859 | } else if (macho_file.getAtom(atom.next_index) == null) { | 841 | } else if (self.getAtom(atom.next_index) == null) { |
| 860 | const needed_size = atom.value + code.len; | 842 | const needed_size = atom.value + code.len; |
| 861 | sect.size = needed_size; | 843 | sect.size = needed_size; |
| 862 | } | 844 | } |
| ... | @@ -922,8 +904,8 @@ fn createTlvInitializer( | ... | @@ -922,8 +904,8 @@ fn createTlvInitializer( |
| 922 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); | 904 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); |
| 923 | defer gpa.free(sym_name); | 905 | defer gpa.free(sym_name); |
| 924 | | 906 | |
| 925 | const sym_index = try self.addAtom(macho_file); | 907 | const sym_index = try self.createAtomForDecl(gpa, macho_file); |
| 926 | const sym = macho_file.getSymbol(sym_index); | 908 | const sym = &self.symbols.items[sym_index]; |
| 927 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 909 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 928 | const atom = sym.getAtom(macho_file).?; | 910 | const atom = sym.getAtom(macho_file).?; |
| 929 | | 911 | |
| ... | @@ -945,7 +927,6 @@ fn createTlvInitializer( | ... | @@ -945,7 +927,6 @@ fn createTlvInitializer( |
| 945 | | 927 | |
| 946 | const slice = macho_file.sections.slice(); | 928 | const slice = macho_file.sections.slice(); |
| 947 | const header = slice.items(.header)[sect_index]; | 929 | const header = slice.items(.header)[sect_index]; |
| 948 | const atoms = &slice.items(.atoms)[sect_index]; | | |
| 949 | | 930 | |
| 950 | const gop = try self.tlv_initializers.getOrPut(gpa, atom.atom_index); | 931 | const gop = try self.tlv_initializers.getOrPut(gpa, atom.atom_index); |
| 951 | assert(!gop.found_existing); // TODO incremental updates | 932 | assert(!gop.found_existing); // TODO incremental updates |
| ... | @@ -956,8 +937,6 @@ fn createTlvInitializer( | ... | @@ -956,8 +937,6 @@ fn createTlvInitializer( |
| 956 | gop.value_ptr.data = try gpa.dupe(u8, code); | 937 | gop.value_ptr.data = try gpa.dupe(u8, code); |
| 957 | } | 938 | } |
| 958 | | 939 | |
| 959 | try atoms.append(gpa, atom.atom_index); | | |
| 960 | | | |
| 961 | return sym_index; | 940 | return sym_index; |
| 962 | } | 941 | } |
| 963 | | 942 | |
| ... | @@ -970,7 +949,7 @@ fn createTlvDescriptor( | ... | @@ -970,7 +949,7 @@ fn createTlvDescriptor( |
| 970 | ) !void { | 949 | ) !void { |
| 971 | const gpa = macho_file.base.comp.gpa; | 950 | const gpa = macho_file.base.comp.gpa; |
| 972 | | 951 | |
| 973 | const sym = macho_file.getSymbol(sym_index); | 952 | const sym = &self.symbols.items[sym_index]; |
| 974 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; | 953 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 975 | const atom = sym.getAtom(macho_file).?; | 954 | const atom = sym.getAtom(macho_file).?; |
| 976 | const alignment = Atom.Alignment.fromNonzeroByteUnits(@alignOf(u64)); | 955 | const alignment = Atom.Alignment.fromNonzeroByteUnits(@alignOf(u64)); |
| ... | @@ -1000,7 +979,7 @@ fn createTlvDescriptor( | ... | @@ -1000,7 +979,7 @@ fn createTlvDescriptor( |
| 1000 | try atom.addReloc(macho_file, .{ | 979 | try atom.addReloc(macho_file, .{ |
| 1001 | .tag = .@"extern", | 980 | .tag = .@"extern", |
| 1002 | .offset = 0, | 981 | .offset = 0, |
| 1003 | .target = self.symbols.items[tlv_bootstrap_index], | 982 | .target = tlv_bootstrap_index, |
| 1004 | .addend = 0, | 983 | .addend = 0, |
| 1005 | .type = .unsigned, | 984 | .type = .unsigned, |
| 1006 | .meta = .{ | 985 | .meta = .{ |
| ... | @@ -1020,11 +999,14 @@ fn createTlvDescriptor( | ... | @@ -1020,11 +999,14 @@ fn createTlvDescriptor( |
| 1020 | .pcrel = false, | 999 | .pcrel = false, |
| 1021 | .has_subtractor = false, | 1000 | .has_subtractor = false, |
| 1022 | .length = 3, | 1001 | .length = 3, |
| 1023 | .symbolnum = @intCast(macho_file.getSymbol(init_sym_index).nlist_idx), | 1002 | .symbolnum = @intCast(init_sym_index), |
| 1024 | }, | 1003 | }, |
| 1025 | }); | 1004 | }); |
| 1026 | | 1005 | |
| 1027 | try macho_file.sections.items(.atoms)[sect_index].append(gpa, atom.atom_index); | 1006 | try macho_file.sections.items(.atoms)[sect_index].append(gpa, .{ |
| | 1007 | .index = atom.atom_index, |
| | 1008 | .file = self.index, |
| | 1009 | }); |
| 1028 | } | 1010 | } |
| 1029 | | 1011 | |
| 1030 | fn getDeclOutputSection( | 1012 | fn getDeclOutputSection( |
| ... | @@ -1115,7 +1097,7 @@ pub fn lowerUnnamedConst( | ... | @@ -1115,7 +1097,7 @@ pub fn lowerUnnamedConst( |
| 1115 | return error.CodegenFail; | 1097 | return error.CodegenFail; |
| 1116 | }, | 1098 | }, |
| 1117 | }; | 1099 | }; |
| 1118 | const sym = macho_file.getSymbol(sym_index); | 1100 | const sym = self.symbols.items[sym_index]; |
| 1119 | try unnamed_consts.append(gpa, sym.atom); | 1101 | try unnamed_consts.append(gpa, sym.atom); |
| 1120 | return sym_index; | 1102 | return sym_index; |
| 1121 | } | 1103 | } |
| ... | @@ -1140,7 +1122,7 @@ fn lowerConst( | ... | @@ -1140,7 +1122,7 @@ fn lowerConst( |
| 1140 | var code_buffer = std.ArrayList(u8).init(gpa); | 1122 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1141 | defer code_buffer.deinit(); | 1123 | defer code_buffer.deinit(); |
| 1142 | | 1124 | |
| 1143 | const sym_index = try self.addAtom(macho_file); | 1125 | const sym_index = try self.createAtomForDecl(gpa, macho_file); |
| 1144 | | 1126 | |
| 1145 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ | 1127 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1146 | .none = {}, | 1128 | .none = {}, |
| ... | @@ -1152,7 +1134,7 @@ fn lowerConst( | ... | @@ -1152,7 +1134,7 @@ fn lowerConst( |
| 1152 | .fail => |em| return .{ .fail = em }, | 1134 | .fail => |em| return .{ .fail = em }, |
| 1153 | }; | 1135 | }; |
| 1154 | | 1136 | |
| 1155 | const sym = macho_file.getSymbol(sym_index); | 1137 | const sym = &self.symbols.items[sym_index]; |
| 1156 | const name_str_index = try self.strtab.insert(gpa, name); | 1138 | const name_str_index = try self.strtab.insert(gpa, name); |
| 1157 | sym.name = name_str_index; | 1139 | sym.name = name_str_index; |
| 1158 | sym.out_n_sect = output_section_index; | 1140 | sym.out_n_sect = output_section_index; |
| ... | @@ -1218,7 +1200,7 @@ pub fn updateExports( | ... | @@ -1218,7 +1200,7 @@ pub fn updateExports( |
| 1218 | }, | 1200 | }, |
| 1219 | }; | 1201 | }; |
| 1220 | const sym_index = metadata.symbol_index; | 1202 | const sym_index = metadata.symbol_index; |
| 1221 | const nlist_idx = macho_file.getSymbol(sym_index).nlist_idx; | 1203 | const nlist_idx = self.symbols.items[sym_index].nlist_idx; |
| 1222 | const nlist = self.symtab.items(.nlist)[nlist_idx]; | 1204 | const nlist = self.symtab.items(.nlist)[nlist_idx]; |
| 1223 | | 1205 | |
| 1224 | for (export_indices) |export_idx| { | 1206 | for (export_indices) |export_idx| { |
| ... | @@ -1322,7 +1304,7 @@ fn updateLazySymbol( | ... | @@ -1322,7 +1304,7 @@ fn updateLazySymbol( |
| 1322 | .code => macho_file.zig_text_sect_index.?, | 1304 | .code => macho_file.zig_text_sect_index.?, |
| 1323 | .const_data => macho_file.zig_const_sect_index.?, | 1305 | .const_data => macho_file.zig_const_sect_index.?, |
| 1324 | }; | 1306 | }; |
| 1325 | const sym = macho_file.getSymbol(symbol_index); | 1307 | const sym = &self.symbols.items[symbol_index]; |
| 1326 | sym.name = name_str_index; | 1308 | sym.name = name_str_index; |
| 1327 | sym.out_n_sect = output_section_index; | 1309 | sym.out_n_sect = output_section_index; |
| 1328 | | 1310 | |
| ... | @@ -1382,12 +1364,12 @@ pub fn deleteExport( | ... | @@ -1382,12 +1364,12 @@ pub fn deleteExport( |
| 1382 | const nlist = &self.symtab.items(.nlist)[nlist_index.*]; | 1364 | const nlist = &self.symtab.items(.nlist)[nlist_index.*]; |
| 1383 | self.symtab.items(.size)[nlist_index.*] = 0; | 1365 | self.symtab.items(.size)[nlist_index.*] = 0; |
| 1384 | _ = self.globals_lookup.remove(nlist.n_strx); | 1366 | _ = self.globals_lookup.remove(nlist.n_strx); |
| 1385 | const sym_index = macho_file.globals.get(nlist.n_strx).?; | 1367 | // TODO actually remove the export |
| 1386 | const sym = macho_file.getSymbol(sym_index); | 1368 | // const sym_index = macho_file.globals.get(nlist.n_strx).?; |
| 1387 | if (sym.file == self.index) { | 1369 | // const sym = &self.symbols.items[sym_index]; |
| 1388 | _ = macho_file.globals.swapRemove(nlist.n_strx); | 1370 | // if (sym.file == self.index) { |
| 1389 | sym.* = .{}; | 1371 | // sym.* = .{}; |
| 1390 | } | 1372 | // } |
| 1391 | nlist.* = MachO.null_sym; | 1373 | nlist.* = MachO.null_sym; |
| 1392 | } | 1374 | } |
| 1393 | | 1375 | |
| ... | @@ -1404,9 +1386,11 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l | ... | @@ -1404,9 +1386,11 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l |
| 1404 | nlist.n_strx = off; | 1386 | nlist.n_strx = off; |
| 1405 | nlist.n_type = macho.N_EXT; | 1387 | nlist.n_type = macho.N_EXT; |
| 1406 | lookup_gop.value_ptr.* = nlist_index; | 1388 | lookup_gop.value_ptr.* = nlist_index; |
| 1407 | const global_name_off = try macho_file.strings.insert(gpa, sym_name); | 1389 | _ = try macho_file.resolver.getOrPut(gpa, .{ |
| 1408 | const gop = try macho_file.getOrCreateGlobal(global_name_off); | 1390 | .index = nlist_index, |
| 1409 | try self.symbols.append(gpa, gop.index); | 1391 | .file = self.index, |
| | 1392 | }, macho_file); |
| | 1393 | try self.globals.append(gpa, nlist_index); |
| 1410 | } | 1394 | } |
| 1411 | return lookup_gop.value_ptr.*; | 1395 | return lookup_gop.value_ptr.*; |
| 1412 | } | 1396 | } |
| ... | @@ -1420,10 +1404,10 @@ pub fn getOrCreateMetadataForDecl( | ... | @@ -1420,10 +1404,10 @@ pub fn getOrCreateMetadataForDecl( |
| 1420 | const gop = try self.decls.getOrPut(gpa, decl_index); | 1404 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 1421 | if (!gop.found_existing) { | 1405 | if (!gop.found_existing) { |
| 1422 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; | 1406 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; |
| 1423 | const sym_index = try self.addAtom(macho_file); | 1407 | const sym_index = try self.createAtomForDecl(gpa, macho_file); |
| 1424 | const mod = macho_file.base.comp.module.?; | 1408 | const mod = macho_file.base.comp.module.?; |
| 1425 | const decl = mod.declPtr(decl_index); | 1409 | const decl = mod.declPtr(decl_index); |
| 1426 | const sym = macho_file.getSymbol(sym_index); | 1410 | const sym = &self.symbols.items[sym_index]; |
| 1427 | if (decl.getOwnedVariable(mod)) |variable| { | 1411 | if (decl.getOwnedVariable(mod)) |variable| { |
| 1428 | if (variable.is_threadlocal and any_non_single_threaded) { | 1412 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 1429 | sym.flags.tlv = true; | 1413 | sym.flags.tlv = true; |
| ... | @@ -1463,8 +1447,8 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -1463,8 +1447,8 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1463 | }; | 1447 | }; |
| 1464 | switch (metadata.state.*) { | 1448 | switch (metadata.state.*) { |
| 1465 | .unused => { | 1449 | .unused => { |
| 1466 | const symbol_index = try self.addAtom(macho_file); | 1450 | const symbol_index = try self.createAtomForDecl(gpa, macho_file); |
| 1467 | const sym = macho_file.getSymbol(symbol_index); | 1451 | const sym = &self.symbols.items[symbol_index]; |
| 1468 | sym.flags.needs_zig_got = true; | 1452 | sym.flags.needs_zig_got = true; |
| 1469 | metadata.symbol_index.* = symbol_index; | 1453 | metadata.symbol_index.* = symbol_index; |
| 1470 | }, | 1454 | }, |
| ... | @@ -1478,6 +1462,130 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -1478,6 +1462,130 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1478 | return symbol_index; | 1462 | return symbol_index; |
| 1479 | } | 1463 | } |
| 1480 | | 1464 | |
| | 1465 | fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { |
| | 1466 | const atom_index: Atom.Index = @intCast(self.atoms.items.len); |
| | 1467 | const atom = try self.atoms.addOne(allocator); |
| | 1468 | atom.* = .{ |
| | 1469 | .file = self.index, |
| | 1470 | .atom_index = atom_index, |
| | 1471 | .extra = try self.addAtomExtra(allocator, .{}), |
| | 1472 | }; |
| | 1473 | return atom_index; |
| | 1474 | } |
| | 1475 | |
| | 1476 | pub fn getAtom(self: *ZigObject, atom_index: Atom.Index) ?*Atom { |
| | 1477 | if (atom_index == 0) return null; |
| | 1478 | assert(atom_index < self.atoms.items.len); |
| | 1479 | return &self.atoms.items[atom_index]; |
| | 1480 | } |
| | 1481 | |
| | 1482 | pub fn getAtoms(self: *ZigObject) []const Atom.Index { |
| | 1483 | return self.atoms_indexes.items; |
| | 1484 | } |
| | 1485 | |
| | 1486 | fn addAtomExtra(self: *ZigObject, allocator: Allocator, extra: Atom.Extra) !u32 { |
| | 1487 | const fields = @typeInfo(Atom.Extra).Struct.fields; |
| | 1488 | try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); |
| | 1489 | return self.addAtomExtraAssumeCapacity(extra); |
| | 1490 | } |
| | 1491 | |
| | 1492 | fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 { |
| | 1493 | const index = @as(u32, @intCast(self.atoms_extra.items.len)); |
| | 1494 | const fields = @typeInfo(Atom.Extra).Struct.fields; |
| | 1495 | inline for (fields) |field| { |
| | 1496 | self.atoms_extra.appendAssumeCapacity(switch (field.type) { |
| | 1497 | u32 => @field(extra, field.name), |
| | 1498 | else => @compileError("bad field type"), |
| | 1499 | }); |
| | 1500 | } |
| | 1501 | return index; |
| | 1502 | } |
| | 1503 | |
| | 1504 | pub fn getAtomExtra(self: ZigObject, index: u32) Atom.Extra { |
| | 1505 | const fields = @typeInfo(Atom.Extra).Struct.fields; |
| | 1506 | var i: usize = index; |
| | 1507 | var result: Atom.Extra = undefined; |
| | 1508 | inline for (fields) |field| { |
| | 1509 | @field(result, field.name) = switch (field.type) { |
| | 1510 | u32 => self.atoms_extra.items[i], |
| | 1511 | else => @compileError("bad field type"), |
| | 1512 | }; |
| | 1513 | i += 1; |
| | 1514 | } |
| | 1515 | return result; |
| | 1516 | } |
| | 1517 | |
| | 1518 | pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void { |
| | 1519 | assert(index > 0); |
| | 1520 | const fields = @typeInfo(Atom.Extra).Struct.fields; |
| | 1521 | inline for (fields, 0..) |field, i| { |
| | 1522 | self.atoms_extra.items[index + i] = switch (field.type) { |
| | 1523 | u32 => @field(extra, field.name), |
| | 1524 | else => @compileError("bad field type"), |
| | 1525 | }; |
| | 1526 | } |
| | 1527 | } |
| | 1528 | |
| | 1529 | fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| | 1530 | try self.symbols.ensureUnusedCapacity(allocator, 1); |
| | 1531 | return self.addSymbolAssumeCapacity(); |
| | 1532 | } |
| | 1533 | |
| | 1534 | fn addSymbolAssumeCapacity(self: *ZigObject) Symbol.Index { |
| | 1535 | const index: Symbol.Index = @intCast(self.symbols.items.len); |
| | 1536 | const symbol = self.symbols.addOneAssumeCapacity(); |
| | 1537 | symbol.* = .{ .file = self.index }; |
| | 1538 | return index; |
| | 1539 | } |
| | 1540 | |
| | 1541 | pub fn getSymbolRef(self: ZigObject, index: Symbol.Index, macho_file: *MachO) MachO.Ref { |
| | 1542 | const global_index = self.globals.items[index]; |
| | 1543 | if (macho_file.resolver.get(global_index)) |ref| return ref; |
| | 1544 | return .{ .index = index, .file = self.index }; |
| | 1545 | } |
| | 1546 | |
| | 1547 | pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 { |
| | 1548 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1549 | try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); |
| | 1550 | return self.addSymbolExtraAssumeCapacity(extra); |
| | 1551 | } |
| | 1552 | |
| | 1553 | fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { |
| | 1554 | const index = @as(u32, @intCast(self.symbols_extra.items.len)); |
| | 1555 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1556 | inline for (fields) |field| { |
| | 1557 | self.symbols_extra.appendAssumeCapacity(switch (field.type) { |
| | 1558 | u32 => @field(extra, field.name), |
| | 1559 | else => @compileError("bad field type"), |
| | 1560 | }); |
| | 1561 | } |
| | 1562 | return index; |
| | 1563 | } |
| | 1564 | |
| | 1565 | pub fn getSymbolExtra(self: ZigObject, index: u32) Symbol.Extra { |
| | 1566 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1567 | var i: usize = index; |
| | 1568 | var result: Symbol.Extra = undefined; |
| | 1569 | inline for (fields) |field| { |
| | 1570 | @field(result, field.name) = switch (field.type) { |
| | 1571 | u32 => self.symbols_extra.items[i], |
| | 1572 | else => @compileError("bad field type"), |
| | 1573 | }; |
| | 1574 | i += 1; |
| | 1575 | } |
| | 1576 | return result; |
| | 1577 | } |
| | 1578 | |
| | 1579 | pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void { |
| | 1580 | const fields = @typeInfo(Symbol.Extra).Struct.fields; |
| | 1581 | inline for (fields, 0..) |field, i| { |
| | 1582 | self.symbols_extra.items[index + i] = switch (field.type) { |
| | 1583 | u32 => @field(extra, field.name), |
| | 1584 | else => @compileError("bad field type"), |
| | 1585 | }; |
| | 1586 | } |
| | 1587 | } |
| | 1588 | |
| 1481 | pub fn asFile(self: *ZigObject) File { | 1589 | pub fn asFile(self: *ZigObject) File { |
| 1482 | return .{ .zig_object = self }; | 1590 | return .{ .zig_object = self }; |
| 1483 | } | 1591 | } |
| ... | @@ -1503,9 +1611,16 @@ fn formatSymtab( | ... | @@ -1503,9 +1611,16 @@ fn formatSymtab( |
| 1503 | _ = unused_fmt_string; | 1611 | _ = unused_fmt_string; |
| 1504 | _ = options; | 1612 | _ = options; |
| 1505 | try writer.writeAll(" symbols\n"); | 1613 | try writer.writeAll(" symbols\n"); |
| 1506 | for (ctx.self.symbols.items) |index| { | 1614 | const self = ctx.self; |
| 1507 | const sym = ctx.macho_file.getSymbol(index); | 1615 | const macho_file = ctx.macho_file; |
| 1508 | try writer.print(" {}\n", .{sym.fmt(ctx.macho_file)}); | 1616 | for (self.symbols.items, 0) |sym, i| { |
| | 1617 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| | 1618 | if (ref.getFile(macho_file) == null) { |
| | 1619 | // TODO any better way of handling this? |
| | 1620 | try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)}); |
| | 1621 | } else { |
| | 1622 | try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)}); |
| | 1623 | } |
| 1509 | } | 1624 | } |
| 1510 | } | 1625 | } |
| 1511 | | 1626 | |
| ... | @@ -1524,10 +1639,12 @@ fn formatAtoms( | ... | @@ -1524,10 +1639,12 @@ fn formatAtoms( |
| 1524 | ) !void { | 1639 | ) !void { |
| 1525 | _ = unused_fmt_string; | 1640 | _ = unused_fmt_string; |
| 1526 | _ = options; | 1641 | _ = options; |
| | 1642 | const self = ctx.self; |
| | 1643 | const macho_file = ctx.macho_file; |
| 1527 | try writer.writeAll(" atoms\n"); | 1644 | try writer.writeAll(" atoms\n"); |
| 1528 | for (ctx.self.atoms.items) |atom_index| { | 1645 | for (self.getAtoms()) |atom_index| { |
| 1529 | const atom = ctx.macho_file.getAtom(atom_index) orelse continue; | 1646 | const atom = self.getAtom(atom_index) orelse continue; |
| 1530 | try writer.print(" {}\n", .{atom.fmt(ctx.macho_file)}); | 1647 | try writer.print(" {}\n", .{atom.fmt(macho_file)}); |
| 1531 | } | 1648 | } |
| 1532 | } | 1649 | } |
| 1533 | | 1650 | |