| ... | @@ -66,7 +66,7 @@ const Section = struct { | ... | @@ -66,7 +66,7 @@ const Section = struct { |
| 66 | | 66 | |
| 67 | // TODO is null here necessary, or can we do away with tracking via section | 67 | // TODO is null here necessary, or can we do away with tracking via section |
| 68 | // size in incremental context? | 68 | // size in incremental context? |
| 69 | last_atom: ?*Atom = null, | 69 | last_atom_index: ?Atom.Index = null, |
| 70 | | 70 | |
| 71 | /// A list of atoms that have surplus capacity. This list can have false | 71 | /// A list of atoms that have surplus capacity. This list can have false |
| 72 | /// positives, as functions grow and shrink over time, only sometimes being added | 72 | /// positives, as functions grow and shrink over time, only sometimes being added |
| ... | @@ -83,7 +83,7 @@ const Section = struct { | ... | @@ -83,7 +83,7 @@ const Section = struct { |
| 83 | /// overcapacity can be negative. A simple way to have negative overcapacity is to | 83 | /// overcapacity can be negative. A simple way to have negative overcapacity is to |
| 84 | /// allocate a fresh atom, which will have ideal capacity, and then grow it | 84 | /// allocate a fresh atom, which will have ideal capacity, and then grow it |
| 85 | /// by 1 byte. It will then have -1 overcapacity. | 85 | /// by 1 byte. It will then have -1 overcapacity. |
| 86 | free_list: std.ArrayListUnmanaged(*Atom) = .{}, | 86 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 87 | }; | 87 | }; |
| 88 | | 88 | |
| 89 | base: File, | 89 | base: File, |
| ... | @@ -140,8 +140,8 @@ locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | ... | @@ -140,8 +140,8 @@ locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 140 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 140 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 141 | | 141 | |
| 142 | dyld_stub_binder_index: ?u32 = null, | 142 | dyld_stub_binder_index: ?u32 = null, |
| 143 | dyld_private_atom: ?*Atom = null, | 143 | dyld_private_atom_index: ?Atom.Index = null, |
| 144 | stub_helper_preamble_atom: ?*Atom = null, | 144 | stub_helper_preamble_atom_index: ?Atom.Index = null, |
| 145 | | 145 | |
| 146 | strtab: StringTable(.strtab) = .{}, | 146 | strtab: StringTable(.strtab) = .{}, |
| 147 | | 147 | |
| ... | @@ -164,10 +164,10 @@ segment_table_dirty: bool = false, | ... | @@ -164,10 +164,10 @@ segment_table_dirty: bool = false, |
| 164 | cold_start: bool = true, | 164 | cold_start: bool = true, |
| 165 | | 165 | |
| 166 | /// List of atoms that are either synthetic or map directly to the Zig source program. | 166 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 167 | managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, | 167 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 168 | | 168 | |
| 169 | /// Table of atoms indexed by the symbol index. | 169 | /// Table of atoms indexed by the symbol index. |
| 170 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, | 170 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{}, |
| 171 | | 171 | |
| 172 | /// Table of unnamed constants associated with a parent `Decl`. | 172 | /// Table of unnamed constants associated with a parent `Decl`. |
| 173 | /// We store them here so that we can free the constants whenever the `Decl` | 173 | /// We store them here so that we can free the constants whenever the `Decl` |
| ... | @@ -210,11 +210,36 @@ bindings: BindingTable = .{}, | ... | @@ -210,11 +210,36 @@ bindings: BindingTable = .{}, |
| 210 | /// this will be a table indexed by index into the list of Atoms. | 210 | /// this will be a table indexed by index into the list of Atoms. |
| 211 | lazy_bindings: BindingTable = .{}, | 211 | lazy_bindings: BindingTable = .{}, |
| 212 | | 212 | |
| 213 | /// Table of Decls that are currently alive. | 213 | /// Table of tracked Decls. |
| 214 | /// We store them here so that we can properly dispose of any allocated | 214 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 215 | /// memory within the atom in the incremental linker. | 215 | |
| 216 | /// TODO consolidate this. | 216 | const DeclMetadata = struct { |
| 217 | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, ?u8) = .{}, | 217 | atom: Atom.Index, |
| | 218 | section: u8, |
| | 219 | /// A list of all exports aliases of this Decl. |
| | 220 | /// TODO do we actually need this at all? |
| | 221 | exports: std.ArrayListUnmanaged(u32) = .{}, |
| | 222 | |
| | 223 | fn getExport(m: DeclMetadata, macho_file: *const MachO, name: []const u8) ?u32 { |
| | 224 | for (m.exports.items) |exp| { |
| | 225 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ |
| | 226 | .sym_index = exp, |
| | 227 | .file = null, |
| | 228 | }))) return exp; |
| | 229 | } |
| | 230 | return null; |
| | 231 | } |
| | 232 | |
| | 233 | fn getExportPtr(m: *DeclMetadata, macho_file: *MachO, name: []const u8) ?*u32 { |
| | 234 | for (m.exports.items) |*exp| { |
| | 235 | if (mem.eql(u8, name, macho_file.getSymbolName(.{ |
| | 236 | .sym_index = exp.*, |
| | 237 | .file = null, |
| | 238 | }))) return exp; |
| | 239 | } |
| | 240 | return null; |
| | 241 | } |
| | 242 | }; |
| 218 | | 243 | |
| 219 | const Entry = struct { | 244 | const Entry = struct { |
| 220 | target: SymbolWithLoc, | 245 | target: SymbolWithLoc, |
| ... | @@ -229,8 +254,8 @@ const Entry = struct { | ... | @@ -229,8 +254,8 @@ const Entry = struct { |
| 229 | return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null }); | 254 | return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null }); |
| 230 | } | 255 | } |
| 231 | | 256 | |
| 232 | pub fn getAtom(entry: Entry, macho_file: *MachO) ?*Atom { | 257 | pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index { |
| 233 | return macho_file.getAtomForSymbol(.{ .sym_index = entry.sym_index, .file = null }); | 258 | return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index, .file = null }); |
| 234 | } | 259 | } |
| 235 | | 260 | |
| 236 | pub fn getName(entry: Entry, macho_file: *MachO) []const u8 { | 261 | pub fn getName(entry: Entry, macho_file: *MachO) []const u8 { |
| ... | @@ -238,10 +263,10 @@ const Entry = struct { | ... | @@ -238,10 +263,10 @@ const Entry = struct { |
| 238 | } | 263 | } |
| 239 | }; | 264 | }; |
| 240 | | 265 | |
| 241 | const BindingTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Atom.Binding)); | 266 | const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding)); |
| 242 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); | 267 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 243 | const RebaseTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32)); | 268 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 244 | const RelocationTable = std.AutoArrayHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation)); | 269 | const RelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 245 | | 270 | |
| 246 | const PendingUpdate = union(enum) { | 271 | const PendingUpdate = union(enum) { |
| 247 | resolve_undef: u32, | 272 | resolve_undef: u32, |
| ... | @@ -286,10 +311,6 @@ pub const default_pagezero_vmsize: u64 = 0x100000000; | ... | @@ -286,10 +311,6 @@ pub const default_pagezero_vmsize: u64 = 0x100000000; |
| 286 | /// potential future extensions. | 311 | /// potential future extensions. |
| 287 | pub const default_headerpad_size: u32 = 0x1000; | 312 | pub const default_headerpad_size: u32 = 0x1000; |
| 288 | | 313 | |
| 289 | pub const Export = struct { | | |
| 290 | sym_index: ?u32 = null, | | |
| 291 | }; | | |
| 292 | | | |
| 293 | pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { | 314 | pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { |
| 294 | assert(options.target.ofmt == .macho); | 315 | assert(options.target.ofmt == .macho); |
| 295 | | 316 | |
| ... | @@ -451,9 +472,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -451,9 +472,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 451 | | 472 | |
| 452 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 473 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 453 | | 474 | |
| 454 | if (self.d_sym) |*d_sym| { | 475 | // if (self.d_sym) |*d_sym| { |
| 455 | try d_sym.dwarf.flushModule(module); | 476 | // try d_sym.dwarf.flushModule(module); |
| 456 | } | 477 | // } |
| 457 | | 478 | |
| 458 | var libs = std.StringArrayHashMap(link.SystemLib).init(arena); | 479 | var libs = std.StringArrayHashMap(link.SystemLib).init(arena); |
| 459 | try resolveLibSystem( | 480 | try resolveLibSystem( |
| ... | @@ -547,8 +568,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -547,8 +568,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 547 | | 568 | |
| 548 | try self.allocateSpecialSymbols(); | 569 | try self.allocateSpecialSymbols(); |
| 549 | | 570 | |
| 550 | for (self.relocs.keys()) |atom| { | 571 | for (self.relocs.keys()) |atom_index| { |
| 551 | try atom.resolveRelocations(self); | 572 | try Atom.resolveRelocations(self, atom_index); |
| 552 | } | 573 | } |
| 553 | | 574 | |
| 554 | if (build_options.enable_logging) { | 575 | if (build_options.enable_logging) { |
| ... | @@ -643,10 +664,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -643,10 +664,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 643 | try self.writeCodeSignature(comp, csig); // code signing always comes last | 664 | try self.writeCodeSignature(comp, csig); // code signing always comes last |
| 644 | } | 665 | } |
| 645 | | 666 | |
| 646 | if (self.d_sym) |*d_sym| { | 667 | // if (self.d_sym) |*d_sym| { |
| 647 | // Flush debug symbols bundle. | 668 | // // Flush debug symbols bundle. |
| 648 | try d_sym.flushModule(self); | 669 | // try d_sym.flushModule(self); |
| 649 | } | 670 | // } |
| 650 | | 671 | |
| 651 | // if (build_options.enable_link_snapshots) { | 672 | // if (build_options.enable_link_snapshots) { |
| 652 | // if (self.base.options.enable_link_snapshots) | 673 | // if (self.base.options.enable_link_snapshots) |
| ... | @@ -999,18 +1020,19 @@ pub fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: | ... | @@ -999,18 +1020,19 @@ pub fn parseDependentLibs(self: *MachO, syslibroot: ?[]const u8, dependent_libs: |
| 999 | } | 1020 | } |
| 1000 | } | 1021 | } |
| 1001 | | 1022 | |
| 1002 | pub fn writeAtom(self: *MachO, atom: *Atom, code: []const u8) !void { | 1023 | pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []const u8) !void { |
| | 1024 | const atom = self.getAtom(atom_index); |
| 1003 | const sym = atom.getSymbol(self); | 1025 | const sym = atom.getSymbol(self); |
| 1004 | const section = self.sections.get(sym.n_sect - 1); | 1026 | const section = self.sections.get(sym.n_sect - 1); |
| 1005 | const file_offset = section.header.offset + sym.n_value - section.header.addr; | 1027 | const file_offset = section.header.offset + sym.n_value - section.header.addr; |
| 1006 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); | 1028 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); |
| 1007 | try self.base.file.?.pwriteAll(code, file_offset); | 1029 | try self.base.file.?.pwriteAll(code, file_offset); |
| 1008 | try atom.resolveRelocations(self); | 1030 | try Atom.resolveRelocations(self, atom_index); |
| 1009 | } | 1031 | } |
| 1010 | | 1032 | |
| 1011 | fn writePtrWidthAtom(self: *MachO, atom: *Atom) !void { | 1033 | fn writePtrWidthAtom(self: *MachO, atom_index: Atom.Index) !void { |
| 1012 | var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64); | 1034 | var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64); |
| 1013 | try self.writeAtom(atom, &buffer); | 1035 | try self.writeAtom(atom_index, &buffer); |
| 1014 | } | 1036 | } |
| 1015 | | 1037 | |
| 1016 | fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { | 1038 | fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { |
| ... | @@ -1026,7 +1048,8 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { | ... | @@ -1026,7 +1048,8 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { |
| 1026 | fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { | 1048 | fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { |
| 1027 | for (self.relocs.values()) |*relocs| { | 1049 | for (self.relocs.values()) |*relocs| { |
| 1028 | for (relocs.items) |*reloc| { | 1050 | for (relocs.items) |*reloc| { |
| 1029 | const target_atom = reloc.getTargetAtom(self) orelse continue; | 1051 | const target_atom_index = reloc.getTargetAtomIndex(self) orelse continue; |
| | 1052 | const target_atom = self.getAtom(target_atom_index); |
| 1030 | const target_sym = target_atom.getSymbol(self); | 1053 | const target_sym = target_atom.getSymbol(self); |
| 1031 | if (target_sym.n_value < addr) continue; | 1054 | if (target_sym.n_value < addr) continue; |
| 1032 | reloc.dirty = true; | 1055 | reloc.dirty = true; |
| ... | @@ -1053,26 +1076,39 @@ pub fn allocateSpecialSymbols(self: *MachO) !void { | ... | @@ -1053,26 +1076,39 @@ pub fn allocateSpecialSymbols(self: *MachO) !void { |
| 1053 | } | 1076 | } |
| 1054 | } | 1077 | } |
| 1055 | | 1078 | |
| 1056 | pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { | 1079 | pub fn createAtom(self: *MachO) !Atom.Index { |
| 1057 | const gpa = self.base.allocator; | 1080 | const gpa = self.base.allocator; |
| | 1081 | const atom_index = @intCast(Atom.Index, self.atoms.items.len); |
| | 1082 | const atom = try self.atoms.addOne(gpa); |
| | 1083 | const sym_index = try self.allocateSymbol(); |
| | 1084 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index); |
| | 1085 | atom.* = .{ |
| | 1086 | .sym_index = sym_index, |
| | 1087 | .file = null, |
| | 1088 | .size = 0, |
| | 1089 | .alignment = 0, |
| | 1090 | .prev_index = null, |
| | 1091 | .next_index = null, |
| | 1092 | .dbg_info_atom = undefined, |
| | 1093 | }; |
| | 1094 | log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index }); |
| | 1095 | return atom_index; |
| | 1096 | } |
| 1058 | | 1097 | |
| 1059 | const atom = try gpa.create(Atom); | 1098 | pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { |
| 1060 | atom.* = Atom.empty; | 1099 | const atom_index = try self.createAtom(); |
| 1061 | try atom.ensureInitialized(self); | 1100 | const atom = self.getAtomPtr(atom_index); |
| 1062 | atom.size = @sizeOf(u64); | 1101 | atom.size = @sizeOf(u64); |
| 1063 | atom.alignment = @alignOf(u64); | 1102 | atom.alignment = @alignOf(u64); |
| 1064 | errdefer gpa.destroy(atom); | | |
| 1065 | | | |
| 1066 | try self.managed_atoms.append(gpa, atom); | | |
| 1067 | | 1103 | |
| 1068 | const sym = atom.getSymbolPtr(self); | 1104 | const sym = atom.getSymbolPtr(self); |
| 1069 | sym.n_type = macho.N_SECT; | 1105 | sym.n_type = macho.N_SECT; |
| 1070 | sym.n_sect = self.got_section_index.? + 1; | 1106 | sym.n_sect = self.got_section_index.? + 1; |
| 1071 | sym.n_value = try self.allocateAtom(atom, atom.size, @alignOf(u64)); | 1107 | sym.n_value = try self.allocateAtom(atom_index, atom.size, @alignOf(u64)); |
| 1072 | | 1108 | |
| 1073 | log.debug("allocated GOT atom at 0x{x}", .{sym.n_value}); | 1109 | log.debug("allocated GOT atom at 0x{x}", .{sym.n_value}); |
| 1074 | | 1110 | |
| 1075 | try atom.addRelocation(self, .{ | 1111 | try Atom.addRelocation(self, atom_index, .{ |
| 1076 | .type = switch (self.base.options.target.cpu.arch) { | 1112 | .type = switch (self.base.options.target.cpu.arch) { |
| 1077 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), | 1113 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), |
| 1078 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), | 1114 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), |
| ... | @@ -1087,45 +1123,39 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { | ... | @@ -1087,45 +1123,39 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !*Atom { |
| 1087 | | 1123 | |
| 1088 | const target_sym = self.getSymbol(target); | 1124 | const target_sym = self.getSymbol(target); |
| 1089 | if (target_sym.undf()) { | 1125 | if (target_sym.undf()) { |
| 1090 | try atom.addBinding(self, .{ | 1126 | try Atom.addBinding(self, atom_index, .{ |
| 1091 | .target = self.getGlobal(self.getSymbolName(target)).?, | 1127 | .target = self.getGlobal(self.getSymbolName(target)).?, |
| 1092 | .offset = 0, | 1128 | .offset = 0, |
| 1093 | }); | 1129 | }); |
| 1094 | } else { | 1130 | } else { |
| 1095 | try atom.addRebase(self, 0); | 1131 | try Atom.addRebase(self, atom_index, 0); |
| 1096 | } | 1132 | } |
| 1097 | | 1133 | |
| 1098 | return atom; | 1134 | return atom_index; |
| 1099 | } | 1135 | } |
| 1100 | | 1136 | |
| 1101 | pub fn createDyldPrivateAtom(self: *MachO) !void { | 1137 | pub fn createDyldPrivateAtom(self: *MachO) !void { |
| 1102 | if (self.dyld_stub_binder_index == null) return; | 1138 | if (self.dyld_stub_binder_index == null) return; |
| 1103 | if (self.dyld_private_atom != null) return; | 1139 | if (self.dyld_private_atom_index != null) return; |
| 1104 | | 1140 | |
| 1105 | const gpa = self.base.allocator; | 1141 | const atom_index = try self.createAtom(); |
| 1106 | | 1142 | const atom = self.getAtomPtr(atom_index); |
| 1107 | const atom = try gpa.create(Atom); | | |
| 1108 | atom.* = Atom.empty; | | |
| 1109 | try atom.ensureInitialized(self); | | |
| 1110 | atom.size = @sizeOf(u64); | 1143 | atom.size = @sizeOf(u64); |
| 1111 | atom.alignment = @alignOf(u64); | 1144 | atom.alignment = @alignOf(u64); |
| 1112 | errdefer gpa.destroy(atom); | | |
| 1113 | | 1145 | |
| 1114 | const sym = atom.getSymbolPtr(self); | 1146 | const sym = atom.getSymbolPtr(self); |
| 1115 | sym.n_type = macho.N_SECT; | 1147 | sym.n_type = macho.N_SECT; |
| 1116 | sym.n_sect = self.data_section_index.? + 1; | 1148 | sym.n_sect = self.data_section_index.? + 1; |
| 1117 | self.dyld_private_atom = atom; | 1149 | self.dyld_private_atom_index = atom_index; |
| 1118 | | | |
| 1119 | try self.managed_atoms.append(gpa, atom); | | |
| 1120 | | 1150 | |
| 1121 | sym.n_value = try self.allocateAtom(atom, atom.size, @alignOf(u64)); | 1151 | sym.n_value = try self.allocateAtom(atom_index, atom.size, @alignOf(u64)); |
| 1122 | log.debug("allocated dyld_private atom at 0x{x}", .{sym.n_value}); | 1152 | log.debug("allocated dyld_private atom at 0x{x}", .{sym.n_value}); |
| 1123 | try self.writePtrWidthAtom(atom); | 1153 | try self.writePtrWidthAtom(atom_index); |
| 1124 | } | 1154 | } |
| 1125 | | 1155 | |
| 1126 | pub fn createStubHelperPreambleAtom(self: *MachO) !void { | 1156 | pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1127 | if (self.dyld_stub_binder_index == null) return; | 1157 | if (self.dyld_stub_binder_index == null) return; |
| 1128 | if (self.stub_helper_preamble_atom != null) return; | 1158 | if (self.stub_helper_preamble_atom_index != null) return; |
| 1129 | | 1159 | |
| 1130 | const gpa = self.base.allocator; | 1160 | const gpa = self.base.allocator; |
| 1131 | const arch = self.base.options.target.cpu.arch; | 1161 | const arch = self.base.options.target.cpu.arch; |
| ... | @@ -1134,22 +1164,23 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1134,22 +1164,23 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1134 | .aarch64 => 6 * @sizeOf(u32), | 1164 | .aarch64 => 6 * @sizeOf(u32), |
| 1135 | else => unreachable, | 1165 | else => unreachable, |
| 1136 | }; | 1166 | }; |
| 1137 | const atom = try gpa.create(Atom); | 1167 | const atom_index = try self.createAtom(); |
| 1138 | atom.* = Atom.empty; | 1168 | const atom = self.getAtomPtr(atom_index); |
| 1139 | try atom.ensureInitialized(self); | | |
| 1140 | atom.size = size; | 1169 | atom.size = size; |
| 1141 | atom.alignment = switch (arch) { | 1170 | atom.alignment = switch (arch) { |
| 1142 | .x86_64 => 1, | 1171 | .x86_64 => 1, |
| 1143 | .aarch64 => @alignOf(u32), | 1172 | .aarch64 => @alignOf(u32), |
| 1144 | else => unreachable, | 1173 | else => unreachable, |
| 1145 | }; | 1174 | }; |
| 1146 | errdefer gpa.destroy(atom); | | |
| 1147 | | 1175 | |
| 1148 | const sym = atom.getSymbolPtr(self); | 1176 | const sym = atom.getSymbolPtr(self); |
| 1149 | sym.n_type = macho.N_SECT; | 1177 | sym.n_type = macho.N_SECT; |
| 1150 | sym.n_sect = self.stub_helper_section_index.? + 1; | 1178 | sym.n_sect = self.stub_helper_section_index.? + 1; |
| 1151 | | 1179 | |
| 1152 | const dyld_private_sym_index = self.dyld_private_atom.?.getSymbolIndex().?; | 1180 | const dyld_private_sym_index = if (self.dyld_private_atom_index) |dyld_index| |
| | 1181 | self.getAtom(dyld_index).getSymbolIndex().? |
| | 1182 | else |
| | 1183 | unreachable; |
| 1153 | | 1184 | |
| 1154 | const code = try gpa.alloc(u8, size); | 1185 | const code = try gpa.alloc(u8, size); |
| 1155 | defer gpa.free(code); | 1186 | defer gpa.free(code); |
| ... | @@ -1168,7 +1199,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1168,7 +1199,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1168 | code[9] = 0xff; | 1199 | code[9] = 0xff; |
| 1169 | code[10] = 0x25; | 1200 | code[10] = 0x25; |
| 1170 | | 1201 | |
| 1171 | try atom.addRelocations(self, 2, .{ .{ | 1202 | try Atom.addRelocations(self, atom_index, 2, .{ .{ |
| 1172 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), | 1203 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), |
| 1173 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, | 1204 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, |
| 1174 | .offset = 3, | 1205 | .offset = 3, |
| ... | @@ -1208,7 +1239,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1208,7 +1239,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1208 | // br x16 | 1239 | // br x16 |
| 1209 | mem.writeIntLittle(u32, code[20..][0..4], aarch64.Instruction.br(.x16).toU32()); | 1240 | mem.writeIntLittle(u32, code[20..][0..4], aarch64.Instruction.br(.x16).toU32()); |
| 1210 | | 1241 | |
| 1211 | try atom.addRelocations(self, 4, .{ .{ | 1242 | try Atom.addRelocations(self, atom_index, 4, .{ .{ |
| 1212 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), | 1243 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), |
| 1213 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, | 1244 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, |
| 1214 | .offset = 0, | 1245 | .offset = 0, |
| ... | @@ -1241,16 +1272,14 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1241,16 +1272,14 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1241 | | 1272 | |
| 1242 | else => unreachable, | 1273 | else => unreachable, |
| 1243 | } | 1274 | } |
| 1244 | self.stub_helper_preamble_atom = atom; | 1275 | self.stub_helper_preamble_atom_index = atom_index; |
| 1245 | | 1276 | |
| 1246 | try self.managed_atoms.append(gpa, atom); | 1277 | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1247 | | | |
| 1248 | sym.n_value = try self.allocateAtom(atom, size, atom.alignment); | | |
| 1249 | log.debug("allocated stub preamble atom at 0x{x}", .{sym.n_value}); | 1278 | log.debug("allocated stub preamble atom at 0x{x}", .{sym.n_value}); |
| 1250 | try self.writeAtom(atom, code); | 1279 | try self.writeAtom(atom_index, code); |
| 1251 | } | 1280 | } |
| 1252 | | 1281 | |
| 1253 | pub fn createStubHelperAtom(self: *MachO) !*Atom { | 1282 | pub fn createStubHelperAtom(self: *MachO) !Atom.Index { |
| 1254 | const gpa = self.base.allocator; | 1283 | const gpa = self.base.allocator; |
| 1255 | const arch = self.base.options.target.cpu.arch; | 1284 | const arch = self.base.options.target.cpu.arch; |
| 1256 | const size: u4 = switch (arch) { | 1285 | const size: u4 = switch (arch) { |
| ... | @@ -1258,16 +1287,14 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -1258,16 +1287,14 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 1258 | .aarch64 => 3 * @sizeOf(u32), | 1287 | .aarch64 => 3 * @sizeOf(u32), |
| 1259 | else => unreachable, | 1288 | else => unreachable, |
| 1260 | }; | 1289 | }; |
| 1261 | const atom = try gpa.create(Atom); | 1290 | const atom_index = try self.createAtom(); |
| 1262 | atom.* = Atom.empty; | 1291 | const atom = self.getAtomPtr(atom_index); |
| 1263 | try atom.ensureInitialized(self); | | |
| 1264 | atom.size = size; | 1292 | atom.size = size; |
| 1265 | atom.alignment = switch (arch) { | 1293 | atom.alignment = switch (arch) { |
| 1266 | .x86_64 => 1, | 1294 | .x86_64 => 1, |
| 1267 | .aarch64 => @alignOf(u32), | 1295 | .aarch64 => @alignOf(u32), |
| 1268 | else => unreachable, | 1296 | else => unreachable, |
| 1269 | }; | 1297 | }; |
| 1270 | errdefer gpa.destroy(atom); | | |
| 1271 | | 1298 | |
| 1272 | const sym = atom.getSymbolPtr(self); | 1299 | const sym = atom.getSymbolPtr(self); |
| 1273 | sym.n_type = macho.N_SECT; | 1300 | sym.n_type = macho.N_SECT; |
| ... | @@ -1277,6 +1304,11 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -1277,6 +1304,11 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 1277 | defer gpa.free(code); | 1304 | defer gpa.free(code); |
| 1278 | mem.set(u8, code, 0); | 1305 | mem.set(u8, code, 0); |
| 1279 | | 1306 | |
| | 1307 | const stub_helper_preamble_atom_sym_index = if (self.stub_helper_preamble_atom_index) |stub_index| |
| | 1308 | self.getAtom(stub_index).getSymbolIndex().? |
| | 1309 | else |
| | 1310 | unreachable; |
| | 1311 | |
| 1280 | switch (arch) { | 1312 | switch (arch) { |
| 1281 | .x86_64 => { | 1313 | .x86_64 => { |
| 1282 | // pushq | 1314 | // pushq |
| ... | @@ -1285,9 +1317,9 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -1285,9 +1317,9 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 1285 | // jmpq | 1317 | // jmpq |
| 1286 | code[5] = 0xe9; | 1318 | code[5] = 0xe9; |
| 1287 | | 1319 | |
| 1288 | try atom.addRelocation(self, .{ | 1320 | try Atom.addRelocation(self, atom_index, .{ |
| 1289 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), | 1321 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), |
| 1290 | .target = .{ .sym_index = self.stub_helper_preamble_atom.?.getSymbolIndex().?, .file = null }, | 1322 | .target = .{ .sym_index = stub_helper_preamble_atom_sym_index, .file = null }, |
| 1291 | .offset = 6, | 1323 | .offset = 6, |
| 1292 | .addend = 0, | 1324 | .addend = 0, |
| 1293 | .pcrel = true, | 1325 | .pcrel = true, |
| ... | @@ -1308,9 +1340,9 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -1308,9 +1340,9 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 1308 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(0).toU32()); | 1340 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(0).toU32()); |
| 1309 | // Next 4 bytes 8..12 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`. | 1341 | // Next 4 bytes 8..12 are just a placeholder populated in `populateLazyBindOffsetsInStubHelper`. |
| 1310 | | 1342 | |
| 1311 | try atom.addRelocation(self, .{ | 1343 | try Atom.addRelocation(self, atom_index, .{ |
| 1312 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_BRANCH26), | 1344 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_BRANCH26), |
| 1313 | .target = .{ .sym_index = self.stub_helper_preamble_atom.?.getSymbolIndex().?, .file = null }, | 1345 | .target = .{ .sym_index = stub_helper_preamble_atom_sym_index, .file = null }, |
| 1314 | .offset = 4, | 1346 | .offset = 4, |
| 1315 | .addend = 0, | 1347 | .addend = 0, |
| 1316 | .pcrel = true, | 1348 | .pcrel = true, |
| ... | @@ -1320,29 +1352,24 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { | ... | @@ -1320,29 +1352,24 @@ pub fn createStubHelperAtom(self: *MachO) !*Atom { |
| 1320 | else => unreachable, | 1352 | else => unreachable, |
| 1321 | } | 1353 | } |
| 1322 | | 1354 | |
| 1323 | try self.managed_atoms.append(gpa, atom); | 1355 | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1324 | | | |
| 1325 | sym.n_value = try self.allocateAtom(atom, size, atom.alignment); | | |
| 1326 | log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value}); | 1356 | log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value}); |
| 1327 | try self.writeAtom(atom, code); | 1357 | try self.writeAtom(atom_index, code); |
| 1328 | | 1358 | |
| 1329 | return atom; | 1359 | return atom_index; |
| 1330 | } | 1360 | } |
| 1331 | | 1361 | |
| 1332 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !*Atom { | 1362 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index { |
| 1333 | const gpa = self.base.allocator; | 1363 | const atom_index = try self.createAtom(); |
| 1334 | const atom = try gpa.create(Atom); | 1364 | const atom = self.getAtomPtr(atom_index); |
| 1335 | atom.* = Atom.empty; | | |
| 1336 | try atom.ensureInitialized(self); | | |
| 1337 | atom.size = @sizeOf(u64); | 1365 | atom.size = @sizeOf(u64); |
| 1338 | atom.alignment = @alignOf(u64); | 1366 | atom.alignment = @alignOf(u64); |
| 1339 | errdefer gpa.destroy(atom); | | |
| 1340 | | 1367 | |
| 1341 | const sym = atom.getSymbolPtr(self); | 1368 | const sym = atom.getSymbolPtr(self); |
| 1342 | sym.n_type = macho.N_SECT; | 1369 | sym.n_type = macho.N_SECT; |
| 1343 | sym.n_sect = self.la_symbol_ptr_section_index.? + 1; | 1370 | sym.n_sect = self.la_symbol_ptr_section_index.? + 1; |
| 1344 | | 1371 | |
| 1345 | try atom.addRelocation(self, .{ | 1372 | try Atom.addRelocation(self, atom_index, .{ |
| 1346 | .type = switch (self.base.options.target.cpu.arch) { | 1373 | .type = switch (self.base.options.target.cpu.arch) { |
| 1347 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), | 1374 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), |
| 1348 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), | 1375 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), |
| ... | @@ -1354,22 +1381,20 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi | ... | @@ -1354,22 +1381,20 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi |
| 1354 | .pcrel = false, | 1381 | .pcrel = false, |
| 1355 | .length = 3, | 1382 | .length = 3, |
| 1356 | }); | 1383 | }); |
| 1357 | try atom.addRebase(self, 0); | 1384 | try Atom.addRebase(self, atom_index, 0); |
| 1358 | try atom.addLazyBinding(self, .{ | 1385 | try Atom.addLazyBinding(self, atom_index, .{ |
| 1359 | .target = self.getGlobal(self.getSymbolName(target)).?, | 1386 | .target = self.getGlobal(self.getSymbolName(target)).?, |
| 1360 | .offset = 0, | 1387 | .offset = 0, |
| 1361 | }); | 1388 | }); |
| 1362 | | 1389 | |
| 1363 | try self.managed_atoms.append(gpa, atom); | 1390 | sym.n_value = try self.allocateAtom(atom_index, atom.size, @alignOf(u64)); |
| 1364 | | | |
| 1365 | sym.n_value = try self.allocateAtom(atom, atom.size, @alignOf(u64)); | | |
| 1366 | log.debug("allocated lazy pointer atom at 0x{x} ({s})", .{ sym.n_value, self.getSymbolName(target) }); | 1391 | log.debug("allocated lazy pointer atom at 0x{x} ({s})", .{ sym.n_value, self.getSymbolName(target) }); |
| 1367 | try self.writePtrWidthAtom(atom); | 1392 | try self.writePtrWidthAtom(atom_index); |
| 1368 | | 1393 | |
| 1369 | return atom; | 1394 | return atom_index; |
| 1370 | } | 1395 | } |
| 1371 | | 1396 | |
| 1372 | pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | 1397 | pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { |
| 1373 | const gpa = self.base.allocator; | 1398 | const gpa = self.base.allocator; |
| 1374 | const arch = self.base.options.target.cpu.arch; | 1399 | const arch = self.base.options.target.cpu.arch; |
| 1375 | const size: u4 = switch (arch) { | 1400 | const size: u4 = switch (arch) { |
| ... | @@ -1377,9 +1402,8 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | ... | @@ -1377,9 +1402,8 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 1377 | .aarch64 => 3 * @sizeOf(u32), | 1402 | .aarch64 => 3 * @sizeOf(u32), |
| 1378 | else => unreachable, // unhandled architecture type | 1403 | else => unreachable, // unhandled architecture type |
| 1379 | }; | 1404 | }; |
| 1380 | const atom = try gpa.create(Atom); | 1405 | const atom_index = try self.createAtom(); |
| 1381 | atom.* = Atom.empty; | 1406 | const atom = self.getAtomPtr(atom_index); |
| 1382 | try atom.ensureInitialized(self); | | |
| 1383 | atom.size = size; | 1407 | atom.size = size; |
| 1384 | atom.alignment = switch (arch) { | 1408 | atom.alignment = switch (arch) { |
| 1385 | .x86_64 => 1, | 1409 | .x86_64 => 1, |
| ... | @@ -1387,7 +1411,6 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | ... | @@ -1387,7 +1411,6 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 1387 | else => unreachable, // unhandled architecture type | 1411 | else => unreachable, // unhandled architecture type |
| 1388 | | 1412 | |
| 1389 | }; | 1413 | }; |
| 1390 | errdefer gpa.destroy(atom); | | |
| 1391 | | 1414 | |
| 1392 | const sym = atom.getSymbolPtr(self); | 1415 | const sym = atom.getSymbolPtr(self); |
| 1393 | sym.n_type = macho.N_SECT; | 1416 | sym.n_type = macho.N_SECT; |
| ... | @@ -1403,7 +1426,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | ... | @@ -1403,7 +1426,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 1403 | code[0] = 0xff; | 1426 | code[0] = 0xff; |
| 1404 | code[1] = 0x25; | 1427 | code[1] = 0x25; |
| 1405 | | 1428 | |
| 1406 | try atom.addRelocation(self, .{ | 1429 | try Atom.addRelocation(self, atom_index, .{ |
| 1407 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), | 1430 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), |
| 1408 | .target = .{ .sym_index = laptr_sym_index, .file = null }, | 1431 | .target = .{ .sym_index = laptr_sym_index, .file = null }, |
| 1409 | .offset = 2, | 1432 | .offset = 2, |
| ... | @@ -1424,7 +1447,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | ... | @@ -1424,7 +1447,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 1424 | // br x16 | 1447 | // br x16 |
| 1425 | mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.br(.x16).toU32()); | 1448 | mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.br(.x16).toU32()); |
| 1426 | | 1449 | |
| 1427 | try atom.addRelocations(self, 2, .{ | 1450 | try Atom.addRelocations(self, atom_index, 2, .{ |
| 1428 | .{ | 1451 | .{ |
| 1429 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), | 1452 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), |
| 1430 | .target = .{ .sym_index = laptr_sym_index, .file = null }, | 1453 | .target = .{ .sym_index = laptr_sym_index, .file = null }, |
| ... | @@ -1446,13 +1469,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { | ... | @@ -1446,13 +1469,11 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !*Atom { |
| 1446 | else => unreachable, | 1469 | else => unreachable, |
| 1447 | } | 1470 | } |
| 1448 | | 1471 | |
| 1449 | try self.managed_atoms.append(gpa, atom); | 1472 | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1450 | | | |
| 1451 | sym.n_value = try self.allocateAtom(atom, size, atom.alignment); | | |
| 1452 | log.debug("allocated stub atom at 0x{x}", .{sym.n_value}); | 1473 | log.debug("allocated stub atom at 0x{x}", .{sym.n_value}); |
| 1453 | try self.writeAtom(atom, code); | 1474 | try self.writeAtom(atom_index, code); |
| 1454 | | 1475 | |
| 1455 | return atom; | 1476 | return atom_index; |
| 1456 | } | 1477 | } |
| 1457 | | 1478 | |
| 1458 | pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { | 1479 | pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { |
| ... | @@ -1586,9 +1607,12 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { | ... | @@ -1586,9 +1607,12 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 1586 | if (self.stubs_table.contains(global)) break :blk; | 1607 | if (self.stubs_table.contains(global)) break :blk; |
| 1587 | | 1608 | |
| 1588 | const stub_index = try self.allocateStubEntry(global); | 1609 | const stub_index = try self.allocateStubEntry(global); |
| 1589 | const stub_helper_atom = try self.createStubHelperAtom(); | 1610 | const stub_helper_atom_index = try self.createStubHelperAtom(); |
| 1590 | const laptr_atom = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, global); | 1611 | const stub_helper_atom = self.getAtom(stub_helper_atom_index); |
| 1591 | const stub_atom = try self.createStubAtom(laptr_atom.getSymbolIndex().?); | 1612 | const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, global); |
| | 1613 | const laptr_atom = self.getAtom(laptr_atom_index); |
| | 1614 | const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); |
| | 1615 | const stub_atom = self.getAtom(stub_atom_index); |
| 1592 | self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; | 1616 | self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; |
| 1593 | self.markRelocsDirtyByTarget(global); | 1617 | self.markRelocsDirtyByTarget(global); |
| 1594 | } | 1618 | } |
| ... | @@ -1686,10 +1710,11 @@ pub fn resolveDyldStubBinder(self: *MachO) !void { | ... | @@ -1686,10 +1710,11 @@ pub fn resolveDyldStubBinder(self: *MachO) !void { |
| 1686 | | 1710 | |
| 1687 | // Add dyld_stub_binder as the final GOT entry. | 1711 | // Add dyld_stub_binder as the final GOT entry. |
| 1688 | const got_index = try self.allocateGotEntry(global); | 1712 | const got_index = try self.allocateGotEntry(global); |
| 1689 | const got_atom = try self.createGotAtom(global); | 1713 | const got_atom_index = try self.createGotAtom(global); |
| | 1714 | const got_atom = self.getAtom(got_atom_index); |
| 1690 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | 1715 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; |
| 1691 | | 1716 | |
| 1692 | try self.writePtrWidthAtom(got_atom); | 1717 | try self.writePtrWidthAtom(got_atom_index); |
| 1693 | } | 1718 | } |
| 1694 | | 1719 | |
| 1695 | pub fn deinit(self: *MachO) void { | 1720 | pub fn deinit(self: *MachO) void { |
| ... | @@ -1699,9 +1724,9 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1699,9 +1724,9 @@ pub fn deinit(self: *MachO) void { |
| 1699 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); | 1724 | if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa); |
| 1700 | } | 1725 | } |
| 1701 | | 1726 | |
| 1702 | if (self.d_sym) |*d_sym| { | 1727 | // if (self.d_sym) |*d_sym| { |
| 1703 | d_sym.deinit(); | 1728 | // d_sym.deinit(); |
| 1704 | } | 1729 | // } |
| 1705 | | 1730 | |
| 1706 | self.got_entries.deinit(gpa); | 1731 | self.got_entries.deinit(gpa); |
| 1707 | self.got_entries_free_list.deinit(gpa); | 1732 | self.got_entries_free_list.deinit(gpa); |
| ... | @@ -1739,12 +1764,12 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1739,12 +1764,12 @@ pub fn deinit(self: *MachO) void { |
| 1739 | } | 1764 | } |
| 1740 | self.sections.deinit(gpa); | 1765 | self.sections.deinit(gpa); |
| 1741 | | 1766 | |
| 1742 | for (self.managed_atoms.items) |atom| { | 1767 | self.atoms.deinit(gpa); |
| 1743 | gpa.destroy(atom); | | |
| 1744 | } | | |
| 1745 | self.managed_atoms.deinit(gpa); | | |
| 1746 | | 1768 | |
| 1747 | if (self.base.options.module) |_| { | 1769 | if (self.base.options.module) |_| { |
| | 1770 | for (self.decls.values()) |*m| { |
| | 1771 | m.exports.deinit(gpa); |
| | 1772 | } |
| 1748 | self.decls.deinit(gpa); | 1773 | self.decls.deinit(gpa); |
| 1749 | } else { | 1774 | } else { |
| 1750 | assert(self.decls.count() == 0); | 1775 | assert(self.decls.count() == 0); |
| ... | @@ -1778,14 +1803,15 @@ pub fn deinit(self: *MachO) void { | ... | @@ -1778,14 +1803,15 @@ pub fn deinit(self: *MachO) void { |
| 1778 | self.lazy_bindings.deinit(gpa); | 1803 | self.lazy_bindings.deinit(gpa); |
| 1779 | } | 1804 | } |
| 1780 | | 1805 | |
| 1781 | fn freeAtom(self: *MachO, atom: *Atom) void { | 1806 | fn freeAtom(self: *MachO, atom_index: Atom.Index) void { |
| 1782 | log.debug("freeAtom {*}", .{atom}); | 1807 | log.debug("freeAtom {d}", .{atom_index}); |
| 1783 | | 1808 | |
| 1784 | const gpa = self.base.allocator; | 1809 | const gpa = self.base.allocator; |
| 1785 | | 1810 | |
| 1786 | // Remove any relocs and base relocs associated with this Atom | 1811 | // Remove any relocs and base relocs associated with this Atom |
| 1787 | self.freeRelocationsForAtom(atom); | 1812 | Atom.freeRelocations(self, atom_index); |
| 1788 | | 1813 | |
| | 1814 | const atom = self.getAtom(atom_index); |
| 1789 | const sect_id = atom.getSymbol(self).n_sect - 1; | 1815 | const sect_id = atom.getSymbol(self).n_sect - 1; |
| 1790 | const free_list = &self.sections.items(.free_list)[sect_id]; | 1816 | const free_list = &self.sections.items(.free_list)[sect_id]; |
| 1791 | var already_have_free_list_node = false; | 1817 | var already_have_free_list_node = false; |
| ... | @@ -1793,45 +1819,46 @@ fn freeAtom(self: *MachO, atom: *Atom) void { | ... | @@ -1793,45 +1819,46 @@ fn freeAtom(self: *MachO, atom: *Atom) void { |
| 1793 | var i: usize = 0; | 1819 | var i: usize = 0; |
| 1794 | // TODO turn free_list into a hash map | 1820 | // TODO turn free_list into a hash map |
| 1795 | while (i < free_list.items.len) { | 1821 | while (i < free_list.items.len) { |
| 1796 | if (free_list.items[i] == atom) { | 1822 | if (free_list.items[i] == atom_index) { |
| 1797 | _ = free_list.swapRemove(i); | 1823 | _ = free_list.swapRemove(i); |
| 1798 | continue; | 1824 | continue; |
| 1799 | } | 1825 | } |
| 1800 | if (free_list.items[i] == atom.prev) { | 1826 | if (free_list.items[i] == atom.prev_index) { |
| 1801 | already_have_free_list_node = true; | 1827 | already_have_free_list_node = true; |
| 1802 | } | 1828 | } |
| 1803 | i += 1; | 1829 | i += 1; |
| 1804 | } | 1830 | } |
| 1805 | } | 1831 | } |
| 1806 | | 1832 | |
| 1807 | const maybe_last_atom = &self.sections.items(.last_atom)[sect_id]; | 1833 | const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id]; |
| 1808 | if (maybe_last_atom.*) |last_atom| { | 1834 | if (maybe_last_atom_index.*) |last_atom_index| { |
| 1809 | if (last_atom == atom) { | 1835 | if (last_atom_index == atom_index) { |
| 1810 | if (atom.prev) |prev| { | 1836 | if (atom.prev_index) |prev_index| { |
| 1811 | // TODO shrink the section size here | 1837 | // TODO shrink the section size here |
| 1812 | maybe_last_atom.* = prev; | 1838 | maybe_last_atom_index.* = prev_index; |
| 1813 | } else { | 1839 | } else { |
| 1814 | maybe_last_atom.* = null; | 1840 | maybe_last_atom_index.* = null; |
| 1815 | } | 1841 | } |
| 1816 | } | 1842 | } |
| 1817 | } | 1843 | } |
| 1818 | | 1844 | |
| 1819 | if (atom.prev) |prev| { | 1845 | if (atom.prev_index) |prev_index| { |
| 1820 | prev.next = atom.next; | 1846 | const prev = self.getAtomPtr(prev_index); |
| | 1847 | prev.next_index = atom.next_index; |
| 1821 | | 1848 | |
| 1822 | if (!already_have_free_list_node and prev.freeListEligible(self)) { | 1849 | if (!already_have_free_list_node and prev.*.freeListEligible(self)) { |
| 1823 | // The free list is heuristics, it doesn't have to be perfect, so we can ignore | 1850 | // The free list is heuristics, it doesn't have to be perfect, so we can ignore |
| 1824 | // the OOM here. | 1851 | // the OOM here. |
| 1825 | free_list.append(gpa, prev) catch {}; | 1852 | free_list.append(gpa, prev_index) catch {}; |
| 1826 | } | 1853 | } |
| 1827 | } else { | 1854 | } else { |
| 1828 | atom.prev = null; | 1855 | self.getAtomPtr(atom_index).prev_index = null; |
| 1829 | } | 1856 | } |
| 1830 | | 1857 | |
| 1831 | if (atom.next) |next| { | 1858 | if (atom.next_index) |next_index| { |
| 1832 | next.prev = atom.prev; | 1859 | self.getAtomPtr(next_index).prev_index = atom.prev_index; |
| 1833 | } else { | 1860 | } else { |
| 1834 | atom.next = null; | 1861 | self.getAtomPtr(atom_index).next_index = null; |
| 1835 | } | 1862 | } |
| 1836 | | 1863 | |
| 1837 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. | 1864 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| ... | @@ -1849,9 +1876,9 @@ fn freeAtom(self: *MachO, atom: *Atom) void { | ... | @@ -1849,9 +1876,9 @@ fn freeAtom(self: *MachO, atom: *Atom) void { |
| 1849 | }; | 1876 | }; |
| 1850 | _ = self.got_entries_table.remove(got_target); | 1877 | _ = self.got_entries_table.remove(got_target); |
| 1851 | | 1878 | |
| 1852 | if (self.d_sym) |*d_sym| { | 1879 | // if (self.d_sym) |*d_sym| { |
| 1853 | d_sym.swapRemoveRelocs(sym_index); | 1880 | // d_sym.swapRemoveRelocs(sym_index); |
| 1854 | } | 1881 | // } |
| 1855 | | 1882 | |
| 1856 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index }); | 1883 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index }); |
| 1857 | } | 1884 | } |
| ... | @@ -1859,27 +1886,28 @@ fn freeAtom(self: *MachO, atom: *Atom) void { | ... | @@ -1859,27 +1886,28 @@ fn freeAtom(self: *MachO, atom: *Atom) void { |
| 1859 | self.locals.items[sym_index].n_type = 0; | 1886 | self.locals.items[sym_index].n_type = 0; |
| 1860 | _ = self.atom_by_index_table.remove(sym_index); | 1887 | _ = self.atom_by_index_table.remove(sym_index); |
| 1861 | log.debug(" adding local symbol index {d} to free list", .{sym_index}); | 1888 | log.debug(" adding local symbol index {d} to free list", .{sym_index}); |
| 1862 | atom.sym_index = 0; | 1889 | self.getAtomPtr(atom_index).sym_index = 0; |
| 1863 | | 1890 | |
| 1864 | if (self.d_sym) |*d_sym| { | 1891 | // if (self.d_sym) |*d_sym| { |
| 1865 | d_sym.dwarf.freeAtom(&atom.dbg_info_atom); | 1892 | // d_sym.dwarf.freeAtom(&atom.dbg_info_atom); |
| 1866 | } | 1893 | // } |
| 1867 | } | 1894 | } |
| 1868 | | 1895 | |
| 1869 | fn shrinkAtom(self: *MachO, atom: *Atom, new_block_size: u64) void { | 1896 | fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { |
| 1870 | _ = self; | 1897 | _ = self; |
| 1871 | _ = atom; | 1898 | _ = atom_index; |
| 1872 | _ = new_block_size; | 1899 | _ = new_block_size; |
| 1873 | // TODO check the new capacity, and if it crosses the size threshold into a big enough | 1900 | // TODO check the new capacity, and if it crosses the size threshold into a big enough |
| 1874 | // capacity, insert a free list node for it. | 1901 | // capacity, insert a free list node for it. |
| 1875 | } | 1902 | } |
| 1876 | | 1903 | |
| 1877 | fn growAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 { | 1904 | fn growAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment: u64) !u64 { |
| | 1905 | const atom = self.getAtom(atom_index); |
| 1878 | const sym = atom.getSymbol(self); | 1906 | const sym = atom.getSymbol(self); |
| 1879 | const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value; | 1907 | const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value; |
| 1880 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); | 1908 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); |
| 1881 | if (!need_realloc) return sym.n_value; | 1909 | if (!need_realloc) return sym.n_value; |
| 1882 | return self.allocateAtom(atom, new_atom_size, alignment); | 1910 | return self.allocateAtom(atom_index, new_atom_size, alignment); |
| 1883 | } | 1911 | } |
| 1884 | | 1912 | |
| 1885 | pub fn allocateSymbol(self: *MachO) !u32 { | 1913 | pub fn allocateSymbol(self: *MachO) !u32 { |
| ... | @@ -1986,31 +2014,29 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv | ... | @@ -1986,31 +2014,29 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv |
| 1986 | | 2014 | |
| 1987 | const decl_index = func.owner_decl; | 2015 | const decl_index = func.owner_decl; |
| 1988 | const decl = module.declPtr(decl_index); | 2016 | const decl = module.declPtr(decl_index); |
| 1989 | const atom = &decl.link.macho; | 2017 | |
| 1990 | try atom.ensureInitialized(self); | 2018 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1991 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 2019 | self.freeUnnamedConsts(decl_index); |
| 1992 | if (gop.found_existing) { | 2020 | Atom.freeRelocations(self, atom_index); |
| 1993 | self.freeUnnamedConsts(decl_index); | 2021 | |
| 1994 | self.freeRelocationsForAtom(atom); | 2022 | const atom = self.getAtom(atom_index); |
| 1995 | } else { | 2023 | _ = atom; |
| 1996 | gop.value_ptr.* = null; | | |
| 1997 | } | | |
| 1998 | | 2024 | |
| 1999 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 2025 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 2000 | defer code_buffer.deinit(); | 2026 | defer code_buffer.deinit(); |
| 2001 | | 2027 | |
| 2002 | var decl_state = if (self.d_sym) |*d_sym| | 2028 | // var decl_state = if (self.d_sym) |*d_sym| |
| 2003 | try d_sym.dwarf.initDeclState(module, decl_index) | 2029 | // try d_sym.dwarf.initDeclState(module, decl_index) |
| 2004 | else | 2030 | // else |
| 2005 | null; | 2031 | // null; |
| 2006 | defer if (decl_state) |*ds| ds.deinit(); | 2032 | // defer if (decl_state) |*ds| ds.deinit(); |
| 2007 | | 2033 | |
| 2008 | const res = if (decl_state) |*ds| | 2034 | // const res = if (decl_state) |*ds| |
| 2009 | try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{ | 2035 | // try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{ |
| 2010 | .dwarf = ds, | 2036 | // .dwarf = ds, |
| 2011 | }) | 2037 | // }) |
| 2012 | else | 2038 | // else |
| 2013 | try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none); | 2039 | const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none); |
| 2014 | | 2040 | |
| 2015 | const code = switch (res) { | 2041 | const code = switch (res) { |
| 2016 | .ok => code_buffer.items, | 2042 | .ok => code_buffer.items, |
| ... | @@ -2022,16 +2048,11 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv | ... | @@ -2022,16 +2048,11 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv |
| 2022 | }; | 2048 | }; |
| 2023 | | 2049 | |
| 2024 | const addr = try self.updateDeclCode(decl_index, code); | 2050 | const addr = try self.updateDeclCode(decl_index, code); |
| | 2051 | _ = addr; |
| 2025 | | 2052 | |
| 2026 | if (decl_state) |*ds| { | 2053 | // if (decl_state) |*ds| { |
| 2027 | try self.d_sym.?.dwarf.commitDeclState( | 2054 | // try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds); |
| 2028 | module, | 2055 | // } |
| 2029 | decl_index, | | |
| 2030 | addr, | | |
| 2031 | decl.link.macho.size, | | |
| 2032 | ds, | | |
| 2033 | ); | | |
| 2034 | } | | |
| 2035 | | 2056 | |
| 2036 | // Since we updated the vaddr and the size, each corresponding export symbol also | 2057 | // Since we updated the vaddr and the size, each corresponding export symbol also |
| 2037 | // needs to be updated. | 2058 | // needs to be updated. |
| ... | @@ -2065,11 +2086,8 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu | ... | @@ -2065,11 +2086,8 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2065 | | 2086 | |
| 2066 | log.debug("allocating symbol indexes for {?s}", .{name}); | 2087 | log.debug("allocating symbol indexes for {?s}", .{name}); |
| 2067 | | 2088 | |
| 2068 | const atom = try gpa.create(Atom); | 2089 | const atom_index = try self.createAtom(); |
| 2069 | errdefer gpa.destroy(atom); | 2090 | const atom = self.getAtomPtr(atom_index); |
| 2070 | atom.* = Atom.empty; | | |
| 2071 | try atom.ensureInitialized(self); | | |
| 2072 | try self.managed_atoms.append(gpa, atom); | | |
| 2073 | | 2091 | |
| 2074 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none, .{ | 2092 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), typed_value, &code_buffer, .none, .{ |
| 2075 | .parent_atom_index = atom.getSymbolIndex().?, | 2093 | .parent_atom_index = atom.getSymbolIndex().?, |
| ... | @@ -2088,21 +2106,21 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu | ... | @@ -2088,21 +2106,21 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2088 | atom.size = code.len; | 2106 | atom.size = code.len; |
| 2089 | atom.alignment = required_alignment; | 2107 | atom.alignment = required_alignment; |
| 2090 | // TODO: work out logic for disambiguating functions from function pointers | 2108 | // TODO: work out logic for disambiguating functions from function pointers |
| 2091 | // const sect_id = self.getDeclOutputSection(decl); | 2109 | // const sect_id = self.getDeclOutputSection(decl_index); |
| 2092 | const sect_id = self.data_const_section_index.?; | 2110 | const sect_id = self.data_const_section_index.?; |
| 2093 | const symbol = atom.getSymbolPtr(self); | 2111 | const symbol = atom.getSymbolPtr(self); |
| 2094 | symbol.n_strx = name_str_index; | 2112 | symbol.n_strx = name_str_index; |
| 2095 | symbol.n_type = macho.N_SECT; | 2113 | symbol.n_type = macho.N_SECT; |
| 2096 | symbol.n_sect = sect_id + 1; | 2114 | symbol.n_sect = sect_id + 1; |
| 2097 | symbol.n_value = try self.allocateAtom(atom, code.len, required_alignment); | 2115 | symbol.n_value = try self.allocateAtom(atom_index, code.len, required_alignment); |
| 2098 | errdefer self.freeAtom(atom); | 2116 | errdefer self.freeAtom(atom_index); |
| 2099 | | 2117 | |
| 2100 | try unnamed_consts.append(gpa, atom); | 2118 | try unnamed_consts.append(gpa, atom_index); |
| 2101 | | 2119 | |
| 2102 | log.debug("allocated atom for {?s} at 0x{x}", .{ name, symbol.n_value }); | 2120 | log.debug("allocated atom for {?s} at 0x{x}", .{ name, symbol.n_value }); |
| 2103 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 2121 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2104 | | 2122 | |
| 2105 | try self.writeAtom(atom, code); | 2123 | try self.writeAtom(atom_index, code); |
| 2106 | | 2124 | |
| 2107 | return atom.getSymbolIndex().?; | 2125 | return atom.getSymbolIndex().?; |
| 2108 | } | 2126 | } |
| ... | @@ -2129,41 +2147,36 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) | ... | @@ -2129,41 +2147,36 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) |
| 2129 | } | 2147 | } |
| 2130 | } | 2148 | } |
| 2131 | | 2149 | |
| 2132 | const atom = &decl.link.macho; | 2150 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2133 | try atom.ensureInitialized(self); | 2151 | Atom.freeRelocations(self, atom_index); |
| 2134 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 2152 | const atom = self.getAtom(atom_index); |
| 2135 | if (gop.found_existing) { | | |
| 2136 | self.freeRelocationsForAtom(atom); | | |
| 2137 | } else { | | |
| 2138 | gop.value_ptr.* = null; | | |
| 2139 | } | | |
| 2140 | | 2153 | |
| 2141 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 2154 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 2142 | defer code_buffer.deinit(); | 2155 | defer code_buffer.deinit(); |
| 2143 | | 2156 | |
| 2144 | var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym| | 2157 | // var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym| |
| 2145 | try d_sym.dwarf.initDeclState(module, decl_index) | 2158 | // try d_sym.dwarf.initDeclState(module, decl_index) |
| 2146 | else | 2159 | // else |
| 2147 | null; | 2160 | // null; |
| 2148 | defer if (decl_state) |*ds| ds.deinit(); | 2161 | // defer if (decl_state) |*ds| ds.deinit(); |
| 2149 | | 2162 | |
| 2150 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; | 2163 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| 2151 | const res = if (decl_state) |*ds| | 2164 | // const res = if (decl_state) |*ds| |
| 2152 | try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ | 2165 | // try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ |
| 2153 | .ty = decl.ty, | 2166 | // .ty = decl.ty, |
| 2154 | .val = decl_val, | 2167 | // .val = decl_val, |
| 2155 | }, &code_buffer, .{ | 2168 | // }, &code_buffer, .{ |
| 2156 | .dwarf = ds, | 2169 | // .dwarf = ds, |
| 2157 | }, .{ | 2170 | // }, .{ |
| 2158 | .parent_atom_index = decl.link.macho.getSymbolIndex().?, | 2171 | // .parent_atom_index = atom.getSymbolIndex().?, |
| 2159 | }) | 2172 | // }) |
| 2160 | else | 2173 | // else |
| 2161 | try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ | 2174 | const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{ |
| 2162 | .ty = decl.ty, | 2175 | .ty = decl.ty, |
| 2163 | .val = decl_val, | 2176 | .val = decl_val, |
| 2164 | }, &code_buffer, .none, .{ | 2177 | }, &code_buffer, .none, .{ |
| 2165 | .parent_atom_index = decl.link.macho.getSymbolIndex().?, | 2178 | .parent_atom_index = atom.getSymbolIndex().?, |
| 2166 | }); | 2179 | }); |
| 2167 | | 2180 | |
| 2168 | const code = switch (res) { | 2181 | const code = switch (res) { |
| 2169 | .ok => code_buffer.items, | 2182 | .ok => code_buffer.items, |
| ... | @@ -2174,23 +2187,31 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) | ... | @@ -2174,23 +2187,31 @@ pub fn updateDecl(self: *MachO, module: *Module, decl_index: Module.Decl.Index) |
| 2174 | }, | 2187 | }, |
| 2175 | }; | 2188 | }; |
| 2176 | const addr = try self.updateDeclCode(decl_index, code); | 2189 | const addr = try self.updateDeclCode(decl_index, code); |
| | 2190 | _ = addr; |
| 2177 | | 2191 | |
| 2178 | if (decl_state) |*ds| { | 2192 | // if (decl_state) |*ds| { |
| 2179 | try self.d_sym.?.dwarf.commitDeclState( | 2193 | // try self.d_sym.?.dwarf.commitDeclState(module, decl_index, addr, atom.size, ds); |
| 2180 | module, | 2194 | // } |
| 2181 | decl_index, | | |
| 2182 | addr, | | |
| 2183 | decl.link.macho.size, | | |
| 2184 | ds, | | |
| 2185 | ); | | |
| 2186 | } | | |
| 2187 | | 2195 | |
| 2188 | // Since we updated the vaddr and the size, each corresponding export symbol also | 2196 | // Since we updated the vaddr and the size, each corresponding export symbol also |
| 2189 | // needs to be updated. | 2197 | // needs to be updated. |
| 2190 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); | 2198 | try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 2191 | } | 2199 | } |
| 2192 | | 2200 | |
| 2193 | fn getDeclOutputSection(self: *MachO, decl: *Module.Decl) u8 { | 2201 | pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index { |
| | 2202 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| | 2203 | if (!gop.found_existing) { |
| | 2204 | gop.value_ptr.* = .{ |
| | 2205 | .atom = try self.createAtom(), |
| | 2206 | .section = self.getDeclOutputSection(decl_index), |
| | 2207 | .exports = .{}, |
| | 2208 | }; |
| | 2209 | } |
| | 2210 | return gop.value_ptr.atom; |
| | 2211 | } |
| | 2212 | |
| | 2213 | fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 { |
| | 2214 | const decl = self.base.options.module.?.declPtr(decl_index); |
| 2194 | const ty = decl.ty; | 2215 | const ty = decl.ty; |
| 2195 | const val = decl.val; | 2216 | const val = decl.val; |
| 2196 | const zig_ty = ty.zigTypeTag(); | 2217 | const zig_ty = ty.zigTypeTag(); |
| ... | @@ -2341,13 +2362,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) | ... | @@ -2341,13 +2362,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) |
| 2341 | const sym_name = try decl.getFullyQualifiedName(mod); | 2362 | const sym_name = try decl.getFullyQualifiedName(mod); |
| 2342 | defer self.base.allocator.free(sym_name); | 2363 | defer self.base.allocator.free(sym_name); |
| 2343 | | 2364 | |
| 2344 | const atom = &decl.link.macho; | 2365 | const decl_metadata = self.decls.get(decl_index).?; |
| 2345 | const sym_index = atom.getSymbolIndex().?; // Atom was not initialized | 2366 | const atom_index = decl_metadata.atom; |
| 2346 | const decl_ptr = self.decls.getPtr(decl_index).?; | 2367 | const atom = self.getAtom(atom_index); |
| 2347 | if (decl_ptr.* == null) { | 2368 | const sym_index = atom.getSymbolIndex().?; |
| 2348 | decl_ptr.* = self.getDeclOutputSection(decl); | 2369 | const sect_id = decl_metadata.section; |
| 2349 | } | | |
| 2350 | const sect_id = decl_ptr.*.?; | | |
| 2351 | const code_len = code.len; | 2370 | const code_len = code.len; |
| 2352 | | 2371 | |
| 2353 | if (atom.size != 0) { | 2372 | if (atom.size != 0) { |
| ... | @@ -2357,11 +2376,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) | ... | @@ -2357,11 +2376,11 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) |
| 2357 | sym.n_sect = sect_id + 1; | 2376 | sym.n_sect = sect_id + 1; |
| 2358 | sym.n_desc = 0; | 2377 | sym.n_desc = 0; |
| 2359 | | 2378 | |
| 2360 | const capacity = decl.link.macho.capacity(self); | 2379 | const capacity = atom.capacity(self); |
| 2361 | const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, sym.n_value, required_alignment); | 2380 | const need_realloc = code_len > capacity or !mem.isAlignedGeneric(u64, sym.n_value, required_alignment); |
| 2362 | | 2381 | |
| 2363 | if (need_realloc) { | 2382 | if (need_realloc) { |
| 2364 | const vaddr = try self.growAtom(atom, code_len, required_alignment); | 2383 | const vaddr = try self.growAtom(atom_index, code_len, required_alignment); |
| 2365 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, sym.n_value, vaddr }); | 2384 | log.debug("growing {s} and moving from 0x{x} to 0x{x}", .{ sym_name, sym.n_value, vaddr }); |
| 2366 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 2385 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2367 | | 2386 | |
| ... | @@ -2369,19 +2388,19 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) | ... | @@ -2369,19 +2388,19 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) |
| 2369 | sym.n_value = vaddr; | 2388 | sym.n_value = vaddr; |
| 2370 | log.debug(" (updating GOT entry)", .{}); | 2389 | log.debug(" (updating GOT entry)", .{}); |
| 2371 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2390 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 2372 | const got_atom = self.getGotAtomForSymbol(got_target).?; | 2391 | const got_atom_index = self.getGotAtomIndexForSymbol(got_target).?; |
| 2373 | self.markRelocsDirtyByTarget(got_target); | 2392 | self.markRelocsDirtyByTarget(got_target); |
| 2374 | try self.writePtrWidthAtom(got_atom); | 2393 | try self.writePtrWidthAtom(got_atom_index); |
| 2375 | } | 2394 | } |
| 2376 | } else if (code_len < atom.size) { | 2395 | } else if (code_len < atom.size) { |
| 2377 | self.shrinkAtom(atom, code_len); | 2396 | self.shrinkAtom(atom_index, code_len); |
| 2378 | } else if (atom.next == null) { | 2397 | } else if (atom.next_index == null) { |
| 2379 | const header = &self.sections.items(.header)[sect_id]; | 2398 | const header = &self.sections.items(.header)[sect_id]; |
| 2380 | const segment = self.getSegment(sect_id); | 2399 | const segment = self.getSegment(sect_id); |
| 2381 | const needed_size = (sym.n_value + code_len) - segment.vmaddr; | 2400 | const needed_size = (sym.n_value + code_len) - segment.vmaddr; |
| 2382 | header.size = needed_size; | 2401 | header.size = needed_size; |
| 2383 | } | 2402 | } |
| 2384 | atom.size = code_len; | 2403 | self.getAtomPtr(atom_index).size = code_len; |
| 2385 | } else { | 2404 | } else { |
| 2386 | const name_str_index = try self.strtab.insert(gpa, sym_name); | 2405 | const name_str_index = try self.strtab.insert(gpa, sym_name); |
| 2387 | const sym = atom.getSymbolPtr(self); | 2406 | const sym = atom.getSymbolPtr(self); |
| ... | @@ -2390,33 +2409,36 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) | ... | @@ -2390,33 +2409,36 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []const u8) |
| 2390 | sym.n_sect = sect_id + 1; | 2409 | sym.n_sect = sect_id + 1; |
| 2391 | sym.n_desc = 0; | 2410 | sym.n_desc = 0; |
| 2392 | | 2411 | |
| 2393 | const vaddr = try self.allocateAtom(atom, code_len, required_alignment); | 2412 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); |
| 2394 | errdefer self.freeAtom(atom); | 2413 | errdefer self.freeAtom(atom_index); |
| 2395 | | 2414 | |
| 2396 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, vaddr }); | 2415 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, vaddr }); |
| 2397 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 2416 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 2398 | | 2417 | |
| 2399 | atom.size = code_len; | 2418 | self.getAtomPtr(atom_index).size = code_len; |
| 2400 | sym.n_value = vaddr; | 2419 | sym.n_value = vaddr; |
| 2401 | | 2420 | |
| 2402 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2421 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 2403 | const got_index = try self.allocateGotEntry(got_target); | 2422 | const got_index = try self.allocateGotEntry(got_target); |
| 2404 | const got_atom = try self.createGotAtom(got_target); | 2423 | const got_atom_index = try self.createGotAtom(got_target); |
| | 2424 | const got_atom = self.getAtom(got_atom_index); |
| 2405 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | 2425 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; |
| 2406 | try self.writePtrWidthAtom(got_atom); | 2426 | try self.writePtrWidthAtom(got_atom_index); |
| 2407 | } | 2427 | } |
| 2408 | | 2428 | |
| 2409 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); | 2429 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); |
| 2410 | try self.writeAtom(atom, code); | 2430 | try self.writeAtom(atom_index, code); |
| 2411 | | 2431 | |
| 2412 | return atom.getSymbol(self).n_value; | 2432 | return atom.getSymbol(self).n_value; |
| 2413 | } | 2433 | } |
| 2414 | | 2434 | |
| 2415 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void { | 2435 | pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void { |
| | 2436 | _ = decl; |
| | 2437 | _ = self; |
| 2416 | _ = module; | 2438 | _ = module; |
| 2417 | if (self.d_sym) |*d_sym| { | 2439 | // if (self.d_sym) |*d_sym| { |
| 2418 | try d_sym.dwarf.updateDeclLineNumber(decl); | 2440 | // try d_sym.dwarf.updateDeclLineNumber(decl); |
| 2419 | } | 2441 | // } |
| 2420 | } | 2442 | } |
| 2421 | | 2443 | |
| 2422 | pub fn updateDeclExports( | 2444 | pub fn updateDeclExports( |
| ... | @@ -2432,22 +2454,17 @@ pub fn updateDeclExports( | ... | @@ -2432,22 +2454,17 @@ pub fn updateDeclExports( |
| 2432 | if (self.llvm_object) |llvm_object| | 2454 | if (self.llvm_object) |llvm_object| |
| 2433 | return llvm_object.updateDeclExports(module, decl_index, exports); | 2455 | return llvm_object.updateDeclExports(module, decl_index, exports); |
| 2434 | } | 2456 | } |
| | 2457 | |
| 2435 | const tracy = trace(@src()); | 2458 | const tracy = trace(@src()); |
| 2436 | defer tracy.end(); | 2459 | defer tracy.end(); |
| 2437 | | 2460 | |
| 2438 | const gpa = self.base.allocator; | 2461 | const gpa = self.base.allocator; |
| 2439 | | 2462 | |
| 2440 | const decl = module.declPtr(decl_index); | 2463 | const decl = module.declPtr(decl_index); |
| 2441 | const atom = &decl.link.macho; | 2464 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2442 | | 2465 | const atom = self.getAtom(atom_index); |
| 2443 | if (atom.getSymbolIndex() == null) return; | | |
| 2444 | | | |
| 2445 | const gop = try self.decls.getOrPut(gpa, decl_index); | | |
| 2446 | if (!gop.found_existing) { | | |
| 2447 | gop.value_ptr.* = self.getDeclOutputSection(decl); | | |
| 2448 | } | | |
| 2449 | | | |
| 2450 | const decl_sym = atom.getSymbol(self); | 2466 | const decl_sym = atom.getSymbol(self); |
| | 2467 | const decl_metadata = self.decls.getPtr(decl_index).?; |
| 2451 | | 2468 | |
| 2452 | for (exports) |exp| { | 2469 | for (exports) |exp| { |
| 2453 | const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{exp.options.name}); | 2470 | const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{exp.options.name}); |
| ... | @@ -2485,9 +2502,9 @@ pub fn updateDeclExports( | ... | @@ -2485,9 +2502,9 @@ pub fn updateDeclExports( |
| 2485 | continue; | 2502 | continue; |
| 2486 | } | 2503 | } |
| 2487 | | 2504 | |
| 2488 | const sym_index = exp.link.macho.sym_index orelse blk: { | 2505 | const sym_index = decl_metadata.getExport(self, exp_name) orelse blk: { |
| 2489 | const sym_index = try self.allocateSymbol(); | 2506 | const sym_index = try self.allocateSymbol(); |
| 2490 | exp.link.macho.sym_index = sym_index; | 2507 | try decl_metadata.exports.append(gpa, sym_index); |
| 2491 | break :blk sym_index; | 2508 | break :blk sym_index; |
| 2492 | }; | 2509 | }; |
| 2493 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2510 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| ... | @@ -2535,16 +2552,18 @@ pub fn updateDeclExports( | ... | @@ -2535,16 +2552,18 @@ pub fn updateDeclExports( |
| 2535 | } | 2552 | } |
| 2536 | } | 2553 | } |
| 2537 | | 2554 | |
| 2538 | pub fn deleteExport(self: *MachO, exp: Export) void { | 2555 | pub fn deleteDeclExport(self: *MachO, decl_index: Module.Decl.Index, name: []const u8) Allocator.Error!void { |
| 2539 | if (self.llvm_object) |_| return; | 2556 | if (self.llvm_object) |_| return; |
| 2540 | const sym_index = exp.sym_index orelse return; | 2557 | const metadata = self.decls.getPtr(decl_index) orelse return; |
| 2541 | | 2558 | |
| 2542 | const gpa = self.base.allocator; | 2559 | const gpa = self.base.allocator; |
| | 2560 | const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); |
| | 2561 | defer gpa.free(exp_name); |
| | 2562 | const sym_index = metadata.getExportPtr(self, exp_name) orelse return; |
| 2543 | | 2563 | |
| 2544 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2564 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null }; |
| 2545 | const sym = self.getSymbolPtr(sym_loc); | 2565 | const sym = self.getSymbolPtr(sym_loc); |
| 2546 | const sym_name = self.getSymbolName(sym_loc); | 2566 | log.debug("deleting export '{s}'", .{exp_name}); |
| 2547 | log.debug("deleting export '{s}'", .{sym_name}); | | |
| 2548 | assert(sym.sect() and sym.ext()); | 2567 | assert(sym.sect() and sym.ext()); |
| 2549 | sym.* = .{ | 2568 | sym.* = .{ |
| 2550 | .n_strx = 0, | 2569 | .n_strx = 0, |
| ... | @@ -2553,9 +2572,9 @@ pub fn deleteExport(self: *MachO, exp: Export) void { | ... | @@ -2553,9 +2572,9 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 2553 | .n_desc = 0, | 2572 | .n_desc = 0, |
| 2554 | .n_value = 0, | 2573 | .n_value = 0, |
| 2555 | }; | 2574 | }; |
| 2556 | self.locals_free_list.append(gpa, sym_index) catch {}; | 2575 | self.locals_free_list.append(gpa, sym_index.*) catch {}; |
| 2557 | | 2576 | |
| 2558 | if (self.resolver.fetchRemove(sym_name)) |entry| { | 2577 | if (self.resolver.fetchRemove(exp_name)) |entry| { |
| 2559 | defer gpa.free(entry.key); | 2578 | defer gpa.free(entry.key); |
| 2560 | self.globals_free_list.append(gpa, entry.value) catch {}; | 2579 | self.globals_free_list.append(gpa, entry.value) catch {}; |
| 2561 | self.globals.items[entry.value] = .{ | 2580 | self.globals.items[entry.value] = .{ |
| ... | @@ -2563,17 +2582,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void { | ... | @@ -2563,17 +2582,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 2563 | .file = null, | 2582 | .file = null, |
| 2564 | }; | 2583 | }; |
| 2565 | } | 2584 | } |
| 2566 | } | | |
| 2567 | | 2585 | |
| 2568 | fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void { | 2586 | sym_index.* = 0; |
| 2569 | var removed_relocs = self.relocs.fetchOrderedRemove(atom); | | |
| 2570 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); | | |
| 2571 | var removed_rebases = self.rebases.fetchOrderedRemove(atom); | | |
| 2572 | if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator); | | |
| 2573 | var removed_bindings = self.bindings.fetchOrderedRemove(atom); | | |
| 2574 | if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator); | | |
| 2575 | var removed_lazy_bindings = self.lazy_bindings.fetchOrderedRemove(atom); | | |
| 2576 | if (removed_lazy_bindings) |*lazy_bindings| lazy_bindings.value.deinit(self.base.allocator); | | |
| 2577 | } | 2587 | } |
| 2578 | | 2588 | |
| 2579 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { | 2589 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { |
| ... | @@ -2595,28 +2605,22 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void { | ... | @@ -2595,28 +2605,22 @@ pub fn freeDecl(self: *MachO, decl_index: Module.Decl.Index) void { |
| 2595 | log.debug("freeDecl {*}", .{decl}); | 2605 | log.debug("freeDecl {*}", .{decl}); |
| 2596 | | 2606 | |
| 2597 | if (self.decls.fetchSwapRemove(decl_index)) |kv| { | 2607 | if (self.decls.fetchSwapRemove(decl_index)) |kv| { |
| 2598 | if (kv.value) |_| { | 2608 | self.freeAtom(kv.value.atom); |
| 2599 | self.freeAtom(&decl.link.macho); | 2609 | self.freeUnnamedConsts(decl_index); |
| 2600 | self.freeUnnamedConsts(decl_index); | | |
| 2601 | } | | |
| 2602 | } | 2610 | } |
| 2603 | | 2611 | |
| 2604 | if (self.d_sym) |*d_sym| { | 2612 | // if (self.d_sym) |*d_sym| { |
| 2605 | d_sym.dwarf.freeDecl(decl); | 2613 | // d_sym.dwarf.freeDecl(decl); |
| 2606 | } | 2614 | // } |
| 2607 | } | 2615 | } |
| 2608 | | 2616 | |
| 2609 | pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 { | 2617 | pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: File.RelocInfo) !u64 { |
| 2610 | const mod = self.base.options.module.?; | | |
| 2611 | const decl = mod.declPtr(decl_index); | | |
| 2612 | | | |
| 2613 | assert(self.llvm_object == null); | 2618 | assert(self.llvm_object == null); |
| 2614 | | 2619 | |
| 2615 | try decl.link.macho.ensureInitialized(self); | 2620 | const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 2616 | const sym_index = decl.link.macho.getSymbolIndex().?; | 2621 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; |
| 2617 | | 2622 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; |
| 2618 | const atom = self.getAtomForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; | 2623 | try Atom.addRelocation(self, atom_index, .{ |
| 2619 | try atom.addRelocation(self, .{ | | |
| 2620 | .type = switch (self.base.options.target.cpu.arch) { | 2624 | .type = switch (self.base.options.target.cpu.arch) { |
| 2621 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), | 2625 | .aarch64 => @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_UNSIGNED), |
| 2622 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), | 2626 | .x86_64 => @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_UNSIGNED), |
| ... | @@ -2628,7 +2632,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil | ... | @@ -2628,7 +2632,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2628 | .pcrel = false, | 2632 | .pcrel = false, |
| 2629 | .length = 3, | 2633 | .length = 3, |
| 2630 | }); | 2634 | }); |
| 2631 | try atom.addRebase(self, @intCast(u32, reloc_info.offset)); | 2635 | try Atom.addRebase(self, atom_index, @intCast(u32, reloc_info.offset)); |
| 2632 | | 2636 | |
| 2633 | return 0; | 2637 | return 0; |
| 2634 | } | 2638 | } |
| ... | @@ -2860,34 +2864,36 @@ fn moveSectionInVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void | ... | @@ -2860,34 +2864,36 @@ fn moveSectionInVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void |
| 2860 | // TODO: enforce order by increasing VM addresses in self.sections container. | 2864 | // TODO: enforce order by increasing VM addresses in self.sections container. |
| 2861 | for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| { | 2865 | for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| { |
| 2862 | const index = @intCast(u8, sect_id + 1 + next_sect_id); | 2866 | const index = @intCast(u8, sect_id + 1 + next_sect_id); |
| 2863 | const maybe_last_atom = &self.sections.items(.last_atom)[index]; | | |
| 2864 | const next_segment = self.getSegmentPtr(index); | 2867 | const next_segment = self.getSegmentPtr(index); |
| 2865 | next_header.addr += diff; | 2868 | next_header.addr += diff; |
| 2866 | next_segment.vmaddr += diff; | 2869 | next_segment.vmaddr += diff; |
| 2867 | | 2870 | |
| 2868 | if (maybe_last_atom.*) |last_atom| { | 2871 | const maybe_last_atom_index = &self.sections.items(.last_atom_index)[index]; |
| 2869 | var atom = last_atom; | 2872 | if (maybe_last_atom_index.*) |last_atom_index| { |
| | 2873 | var atom_index = last_atom_index; |
| 2870 | while (true) { | 2874 | while (true) { |
| | 2875 | const atom = self.getAtom(atom_index); |
| 2871 | const sym = atom.getSymbolPtr(self); | 2876 | const sym = atom.getSymbolPtr(self); |
| 2872 | sym.n_value += diff; | 2877 | sym.n_value += diff; |
| 2873 | | 2878 | |
| 2874 | if (atom.prev) |prev| { | 2879 | if (atom.prev_index) |prev_index| { |
| 2875 | atom = prev; | 2880 | atom_index = prev_index; |
| 2876 | } else break; | 2881 | } else break; |
| 2877 | } | 2882 | } |
| 2878 | } | 2883 | } |
| 2879 | } | 2884 | } |
| 2880 | } | 2885 | } |
| 2881 | | 2886 | |
| 2882 | fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 { | 2887 | fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment: u64) !u64 { |
| 2883 | const tracy = trace(@src()); | 2888 | const tracy = trace(@src()); |
| 2884 | defer tracy.end(); | 2889 | defer tracy.end(); |
| 2885 | | 2890 | |
| | 2891 | const atom = self.getAtom(atom_index); |
| 2886 | const sect_id = atom.getSymbol(self).n_sect - 1; | 2892 | const sect_id = atom.getSymbol(self).n_sect - 1; |
| 2887 | const segment = self.getSegmentPtr(sect_id); | 2893 | const segment = self.getSegmentPtr(sect_id); |
| 2888 | const header = &self.sections.items(.header)[sect_id]; | 2894 | const header = &self.sections.items(.header)[sect_id]; |
| 2889 | const free_list = &self.sections.items(.free_list)[sect_id]; | 2895 | const free_list = &self.sections.items(.free_list)[sect_id]; |
| 2890 | const maybe_last_atom = &self.sections.items(.last_atom)[sect_id]; | 2896 | const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id]; |
| 2891 | const requires_padding = blk: { | 2897 | const requires_padding = blk: { |
| 2892 | if (!header.isCode()) break :blk false; | 2898 | if (!header.isCode()) break :blk false; |
| 2893 | if (header.isSymbolStubs()) break :blk false; | 2899 | if (header.isSymbolStubs()) break :blk false; |
| ... | @@ -2901,7 +2907,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -2901,7 +2907,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 2901 | // It would be simpler to do it inside the for loop below, but that would cause a | 2907 | // It would be simpler to do it inside the for loop below, but that would cause a |
| 2902 | // problem if an error was returned later in the function. So this action | 2908 | // problem if an error was returned later in the function. So this action |
| 2903 | // is actually carried out at the end of the function, when errors are no longer possible. | 2909 | // is actually carried out at the end of the function, when errors are no longer possible. |
| 2904 | var atom_placement: ?*Atom = null; | 2910 | var atom_placement: ?Atom.Index = null; |
| 2905 | var free_list_removal: ?usize = null; | 2911 | var free_list_removal: ?usize = null; |
| 2906 | | 2912 | |
| 2907 | // First we look for an appropriately sized free list node. | 2913 | // First we look for an appropriately sized free list node. |
| ... | @@ -2909,7 +2915,8 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -2909,7 +2915,8 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 2909 | var vaddr = blk: { | 2915 | var vaddr = blk: { |
| 2910 | var i: usize = 0; | 2916 | var i: usize = 0; |
| 2911 | while (i < free_list.items.len) { | 2917 | while (i < free_list.items.len) { |
| 2912 | const big_atom = free_list.items[i]; | 2918 | const big_atom_index = free_list.items[i]; |
| | 2919 | const big_atom = self.getAtom(big_atom_index); |
| 2913 | // We now have a pointer to a live atom that has too much capacity. | 2920 | // We now have a pointer to a live atom that has too much capacity. |
| 2914 | // Is it enough that we could fit this new atom? | 2921 | // Is it enough that we could fit this new atom? |
| 2915 | const sym = big_atom.getSymbol(self); | 2922 | const sym = big_atom.getSymbol(self); |
| ... | @@ -2937,30 +2944,35 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -2937,30 +2944,35 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 2937 | const keep_free_list_node = remaining_capacity >= min_text_capacity; | 2944 | const keep_free_list_node = remaining_capacity >= min_text_capacity; |
| 2938 | | 2945 | |
| 2939 | // Set up the metadata to be updated, after errors are no longer possible. | 2946 | // Set up the metadata to be updated, after errors are no longer possible. |
| 2940 | atom_placement = big_atom; | 2947 | atom_placement = big_atom_index; |
| 2941 | if (!keep_free_list_node) { | 2948 | if (!keep_free_list_node) { |
| 2942 | free_list_removal = i; | 2949 | free_list_removal = i; |
| 2943 | } | 2950 | } |
| 2944 | break :blk new_start_vaddr; | 2951 | break :blk new_start_vaddr; |
| 2945 | } else if (maybe_last_atom.*) |last| { | 2952 | } else if (maybe_last_atom_index.*) |last_index| { |
| | 2953 | const last = self.getAtom(last_index); |
| 2946 | const last_symbol = last.getSymbol(self); | 2954 | const last_symbol = last.getSymbol(self); |
| 2947 | const ideal_capacity = if (requires_padding) padToIdeal(last.size) else last.size; | 2955 | const ideal_capacity = if (requires_padding) padToIdeal(last.size) else last.size; |
| 2948 | const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity; | 2956 | const ideal_capacity_end_vaddr = last_symbol.n_value + ideal_capacity; |
| 2949 | const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); | 2957 | const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, alignment); |
| 2950 | atom_placement = last; | 2958 | atom_placement = last_index; |
| 2951 | break :blk new_start_vaddr; | 2959 | break :blk new_start_vaddr; |
| 2952 | } else { | 2960 | } else { |
| 2953 | break :blk mem.alignForwardGeneric(u64, segment.vmaddr, alignment); | 2961 | break :blk mem.alignForwardGeneric(u64, segment.vmaddr, alignment); |
| 2954 | } | 2962 | } |
| 2955 | }; | 2963 | }; |
| 2956 | | 2964 | |
| 2957 | const expand_section = atom_placement == null or atom_placement.?.next == null; | 2965 | const expand_section = if (atom_placement) |placement_index| |
| | 2966 | self.getAtom(placement_index).next_index == null |
| | 2967 | else |
| | 2968 | true; |
| 2958 | if (expand_section) { | 2969 | if (expand_section) { |
| 2959 | const sect_capacity = self.allocatedSize(header.offset); | 2970 | const sect_capacity = self.allocatedSize(header.offset); |
| 2960 | const needed_size = (vaddr + new_atom_size) - segment.vmaddr; | 2971 | const needed_size = (vaddr + new_atom_size) - segment.vmaddr; |
| 2961 | if (needed_size > sect_capacity) { | 2972 | if (needed_size > sect_capacity) { |
| 2962 | const new_offset = self.findFreeSpace(needed_size, self.page_size); | 2973 | const new_offset = self.findFreeSpace(needed_size, self.page_size); |
| 2963 | const current_size = if (maybe_last_atom.*) |last_atom| blk: { | 2974 | const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { |
| | 2975 | const last_atom = self.getAtom(last_atom_index); |
| 2964 | const sym = last_atom.getSymbol(self); | 2976 | const sym = last_atom.getSymbol(self); |
| 2965 | break :blk (sym.n_value + last_atom.size) - segment.vmaddr; | 2977 | break :blk (sym.n_value + last_atom.size) - segment.vmaddr; |
| 2966 | } else 0; | 2978 | } else 0; |
| ... | @@ -2992,7 +3004,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -2992,7 +3004,7 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 2992 | header.size = needed_size; | 3004 | header.size = needed_size; |
| 2993 | segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); | 3005 | segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| 2994 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); | 3006 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| 2995 | maybe_last_atom.* = atom; | 3007 | maybe_last_atom_index.* = atom_index; |
| 2996 | | 3008 | |
| 2997 | self.segment_table_dirty = true; | 3009 | self.segment_table_dirty = true; |
| 2998 | } | 3010 | } |
| ... | @@ -3002,20 +3014,25 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -3002,20 +3014,25 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 3002 | header.@"align" = align_pow; | 3014 | header.@"align" = align_pow; |
| 3003 | } | 3015 | } |
| 3004 | | 3016 | |
| 3005 | if (atom.prev) |prev| { | 3017 | if (atom.prev_index) |prev_index| { |
| 3006 | prev.next = atom.next; | 3018 | const prev = self.getAtomPtr(prev_index); |
| | 3019 | prev.next_index = atom.next_index; |
| 3007 | } | 3020 | } |
| 3008 | if (atom.next) |next| { | 3021 | if (atom.next_index) |next_index| { |
| 3009 | next.prev = atom.prev; | 3022 | const next = self.getAtomPtr(next_index); |
| | 3023 | next.prev_index = atom.prev_index; |
| 3010 | } | 3024 | } |
| 3011 | | 3025 | |
| 3012 | if (atom_placement) |big_atom| { | 3026 | if (atom_placement) |big_atom_index| { |
| 3013 | atom.prev = big_atom; | 3027 | const big_atom = self.getAtomPtr(big_atom_index); |
| 3014 | atom.next = big_atom.next; | 3028 | const atom_ptr = self.getAtomPtr(atom_index); |
| 3015 | big_atom.next = atom; | 3029 | atom_ptr.prev_index = big_atom_index; |
| | 3030 | atom_ptr.next_index = big_atom.next_index; |
| | 3031 | big_atom.next_index = atom_index; |
| 3016 | } else { | 3032 | } else { |
| 3017 | atom.prev = null; | 3033 | const atom_ptr = self.getAtomPtr(atom_index); |
| 3018 | atom.next = null; | 3034 | atom_ptr.prev_index = null; |
| | 3035 | atom_ptr.next_index = null; |
| 3019 | } | 3036 | } |
| 3020 | if (free_list_removal) |i| { | 3037 | if (free_list_removal) |i| { |
| 3021 | _ = free_list.swapRemove(i); | 3038 | _ = free_list.swapRemove(i); |
| ... | @@ -3155,7 +3172,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { | ... | @@ -3155,7 +3172,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3155 | const gpa = self.base.allocator; | 3172 | const gpa = self.base.allocator; |
| 3156 | const slice = self.sections.slice(); | 3173 | const slice = self.sections.slice(); |
| 3157 | | 3174 | |
| 3158 | for (self.rebases.keys()) |atom, i| { | 3175 | for (self.rebases.keys()) |atom_index, i| { |
| | 3176 | const atom = self.getAtom(atom_index); |
| 3159 | log.debug(" ATOM(%{?d}, '{s}')", .{ atom.getSymbolIndex(), atom.getName(self) }); | 3177 | log.debug(" ATOM(%{?d}, '{s}')", .{ atom.getSymbolIndex(), atom.getName(self) }); |
| 3160 | | 3178 | |
| 3161 | const sym = atom.getSymbol(self); | 3179 | const sym = atom.getSymbol(self); |
| ... | @@ -3184,7 +3202,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { | ... | @@ -3184,7 +3202,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3184 | const gpa = self.base.allocator; | 3202 | const gpa = self.base.allocator; |
| 3185 | const slice = self.sections.slice(); | 3203 | const slice = self.sections.slice(); |
| 3186 | | 3204 | |
| 3187 | for (raw_bindings.keys()) |atom, i| { | 3205 | for (raw_bindings.keys()) |atom_index, i| { |
| | 3206 | const atom = self.getAtom(atom_index); |
| 3188 | log.debug(" ATOM(%{?d}, '{s}')", .{ atom.getSymbolIndex(), atom.getName(self) }); | 3207 | log.debug(" ATOM(%{?d}, '{s}')", .{ atom.getSymbolIndex(), atom.getName(self) }); |
| 3189 | | 3208 | |
| 3190 | const sym = atom.getSymbol(self); | 3209 | const sym = atom.getSymbol(self); |
| ... | @@ -3359,7 +3378,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void | ... | @@ -3359,7 +3378,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void |
| 3359 | if (lazy_bind.size() == 0) return; | 3378 | if (lazy_bind.size() == 0) return; |
| 3360 | | 3379 | |
| 3361 | const stub_helper_section_index = self.stub_helper_section_index.?; | 3380 | const stub_helper_section_index = self.stub_helper_section_index.?; |
| 3362 | assert(self.stub_helper_preamble_atom != null); | 3381 | assert(self.stub_helper_preamble_atom_index != null); |
| 3363 | | 3382 | |
| 3364 | const section = self.sections.get(stub_helper_section_index); | 3383 | const section = self.sections.get(stub_helper_section_index); |
| 3365 | | 3384 | |
| ... | @@ -3369,10 +3388,11 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void | ... | @@ -3369,10 +3388,11 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void |
| 3369 | else => unreachable, | 3388 | else => unreachable, |
| 3370 | }; | 3389 | }; |
| 3371 | const header = section.header; | 3390 | const header = section.header; |
| 3372 | var atom = section.last_atom.?; | 3391 | var atom_index = section.last_atom_index.?; |
| 3373 | | 3392 | |
| 3374 | var index: usize = lazy_bind.offsets.items.len; | 3393 | var index: usize = lazy_bind.offsets.items.len; |
| 3375 | while (index > 0) : (index -= 1) { | 3394 | while (index > 0) : (index -= 1) { |
| | 3395 | const atom = self.getAtom(atom_index); |
| 3376 | const sym = atom.getSymbol(self); | 3396 | const sym = atom.getSymbol(self); |
| 3377 | const file_offset = header.offset + sym.n_value - header.addr + stub_offset; | 3397 | const file_offset = header.offset + sym.n_value - header.addr + stub_offset; |
| 3378 | const bind_offset = lazy_bind.offsets.items[index - 1]; | 3398 | const bind_offset = lazy_bind.offsets.items[index - 1]; |
| ... | @@ -3385,7 +3405,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void | ... | @@ -3385,7 +3405,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: LazyBind) !void |
| 3385 | | 3405 | |
| 3386 | try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset); | 3406 | try self.base.file.?.pwriteAll(mem.asBytes(&bind_offset), file_offset); |
| 3387 | | 3407 | |
| 3388 | atom = atom.prev.?; | 3408 | atom_index = atom.prev_index.?; |
| 3389 | } | 3409 | } |
| 3390 | } | 3410 | } |
| 3391 | | 3411 | |
| ... | @@ -3828,25 +3848,35 @@ pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResul | ... | @@ -3828,25 +3848,35 @@ pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResul |
| 3828 | return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; | 3848 | return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; |
| 3829 | } | 3849 | } |
| 3830 | | 3850 | |
| | 3851 | pub fn getAtom(self: *MachO, atom_index: Atom.Index) Atom { |
| | 3852 | assert(atom_index < self.atoms.items.len); |
| | 3853 | return self.atoms.items[atom_index]; |
| | 3854 | } |
| | 3855 | |
| | 3856 | pub fn getAtomPtr(self: *MachO, atom_index: Atom.Index) *Atom { |
| | 3857 | assert(atom_index < self.atoms.items.len); |
| | 3858 | return &self.atoms.items[atom_index]; |
| | 3859 | } |
| | 3860 | |
| 3831 | /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. | 3861 | /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. |
| 3832 | /// Returns null on failure. | 3862 | /// Returns null on failure. |
| 3833 | pub fn getAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 3863 | pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index { |
| 3834 | assert(sym_with_loc.file == null); | 3864 | assert(sym_with_loc.file == null); |
| 3835 | return self.atom_by_index_table.get(sym_with_loc.sym_index); | 3865 | return self.atom_by_index_table.get(sym_with_loc.sym_index); |
| 3836 | } | 3866 | } |
| 3837 | | 3867 | |
| 3838 | /// Returns GOT atom that references `sym_with_loc` if one exists. | 3868 | /// Returns GOT atom that references `sym_with_loc` if one exists. |
| 3839 | /// Returns null otherwise. | 3869 | /// Returns null otherwise. |
| 3840 | pub fn getGotAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 3870 | pub fn getGotAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index { |
| 3841 | const got_index = self.got_entries_table.get(sym_with_loc) orelse return null; | 3871 | const got_index = self.got_entries_table.get(sym_with_loc) orelse return null; |
| 3842 | return self.got_entries.items[got_index].getAtom(self); | 3872 | return self.got_entries.items[got_index].getAtomIndex(self); |
| 3843 | } | 3873 | } |
| 3844 | | 3874 | |
| 3845 | /// Returns stubs atom that references `sym_with_loc` if one exists. | 3875 | /// Returns stubs atom that references `sym_with_loc` if one exists. |
| 3846 | /// Returns null otherwise. | 3876 | /// Returns null otherwise. |
| 3847 | pub fn getStubsAtomForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?*Atom { | 3877 | pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index { |
| 3848 | const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null; | 3878 | const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null; |
| 3849 | return self.stubs.items[stubs_index].getAtom(self); | 3879 | return self.stubs.items[stubs_index].getAtomIndex(self); |
| 3850 | } | 3880 | } |
| 3851 | | 3881 | |
| 3852 | /// Returns symbol location corresponding to the set entrypoint. | 3882 | /// Returns symbol location corresponding to the set entrypoint. |
| ... | @@ -4232,26 +4262,31 @@ pub fn logAtoms(self: *MachO) void { | ... | @@ -4232,26 +4262,31 @@ pub fn logAtoms(self: *MachO) void { |
| 4232 | log.debug("atoms:", .{}); | 4262 | log.debug("atoms:", .{}); |
| 4233 | | 4263 | |
| 4234 | const slice = self.sections.slice(); | 4264 | const slice = self.sections.slice(); |
| 4235 | for (slice.items(.last_atom)) |last, i| { | 4265 | for (slice.items(.last_atom_index)) |last_atom_index, i| { |
| 4236 | var atom = last orelse continue; | 4266 | var atom_index = last_atom_index orelse continue; |
| 4237 | const header = slice.items(.header)[i]; | 4267 | const header = slice.items(.header)[i]; |
| 4238 | | 4268 | |
| 4239 | while (atom.prev) |prev| { | 4269 | while (true) { |
| 4240 | atom = prev; | 4270 | const atom = self.getAtom(atom_index); |
| | 4271 | if (atom.prev_index) |prev_index| { |
| | 4272 | atom_index = prev_index; |
| | 4273 | } else break; |
| 4241 | } | 4274 | } |
| 4242 | | 4275 | |
| 4243 | log.debug("{s},{s}", .{ header.segName(), header.sectName() }); | 4276 | log.debug("{s},{s}", .{ header.segName(), header.sectName() }); |
| 4244 | | 4277 | |
| 4245 | while (true) { | 4278 | while (true) { |
| 4246 | self.logAtom(atom); | 4279 | self.logAtom(atom_index); |
| 4247 | if (atom.next) |next| { | 4280 | const atom = self.getAtom(atom_index); |
| 4248 | atom = next; | 4281 | if (atom.next_index) |next_index| { |
| | 4282 | atom_index = next_index; |
| 4249 | } else break; | 4283 | } else break; |
| 4250 | } | 4284 | } |
| 4251 | } | 4285 | } |
| 4252 | } | 4286 | } |
| 4253 | | 4287 | |
| 4254 | pub fn logAtom(self: *MachO, atom: *const Atom) void { | 4288 | pub fn logAtom(self: *MachO, atom_index: Atom.Index) void { |
| | 4289 | const atom = self.getAtom(atom_index); |
| 4255 | const sym = atom.getSymbol(self); | 4290 | const sym = atom.getSymbol(self); |
| 4256 | const sym_name = atom.getName(self); | 4291 | const sym_name = atom.getName(self); |
| 4257 | log.debug(" ATOM(%{?d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({?d}) in sect({d})", .{ | 4292 | log.debug(" ATOM(%{?d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({?d}) in sect({d})", .{ |