| ... | ... | @@ -6,9 +6,15 @@ index: File.Index, |
| 6 | 6 | symtab: std.MultiArrayList(Nlist) = .{}, |
| 7 | 7 | strtab: StringTable = .{}, |
| 8 | 8 | |
| 9 | | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 10 | | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 11 | | globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| 9 | symbols: std.ArrayListUnmanaged(Symbol) = .{}, |
| 10 | symbols_extra: std.ArrayListUnmanaged(u32) = .{}, |
| 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 | 19 | /// Table of tracked LazySymbols. |
| 14 | 20 | lazy_syms: LazySymbolTable = .{}, |
| ... | ... | @@ -58,10 +64,13 @@ debug_info_header_dirty: bool = false, |
| 58 | 64 | debug_line_header_dirty: bool = false, |
| 59 | 65 | |
| 60 | 66 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { |
| 67 | const tracy = trace(@src()); |
| 68 | defer tracy.end(); |
| 69 | |
| 61 | 70 | const comp = macho_file.base.comp; |
| 62 | 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 | 74 | try self.strtab.buffer.append(gpa, 0); |
| 66 | 75 | |
| 67 | 76 | switch (comp.config.debug_format) { |
| ... | ... | @@ -84,8 +93,12 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 84 | 93 | self.symtab.deinit(allocator); |
| 85 | 94 | self.strtab.deinit(allocator); |
| 86 | 95 | self.symbols.deinit(allocator); |
| 87 | | self.atoms.deinit(allocator); |
| 96 | self.symbols_extra.deinit(allocator); |
| 97 | self.globals.deinit(allocator); |
| 88 | 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 | 104 | var it = self.decls.iterator(); |
| ... | ... | @@ -139,32 +152,21 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| 139 | 152 | return index; |
| 140 | 153 | } |
| 141 | 154 | |
| 142 | | pub fn addAtom(self: *ZigObject, macho_file: *MachO) !Symbol.Index { |
| 143 | | const gpa = macho_file.base.comp.gpa; |
| 144 | | const atom_index = try macho_file.addAtom(); |
| 145 | | const symbol_index = try macho_file.addSymbol(); |
| 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 | | |
| 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 | 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 | 163 | symbol.nlist_idx = nlist_index; |
| 161 | | |
| 164 | symbol.extra = try self.addSymbolExtra(allocator, .{}); |
| 162 | 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 | 167 | relocs.* = .{}; |
| 165 | | try atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); |
| 166 | | atom.flags.relocs = true; |
| 167 | | |
| 168 | const atom = self.getAtom(atom_index).?; |
| 169 | atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); |
| 168 | 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 | 193 | } |
| 192 | 194 | |
| 193 | 195 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) []const Relocation { |
| 194 | | if (!atom.flags.relocs) return &[0]Relocation{}; |
| 195 | | const extra = atom.getExtra(macho_file).?; |
| 196 | const extra = atom.getExtra(macho_file); |
| 196 | 197 | const relocs = self.relocs.items[extra.rel_index]; |
| 197 | 198 | return relocs.items[0..extra.rel_count]; |
| 198 | 199 | } |
| 199 | 200 | |
| 200 | 201 | pub fn freeAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) void { |
| 201 | | if (atom.flags.relocs) { |
| 202 | | const extra = atom.getExtra(macho_file).?; |
| 203 | | self.relocs.items[extra.rel_index].clearRetainingCapacity(); |
| 204 | | } |
| 202 | const extra = atom.getExtra(macho_file); |
| 203 | self.relocs.items[extra.rel_index].clearRetainingCapacity(); |
| 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 | 207 | const tracy = trace(@src()); |
| 209 | 208 | defer tracy.end(); |
| 210 | 209 | |
| 211 | | for (self.symbols.items, 0..) |index, i| { |
| 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]; |
| 210 | const gpa = macho_file.base.comp.gpa; |
| 215 | 211 | |
| 212 | for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| { |
| 216 | 213 | if (!nlist.ext()) continue; |
| 217 | | if (nlist.undf() and !nlist.tentative()) continue; |
| 218 | 214 | if (nlist.sect()) { |
| 219 | | const atom = macho_file.getAtom(atom_index).?; |
| 215 | const atom = self.getAtom(atom_index).?; |
| 220 | 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 | 234 | if (self.asFile().getSymbolRank(.{ |
| 225 | 235 | .archive = false, |
| 226 | 236 | .weak = nlist.weakDef(), |
| 227 | 237 | .tentative = nlist.tentative(), |
| 228 | | }) < symbol.getSymbolRank(macho_file)) { |
| 229 | | const value = if (nlist.sect()) blk: { |
| 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 | | } |
| 238 | }) < gop.ref.getSymbol(macho_file).?.getSymbolRank(macho_file)) { |
| 239 | gop.ref.* = .{ .index = @intCast(i), .file = self.index }; |
| 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 | 245 | const tracy = trace(@src()); |
| 282 | 246 | defer tracy.end(); |
| 283 | 247 | |
| 284 | | for (self.symbols.items, 0..) |index, nlist_idx| { |
| 285 | | const nlist = self.symtab.items(.nlist)[nlist_idx]; |
| 248 | for (0..self.symbols.items.len) |i| { |
| 249 | const nlist = self.symtab.items(.nlist)[i]; |
| 286 | 250 | if (!nlist.ext()) continue; |
| 287 | 251 | |
| 288 | | const sym = macho_file.getSymbol(index); |
| 289 | | const file = sym.getFile(macho_file) orelse continue; |
| 252 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 253 | const file = ref.getFile(macho_file) orelse continue; |
| 254 | const sym = ref.getSymbol(macho_file).?; |
| 290 | 255 | const should_keep = nlist.undf() or (nlist.tentative() and !sym.flags.tentative); |
| 291 | 256 | if (should_keep and file == .object and !file.object.alive) { |
| 292 | 257 | file.object.alive = true; |
| ... | ... | @@ -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 { |
| 299 | | for (self.symbols.items, 0..) |index, nlist_idx| { |
| 300 | | const sym = macho_file.getSymbol(index); |
| 301 | | if (sym.visibility != .global) continue; |
| 302 | | const file = sym.getFile(macho_file) orelse continue; |
| 303 | | if (file.getIndex() == self.index) continue; |
| 304 | | |
| 305 | | const nlist = self.symtab.items(.nlist)[nlist_idx]; |
| 306 | | if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) { |
| 307 | | const gop = try dupes.getOrPut(index); |
| 308 | | if (!gop.found_existing) { |
| 309 | | gop.value_ptr.* = .{}; |
| 310 | | } |
| 311 | | try gop.value_ptr.append(macho_file.base.comp.gpa, self.index); |
| 263 | pub fn mergeSymbolVisibility(self: *ZigObject, macho_file: *MachO) void { |
| 264 | const tracy = trace(@src()); |
| 265 | defer tracy.end(); |
| 266 | |
| 267 | for (self.symbols.items, 0..) |sym, i| { |
| 268 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 269 | const global = ref.getSymbol(macho_file) orelse continue; |
| 270 | if (global.visibility != .global) { |
| 271 | global.visibility = sym.visibility; |
| 272 | } |
| 273 | if (sym.flags.weak_ref) { |
| 274 | global.flags.weak_ref = true; |
| 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 | 298 | pub fn resolveLiterals(self: *ZigObject, lp: *MachO.LiteralPool, macho_file: *MachO) !void { |
| 317 | 299 | _ = self; |
| 318 | 300 | _ = lp; |
| ... | ... | @@ -362,8 +344,8 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi |
| 362 | 344 | } |
| 363 | 345 | |
| 364 | 346 | pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void { |
| 365 | | for (self.atoms.items) |atom_index| { |
| 366 | | const atom = macho_file.getAtom(atom_index) orelse continue; |
| 347 | for (self.getAtoms()) |atom_index| { |
| 348 | const atom = self.getAtom(atom_index) orelse continue; |
| 367 | 349 | if (!atom.flags.alive) continue; |
| 368 | 350 | const sect = atom.getInputSection(macho_file); |
| 369 | 351 | if (sect.isZerofill()) continue; |
| ... | ... | @@ -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 | 357 | const tracy = trace(@src()); |
| 376 | 358 | defer tracy.end(); |
| 377 | 359 | |
| 378 | | for (self.symbols.items) |sym_index| { |
| 379 | | const sym = macho_file.getSymbol(sym_index); |
| 380 | | const file = sym.getFile(macho_file) orelse continue; |
| 360 | for (self.symbols.items, 0..) |*sym, i| { |
| 361 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 362 | const file = ref.getFile(macho_file) orelse continue; |
| 381 | 363 | if (file.getIndex() != self.index) continue; |
| 382 | 364 | if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue; |
| 383 | 365 | sym.flags.output_symtab = true; |
| 384 | 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 | 368 | self.output_symtab_ctx.nlocals += 1; |
| 387 | 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 | 371 | self.output_symtab_ctx.nexports += 1; |
| 390 | 372 | } else { |
| 391 | 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 | 375 | self.output_symtab_ctx.nimports += 1; |
| 394 | 376 | } |
| 395 | 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 | 382 | const tracy = trace(@src()); |
| 401 | 383 | defer tracy.end(); |
| 402 | 384 | |
| 403 | | for (self.symbols.items) |sym_index| { |
| 404 | | const sym = macho_file.getSymbol(sym_index); |
| 405 | | const file = sym.getFile(macho_file) orelse continue; |
| 385 | var n_strx = self.output_symtab_ctx.stroff; |
| 386 | for (self.symbols.items, 0..) |sym, i| { |
| 387 | const ref = self.getSymbolRef(@intCast(i), macho_file); |
| 388 | const file = ref.getFile(macho_file) orelse continue; |
| 406 | 389 | if (file.getIndex() != self.index) continue; |
| 407 | 390 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; |
| 408 | | const n_strx = @as(u32, @intCast(ctx.strtab.items.len)); |
| 409 | | ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); |
| 410 | | ctx.strtab.appendAssumeCapacity(0); |
| 411 | | const out_sym = &ctx.symtab.items[idx]; |
| 391 | const out_sym = &macho_file.symtab.items[idx]; |
| 412 | 392 | out_sym.n_strx = n_strx; |
| 413 | 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 | 508 | reloc_info: link.File.RelocInfo, |
| 524 | 509 | ) !u64 { |
| 525 | 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 | 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 | 514 | try parent_atom.addReloc(macho_file, .{ |
| 530 | 515 | .tag = .@"extern", |
| 531 | 516 | .offset = @intCast(reloc_info.offset), |
| ... | ... | @@ -549,9 +534,9 @@ pub fn getAnonDeclVAddr( |
| 549 | 534 | reloc_info: link.File.RelocInfo, |
| 550 | 535 | ) !u64 { |
| 551 | 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 | 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 | 540 | try parent_atom.addReloc(macho_file, .{ |
| 556 | 541 | .tag = .@"extern", |
| 557 | 542 | .offset = @intCast(reloc_info.offset), |
| ... | ... | @@ -584,7 +569,7 @@ pub fn lowerAnonDecl( |
| 584 | 569 | else => explicit_alignment, |
| 585 | 570 | }; |
| 586 | 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 | 573 | if (decl_alignment.order(existing_alignment).compare(.lte)) |
| 589 | 574 | return .ok; |
| 590 | 575 | } |
| ... | ... | @@ -628,13 +613,10 @@ fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPoo |
| 628 | 613 | } |
| 629 | 614 | |
| 630 | 615 | fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { |
| 631 | | _ = self; |
| 632 | | const gpa = macho_file.base.comp.gpa; |
| 633 | | const sym = macho_file.getSymbol(sym_index); |
| 616 | const sym = self.symbols.items[sym_index]; |
| 634 | 617 | sym.getAtom(macho_file).?.free(macho_file); |
| 635 | 618 | log.debug("adding %{d} to local symbols free list", .{sym_index}); |
| 636 | | macho_file.symbols_free_list.append(gpa, sym_index) catch {}; |
| 637 | | macho_file.symbols.items[sym_index] = .{}; |
| 619 | // TODO redo this |
| 638 | 620 | // TODO free GOT entry here |
| 639 | 621 | } |
| 640 | 622 | |
| ... | ... | @@ -675,7 +657,7 @@ pub fn updateFunc( |
| 675 | 657 | |
| 676 | 658 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 677 | 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 | 662 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 681 | 663 | defer code_buffer.deinit(); |
| ... | ... | @@ -708,7 +690,7 @@ pub fn updateFunc( |
| 708 | 690 | try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code); |
| 709 | 691 | |
| 710 | 692 | if (decl_state) |*ds| { |
| 711 | | const sym = macho_file.getSymbol(sym_index); |
| 693 | const sym = self.symbols.items[sym_index]; |
| 712 | 694 | try self.dwarf.?.commitDeclState( |
| 713 | 695 | pt, |
| 714 | 696 | decl_index, |
| ... | ... | @@ -743,13 +725,13 @@ pub fn updateDecl( |
| 743 | 725 | const name = decl.name.toSlice(&mod.intern_pool); |
| 744 | 726 | const lib_name = variable.lib_name.toSlice(&mod.intern_pool); |
| 745 | 727 | const index = try self.getGlobalSymbol(macho_file, name, lib_name); |
| 746 | | const actual_index = self.symbols.items[index]; |
| 747 | | macho_file.getSymbol(actual_index).flags.needs_got = true; |
| 728 | const sym = &self.symbols.items[index]; |
| 729 | sym.flags.needs_got = true; |
| 748 | 730 | return; |
| 749 | 731 | } |
| 750 | 732 | |
| 751 | 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 | 736 | const gpa = macho_file.base.comp.gpa; |
| 755 | 737 | var code_buffer = std.ArrayList(u8).init(gpa); |
| ... | ... | @@ -784,7 +766,7 @@ pub fn updateDecl( |
| 784 | 766 | } |
| 785 | 767 | |
| 786 | 768 | if (decl_state) |*ds| { |
| 787 | | const sym = macho_file.getSymbol(sym_index); |
| 769 | const sym = self.symbols.items[sym_index]; |
| 788 | 770 | try self.dwarf.?.commitDeclState( |
| 789 | 771 | pt, |
| 790 | 772 | decl_index, |
| ... | ... | @@ -816,7 +798,7 @@ fn updateDeclCode( |
| 816 | 798 | const required_alignment = decl.getAlignment(pt); |
| 817 | 799 | |
| 818 | 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 | 802 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 821 | 803 | const atom = sym.getAtom(macho_file).?; |
| 822 | 804 | |
| ... | ... | @@ -850,13 +832,13 @@ fn updateDeclCode( |
| 850 | 832 | if (!macho_file.base.isRelocatable()) { |
| 851 | 833 | log.debug(" (updating offset table entry)", .{}); |
| 852 | 834 | assert(sym.flags.has_zig_got); |
| 853 | | const extra = sym.getExtra(macho_file).?; |
| 835 | const extra = sym.getExtra(macho_file); |
| 854 | 836 | try macho_file.zig_got.writeOne(macho_file, extra.zig_got); |
| 855 | 837 | } |
| 856 | 838 | } |
| 857 | 839 | } else if (code.len < old_size) { |
| 858 | 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 | 842 | const needed_size = atom.value + code.len; |
| 861 | 843 | sect.size = needed_size; |
| 862 | 844 | } |
| ... | ... | @@ -922,8 +904,8 @@ fn createTlvInitializer( |
| 922 | 904 | const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); |
| 923 | 905 | defer gpa.free(sym_name); |
| 924 | 906 | |
| 925 | | const sym_index = try self.addAtom(macho_file); |
| 926 | | const sym = macho_file.getSymbol(sym_index); |
| 907 | const sym_index = try self.createAtomForDecl(gpa, macho_file); |
| 908 | const sym = &self.symbols.items[sym_index]; |
| 927 | 909 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 928 | 910 | const atom = sym.getAtom(macho_file).?; |
| 929 | 911 | |
| ... | ... | @@ -945,7 +927,6 @@ fn createTlvInitializer( |
| 945 | 927 | |
| 946 | 928 | const slice = macho_file.sections.slice(); |
| 947 | 929 | const header = slice.items(.header)[sect_index]; |
| 948 | | const atoms = &slice.items(.atoms)[sect_index]; |
| 949 | 930 | |
| 950 | 931 | const gop = try self.tlv_initializers.getOrPut(gpa, atom.atom_index); |
| 951 | 932 | assert(!gop.found_existing); // TODO incremental updates |
| ... | ... | @@ -956,8 +937,6 @@ fn createTlvInitializer( |
| 956 | 937 | gop.value_ptr.data = try gpa.dupe(u8, code); |
| 957 | 938 | } |
| 958 | 939 | |
| 959 | | try atoms.append(gpa, atom.atom_index); |
| 960 | | |
| 961 | 940 | return sym_index; |
| 962 | 941 | } |
| 963 | 942 | |
| ... | ... | @@ -970,7 +949,7 @@ fn createTlvDescriptor( |
| 970 | 949 | ) !void { |
| 971 | 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 | 953 | const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; |
| 975 | 954 | const atom = sym.getAtom(macho_file).?; |
| 976 | 955 | const alignment = Atom.Alignment.fromNonzeroByteUnits(@alignOf(u64)); |
| ... | ... | @@ -1000,7 +979,7 @@ fn createTlvDescriptor( |
| 1000 | 979 | try atom.addReloc(macho_file, .{ |
| 1001 | 980 | .tag = .@"extern", |
| 1002 | 981 | .offset = 0, |
| 1003 | | .target = self.symbols.items[tlv_bootstrap_index], |
| 982 | .target = tlv_bootstrap_index, |
| 1004 | 983 | .addend = 0, |
| 1005 | 984 | .type = .unsigned, |
| 1006 | 985 | .meta = .{ |
| ... | ... | @@ -1020,11 +999,14 @@ fn createTlvDescriptor( |
| 1020 | 999 | .pcrel = false, |
| 1021 | 1000 | .has_subtractor = false, |
| 1022 | 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 | 1012 | fn getDeclOutputSection( |
| ... | ... | @@ -1115,7 +1097,7 @@ pub fn lowerUnnamedConst( |
| 1115 | 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 | 1101 | try unnamed_consts.append(gpa, sym.atom); |
| 1120 | 1102 | return sym_index; |
| 1121 | 1103 | } |
| ... | ... | @@ -1140,7 +1122,7 @@ fn lowerConst( |
| 1140 | 1122 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 1141 | 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 | 1127 | const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ |
| 1146 | 1128 | .none = {}, |
| ... | ... | @@ -1152,7 +1134,7 @@ fn lowerConst( |
| 1152 | 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 | 1138 | const name_str_index = try self.strtab.insert(gpa, name); |
| 1157 | 1139 | sym.name = name_str_index; |
| 1158 | 1140 | sym.out_n_sect = output_section_index; |
| ... | ... | @@ -1218,7 +1200,7 @@ pub fn updateExports( |
| 1218 | 1200 | }, |
| 1219 | 1201 | }; |
| 1220 | 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 | 1204 | const nlist = self.symtab.items(.nlist)[nlist_idx]; |
| 1223 | 1205 | |
| 1224 | 1206 | for (export_indices) |export_idx| { |
| ... | ... | @@ -1322,7 +1304,7 @@ fn updateLazySymbol( |
| 1322 | 1304 | .code => macho_file.zig_text_sect_index.?, |
| 1323 | 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 | 1308 | sym.name = name_str_index; |
| 1327 | 1309 | sym.out_n_sect = output_section_index; |
| 1328 | 1310 | |
| ... | ... | @@ -1382,12 +1364,12 @@ pub fn deleteExport( |
| 1382 | 1364 | const nlist = &self.symtab.items(.nlist)[nlist_index.*]; |
| 1383 | 1365 | self.symtab.items(.size)[nlist_index.*] = 0; |
| 1384 | 1366 | _ = self.globals_lookup.remove(nlist.n_strx); |
| 1385 | | const sym_index = macho_file.globals.get(nlist.n_strx).?; |
| 1386 | | const sym = macho_file.getSymbol(sym_index); |
| 1387 | | if (sym.file == self.index) { |
| 1388 | | _ = macho_file.globals.swapRemove(nlist.n_strx); |
| 1389 | | sym.* = .{}; |
| 1390 | | } |
| 1367 | // TODO actually remove the export |
| 1368 | // const sym_index = macho_file.globals.get(nlist.n_strx).?; |
| 1369 | // const sym = &self.symbols.items[sym_index]; |
| 1370 | // if (sym.file == self.index) { |
| 1371 | // sym.* = .{}; |
| 1372 | // } |
| 1391 | 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 | 1386 | nlist.n_strx = off; |
| 1405 | 1387 | nlist.n_type = macho.N_EXT; |
| 1406 | 1388 | lookup_gop.value_ptr.* = nlist_index; |
| 1407 | | const global_name_off = try macho_file.strings.insert(gpa, sym_name); |
| 1408 | | const gop = try macho_file.getOrCreateGlobal(global_name_off); |
| 1409 | | try self.symbols.append(gpa, gop.index); |
| 1389 | _ = try macho_file.resolver.getOrPut(gpa, .{ |
| 1390 | .index = nlist_index, |
| 1391 | .file = self.index, |
| 1392 | }, macho_file); |
| 1393 | try self.globals.append(gpa, nlist_index); |
| 1410 | 1394 | } |
| 1411 | 1395 | return lookup_gop.value_ptr.*; |
| 1412 | 1396 | } |
| ... | ... | @@ -1420,10 +1404,10 @@ pub fn getOrCreateMetadataForDecl( |
| 1420 | 1404 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 1421 | 1405 | if (!gop.found_existing) { |
| 1422 | 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 | 1408 | const mod = macho_file.base.comp.module.?; |
| 1425 | 1409 | const decl = mod.declPtr(decl_index); |
| 1426 | | const sym = macho_file.getSymbol(sym_index); |
| 1410 | const sym = &self.symbols.items[sym_index]; |
| 1427 | 1411 | if (decl.getOwnedVariable(mod)) |variable| { |
| 1428 | 1412 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 1429 | 1413 | sym.flags.tlv = true; |
| ... | ... | @@ -1463,8 +1447,8 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1463 | 1447 | }; |
| 1464 | 1448 | switch (metadata.state.*) { |
| 1465 | 1449 | .unused => { |
| 1466 | | const symbol_index = try self.addAtom(macho_file); |
| 1467 | | const sym = macho_file.getSymbol(symbol_index); |
| 1450 | const symbol_index = try self.createAtomForDecl(gpa, macho_file); |
| 1451 | const sym = &self.symbols.items[symbol_index]; |
| 1468 | 1452 | sym.flags.needs_zig_got = true; |
| 1469 | 1453 | metadata.symbol_index.* = symbol_index; |
| 1470 | 1454 | }, |
| ... | ... | @@ -1478,6 +1462,130 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 1478 | 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 | 1589 | pub fn asFile(self: *ZigObject) File { |
| 1482 | 1590 | return .{ .zig_object = self }; |
| 1483 | 1591 | } |
| ... | ... | @@ -1503,9 +1611,16 @@ fn formatSymtab( |
| 1503 | 1611 | _ = unused_fmt_string; |
| 1504 | 1612 | _ = options; |
| 1505 | 1613 | try writer.writeAll(" symbols\n"); |
| 1506 | | for (ctx.self.symbols.items) |index| { |
| 1507 | | const sym = ctx.macho_file.getSymbol(index); |
| 1508 | | try writer.print(" {}\n", .{sym.fmt(ctx.macho_file)}); |
| 1614 | const self = ctx.self; |
| 1615 | const macho_file = 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 | 1639 | ) !void { |
| 1525 | 1640 | _ = unused_fmt_string; |
| 1526 | 1641 | _ = options; |
| 1642 | const self = ctx.self; |
| 1643 | const macho_file = ctx.macho_file; |
| 1527 | 1644 | try writer.writeAll(" atoms\n"); |
| 1528 | | for (ctx.self.atoms.items) |atom_index| { |
| 1529 | | const atom = ctx.macho_file.getAtom(atom_index) orelse continue; |
| 1530 | | try writer.print(" {}\n", .{atom.fmt(ctx.macho_file)}); |
| 1645 | for (self.getAtoms()) |atom_index| { |
| 1646 | const atom = self.getAtom(atom_index) orelse continue; |
| 1647 | try writer.print(" {}\n", .{atom.fmt(macho_file)}); |
| 1531 | 1648 | } |
| 1532 | 1649 | } |
| 1533 | 1650 | |