| ... | ... | @@ -7,6 +7,12 @@ symtab: std.MultiArrayList(Nlist) = .{}, |
| 7 | 7 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 8 | 8 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 9 | 9 | |
| 10 | /// Table of tracked Decls. |
| 11 | decls: DeclTable = .{}, |
| 12 | |
| 13 | /// A table of relocations. |
| 14 | relocs: RelocationTable = .{}, |
| 15 | |
| 10 | 16 | output_symtab_ctx: MachO.SymtabCtx = .{}, |
| 11 | 17 | |
| 12 | 18 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { |
| ... | ... | @@ -20,6 +26,19 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { |
| 20 | 26 | self.symtab.deinit(allocator); |
| 21 | 27 | self.symbols.deinit(allocator); |
| 22 | 28 | self.atoms.deinit(allocator); |
| 29 | |
| 30 | { |
| 31 | var it = self.decls.iterator(); |
| 32 | while (it.next()) |entry| { |
| 33 | entry.value_ptr.exports.deinit(allocator); |
| 34 | } |
| 35 | self.decls.deinit(allocator); |
| 36 | } |
| 37 | |
| 38 | for (self.relocs.items) |*list| { |
| 39 | list.deinit(allocator); |
| 40 | } |
| 41 | self.relocs.deinit(allocator); |
| 23 | 42 | } |
| 24 | 43 | |
| 25 | 44 | fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| ... | ... | @@ -33,6 +52,38 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { |
| 33 | 52 | return index; |
| 34 | 53 | } |
| 35 | 54 | |
| 55 | pub fn addAtom(self: *ZigObject, macho_file: *MachO) !Symbol.Index { |
| 56 | const gpa = macho_file.base.comp.gpa; |
| 57 | const atom_index = try macho_file.addAtom(); |
| 58 | const symbol_index = try macho_file.addSymbol(); |
| 59 | const nlist_index = try self.addNlist(gpa); |
| 60 | |
| 61 | try self.atoms.append(gpa, atom_index); |
| 62 | try self.symbols.append(gpa, symbol_index); |
| 63 | |
| 64 | const atom = macho_file.getAtom(atom_index).?; |
| 65 | atom.file = self.index; |
| 66 | |
| 67 | const symbol = macho_file.getSymbol(symbol_index); |
| 68 | symbol.file = self.index; |
| 69 | symbol.atom = atom_index; |
| 70 | |
| 71 | self.symtab.items(.atom)[nlist_index] = atom_index; |
| 72 | symbol.nlist_idx = nlist_index; |
| 73 | |
| 74 | const relocs_index = @as(u32, @intCast(self.relocs.items.len)); |
| 75 | const relocs = try self.relocs.addOne(gpa); |
| 76 | relocs.* = .{}; |
| 77 | atom.relocs = .{ .pos = relocs_index, .len = 0 }; |
| 78 | |
| 79 | return symbol_index; |
| 80 | } |
| 81 | |
| 82 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation { |
| 83 | const relocs = self.relocs.items[atom.relocs.pos]; |
| 84 | return relocs.items[0..atom.relocs.len]; |
| 85 | } |
| 86 | |
| 36 | 87 | pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void { |
| 37 | 88 | _ = self; |
| 38 | 89 | _ = macho_file; |
| ... | ... | @@ -216,54 +267,35 @@ pub fn updateDecl( |
| 216 | 267 | return; |
| 217 | 268 | } |
| 218 | 269 | |
| 219 | | // const is_threadlocal = if (decl.val.getVariable(mod)) |variable| |
| 220 | | // variable.is_threadlocal and comp.config.any_non_single_threaded |
| 221 | | // else |
| 222 | | // false; |
| 223 | | // if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index); |
| 224 | | |
| 225 | | // const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 226 | | // const sym_index = self.getAtom(atom_index).getSymbolIndex().?; |
| 227 | | // Atom.freeRelocations(self, atom_index); |
| 228 | | |
| 229 | | // const comp = macho_file.base.comp; |
| 230 | | // const gpa = comp.gpa; |
| 231 | | |
| 232 | | // var code_buffer = std.ArrayList(u8).init(gpa); |
| 233 | | // defer code_buffer.deinit(); |
| 234 | | |
| 235 | | // var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym| |
| 236 | | // try d_sym.dwarf.initDeclState(mod, decl_index) |
| 237 | | // else |
| 238 | | // null; |
| 239 | | // defer if (decl_state) |*ds| ds.deinit(); |
| 240 | | |
| 241 | | // const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 242 | | // const res = if (decl_state) |*ds| |
| 243 | | // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{ |
| 244 | | // .ty = decl.ty, |
| 245 | | // .val = decl_val, |
| 246 | | // }, &code_buffer, .{ |
| 247 | | // .dwarf = ds, |
| 248 | | // }, .{ |
| 249 | | // .parent_atom_index = sym_index, |
| 250 | | // }) |
| 251 | | // else |
| 252 | | // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{ |
| 253 | | // .ty = decl.ty, |
| 254 | | // .val = decl_val, |
| 255 | | // }, &code_buffer, .none, .{ |
| 256 | | // .parent_atom_index = sym_index, |
| 257 | | // }); |
| 258 | | |
| 259 | | // const code = switch (res) { |
| 260 | | // .ok => code_buffer.items, |
| 261 | | // .fail => |em| { |
| 262 | | // decl.analysis = .codegen_failure; |
| 263 | | // try mod.failed_decls.put(mod.gpa, decl_index, em); |
| 264 | | // return; |
| 265 | | // }, |
| 266 | | // }; |
| 270 | const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); |
| 271 | // TODO: free relocs if any |
| 272 | |
| 273 | const gpa = macho_file.base.comp.gpa; |
| 274 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 275 | defer code_buffer.deinit(); |
| 276 | |
| 277 | var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf |
| 278 | defer if (decl_state) |*ds| ds.deinit(); |
| 279 | |
| 280 | const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val; |
| 281 | const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none; |
| 282 | const res = |
| 283 | try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), .{ |
| 284 | .ty = decl.ty, |
| 285 | .val = decl_val, |
| 286 | }, &code_buffer, dio, .{ |
| 287 | .parent_atom_index = sym_index, |
| 288 | }); |
| 289 | |
| 290 | const code = switch (res) { |
| 291 | .ok => code_buffer.items, |
| 292 | .fail => |em| { |
| 293 | decl.analysis = .codegen_failure; |
| 294 | try mod.failed_decls.put(mod.gpa, decl_index, em); |
| 295 | return; |
| 296 | }, |
| 297 | }; |
| 298 | _ = code; |
| 267 | 299 | // const addr = try self.updateDeclCode(decl_index, code); |
| 268 | 300 | |
| 269 | 301 | // if (decl_state) |*ds| { |
| ... | ... | @@ -342,6 +374,32 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l |
| 342 | 374 | @panic("TODO getGlobalSymbol"); |
| 343 | 375 | } |
| 344 | 376 | |
| 377 | pub fn getOrCreateMetadataForDecl( |
| 378 | self: *ZigObject, |
| 379 | macho_file: *MachO, |
| 380 | decl_index: InternPool.DeclIndex, |
| 381 | ) !Symbol.Index { |
| 382 | const gpa = macho_file.base.comp.gpa; |
| 383 | const gop = try self.decls.getOrPut(gpa, decl_index); |
| 384 | if (!gop.found_existing) { |
| 385 | const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded; |
| 386 | const sym_index = try self.addAtom(macho_file); |
| 387 | const mod = macho_file.base.comp.module.?; |
| 388 | const decl = mod.declPtr(decl_index); |
| 389 | const sym = macho_file.getSymbol(self.symbols.items[sym_index]); |
| 390 | if (decl.getOwnedVariable(mod)) |variable| { |
| 391 | if (variable.is_threadlocal and any_non_single_threaded) { |
| 392 | sym.flags.tlv = true; |
| 393 | } |
| 394 | } |
| 395 | if (!sym.flags.tlv) { |
| 396 | sym.flags.needs_zig_got = true; |
| 397 | } |
| 398 | gop.value_ptr.* = .{ .symbol_index = sym_index }; |
| 399 | } |
| 400 | return gop.value_ptr.symbol_index; |
| 401 | } |
| 402 | |
| 345 | 403 | pub fn asFile(self: *ZigObject) File { |
| 346 | 404 | return .{ .zig_object = self }; |
| 347 | 405 | } |
| ... | ... | @@ -395,11 +453,23 @@ fn formatAtoms( |
| 395 | 453 | } |
| 396 | 454 | } |
| 397 | 455 | |
| 398 | | const Nlist = struct { |
| 399 | | nlist: macho.nlist_64, |
| 400 | | size: u64, |
| 401 | | atom: Atom.Index, |
| 456 | const DeclMetadata = struct { |
| 457 | symbol_index: Symbol.Index, |
| 458 | /// A list of all exports aliases of this Decl. |
| 459 | exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 460 | |
| 461 | fn @"export"(m: DeclMetadata, zig_object: *ZigObject, macho_file: *MachO, name: []const u8) ?*u32 { |
| 462 | for (m.exports.items) |*exp| { |
| 463 | const nlist = zig_object.symtab.items(.nlist)[exp.*]; |
| 464 | const exp_name = macho_file.strings.getAssumeExists(nlist.n_strx); |
| 465 | if (mem.eql(u8, name, exp_name)) return exp; |
| 466 | } |
| 467 | return null; |
| 468 | } |
| 402 | 469 | }; |
| 470 | const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata); |
| 471 | |
| 472 | const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation)); |
| 403 | 473 | |
| 404 | 474 | const assert = std.debug.assert; |
| 405 | 475 | const builtin = @import("builtin"); |
| ... | ... | @@ -420,8 +490,10 @@ const File = @import("file.zig").File; |
| 420 | 490 | const InternPool = @import("../../InternPool.zig"); |
| 421 | 491 | const Liveness = @import("../../Liveness.zig"); |
| 422 | 492 | const MachO = @import("../MachO.zig"); |
| 493 | const Nlist = Object.Nlist; |
| 423 | 494 | const Module = @import("../../Module.zig"); |
| 424 | 495 | const Object = @import("Object.zig"); |
| 496 | const Relocation = @import("Relocation.zig"); |
| 425 | 497 | const Symbol = @import("Symbol.zig"); |
| 426 | 498 | const StringTable = @import("../StringTable.zig"); |
| 427 | 499 | const Type = @import("../../type.zig").Type; |