| ... | ... | @@ -104,16 +104,16 @@ entry_addr: ?u64 = null, |
| 104 | 104 | |
| 105 | 105 | /// Table of all local symbols |
| 106 | 106 | /// Internally references string table for names (which are optional). |
| 107 | | local_symbols: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 107 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 108 | 108 | /// Table of all global symbols |
| 109 | | global_symbols: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 109 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 110 | 110 | /// Table of all extern nonlazy symbols, indexed by name. |
| 111 | | extern_nonlazy_symbols: std.StringArrayHashMapUnmanaged(ExternSymbol) = .{}, |
| 111 | nonlazy_imports: std.StringArrayHashMapUnmanaged(ExternSymbol) = .{}, |
| 112 | 112 | /// Table of all extern lazy symbols, indexed by name. |
| 113 | | extern_lazy_symbols: std.StringArrayHashMapUnmanaged(ExternSymbol) = .{}, |
| 113 | lazy_imports: std.StringArrayHashMapUnmanaged(ExternSymbol) = .{}, |
| 114 | 114 | |
| 115 | | local_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 116 | | global_symbol_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 115 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 116 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 117 | 117 | offset_table_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 118 | 118 | |
| 119 | 119 | stub_helper_stubs_start_off: ?u64 = null, |
| ... | ... | @@ -260,9 +260,9 @@ pub const TextBlock = struct { |
| 260 | 260 | /// File offset relocation happens transparently, so it is not included in |
| 261 | 261 | /// this calculation. |
| 262 | 262 | fn capacity(self: TextBlock, macho_file: MachO) u64 { |
| 263 | | const self_sym = macho_file.local_symbols.items[self.local_sym_index]; |
| 263 | const self_sym = macho_file.locals.items[self.local_sym_index]; |
| 264 | 264 | if (self.next) |next| { |
| 265 | | const next_sym = macho_file.local_symbols.items[next.local_sym_index]; |
| 265 | const next_sym = macho_file.locals.items[next.local_sym_index]; |
| 266 | 266 | return next_sym.n_value - self_sym.n_value; |
| 267 | 267 | } else { |
| 268 | 268 | // We are the last block. |
| ... | ... | @@ -274,8 +274,8 @@ pub const TextBlock = struct { |
| 274 | 274 | fn freeListEligible(self: TextBlock, macho_file: MachO) bool { |
| 275 | 275 | // No need to keep a free list node for the last block. |
| 276 | 276 | const next = self.next orelse return false; |
| 277 | | const self_sym = macho_file.local_symbols.items[self.local_sym_index]; |
| 278 | | const next_sym = macho_file.local_symbols.items[next.local_sym_index]; |
| 277 | const self_sym = macho_file.locals.items[self.local_sym_index]; |
| 278 | const next_sym = macho_file.locals.items[next.local_sym_index]; |
| 279 | 279 | const cap = next_sym.n_value - self_sym.n_value; |
| 280 | 280 | const ideal_cap = padToIdeal(self.size); |
| 281 | 281 | if (cap <= ideal_cap) return false; |
| ... | ... | @@ -344,7 +344,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 344 | 344 | }; |
| 345 | 345 | |
| 346 | 346 | // Index 0 is always a null symbol. |
| 347 | | try self.local_symbols.append(allocator, .{ |
| 347 | try self.locals.append(allocator, .{ |
| 348 | 348 | .n_strx = 0, |
| 349 | 349 | .n_type = 0, |
| 350 | 350 | .n_sect = 0, |
| ... | ... | @@ -834,7 +834,7 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 834 | 834 | } |
| 835 | 835 | }, |
| 836 | 836 | else => { |
| 837 | | log.err("{s} terminated", .{ argv.items[0] }); |
| 837 | log.err("{s} terminated", .{argv.items[0]}); |
| 838 | 838 | return error.LLDCrashed; |
| 839 | 839 | }, |
| 840 | 840 | } |
| ... | ... | @@ -1019,14 +1019,14 @@ pub fn deinit(self: *MachO) void { |
| 1019 | 1019 | if (self.d_sym) |*ds| { |
| 1020 | 1020 | ds.deinit(self.base.allocator); |
| 1021 | 1021 | } |
| 1022 | | for (self.extern_lazy_symbols.items()) |*entry| { |
| 1022 | for (self.lazy_imports.items()) |*entry| { |
| 1023 | 1023 | self.base.allocator.free(entry.key); |
| 1024 | 1024 | } |
| 1025 | | self.extern_lazy_symbols.deinit(self.base.allocator); |
| 1026 | | for (self.extern_nonlazy_symbols.items()) |*entry| { |
| 1025 | self.lazy_imports.deinit(self.base.allocator); |
| 1026 | for (self.nonlazy_imports.items()) |*entry| { |
| 1027 | 1027 | self.base.allocator.free(entry.key); |
| 1028 | 1028 | } |
| 1029 | | self.extern_nonlazy_symbols.deinit(self.base.allocator); |
| 1029 | self.nonlazy_imports.deinit(self.base.allocator); |
| 1030 | 1030 | self.pie_fixups.deinit(self.base.allocator); |
| 1031 | 1031 | self.stub_fixups.deinit(self.base.allocator); |
| 1032 | 1032 | self.text_block_free_list.deinit(self.base.allocator); |
| ... | ... | @@ -1040,10 +1040,10 @@ pub fn deinit(self: *MachO) void { |
| 1040 | 1040 | } |
| 1041 | 1041 | self.string_table_directory.deinit(self.base.allocator); |
| 1042 | 1042 | self.string_table.deinit(self.base.allocator); |
| 1043 | | self.global_symbols.deinit(self.base.allocator); |
| 1044 | | self.global_symbol_free_list.deinit(self.base.allocator); |
| 1045 | | self.local_symbols.deinit(self.base.allocator); |
| 1046 | | self.local_symbol_free_list.deinit(self.base.allocator); |
| 1043 | self.globals.deinit(self.base.allocator); |
| 1044 | self.globals_free_list.deinit(self.base.allocator); |
| 1045 | self.locals.deinit(self.base.allocator); |
| 1046 | self.locals_free_list.deinit(self.base.allocator); |
| 1047 | 1047 | for (self.load_commands.items) |*lc| { |
| 1048 | 1048 | lc.deinit(self.base.allocator); |
| 1049 | 1049 | } |
| ... | ... | @@ -1098,7 +1098,7 @@ fn shrinkTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64) vo |
| 1098 | 1098 | } |
| 1099 | 1099 | |
| 1100 | 1100 | fn growTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |
| 1101 | | const sym = self.local_symbols.items[text_block.local_sym_index]; |
| 1101 | const sym = self.locals.items[text_block.local_sym_index]; |
| 1102 | 1102 | const align_ok = mem.alignBackwardGeneric(u64, sym.n_value, alignment) == sym.n_value; |
| 1103 | 1103 | const need_realloc = !align_ok or new_block_size > text_block.capacity(self.*); |
| 1104 | 1104 | if (!need_realloc) return sym.n_value; |
| ... | ... | @@ -1108,16 +1108,16 @@ fn growTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alig |
| 1108 | 1108 | pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { |
| 1109 | 1109 | if (decl.link.macho.local_sym_index != 0) return; |
| 1110 | 1110 | |
| 1111 | | try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1); |
| 1111 | try self.locals.ensureCapacity(self.base.allocator, self.locals.items.len + 1); |
| 1112 | 1112 | try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1); |
| 1113 | 1113 | |
| 1114 | | if (self.local_symbol_free_list.popOrNull()) |i| { |
| 1114 | if (self.locals_free_list.popOrNull()) |i| { |
| 1115 | 1115 | log.debug("reusing symbol index {d} for {s}", .{ i, decl.name }); |
| 1116 | 1116 | decl.link.macho.local_sym_index = i; |
| 1117 | 1117 | } else { |
| 1118 | | log.debug("allocating symbol index {d} for {s}", .{ self.local_symbols.items.len, decl.name }); |
| 1119 | | decl.link.macho.local_sym_index = @intCast(u32, self.local_symbols.items.len); |
| 1120 | | _ = self.local_symbols.addOneAssumeCapacity(); |
| 1118 | log.debug("allocating symbol index {d} for {s}", .{ self.locals.items.len, decl.name }); |
| 1119 | decl.link.macho.local_sym_index = @intCast(u32, self.locals.items.len); |
| 1120 | _ = self.locals.addOneAssumeCapacity(); |
| 1121 | 1121 | } |
| 1122 | 1122 | |
| 1123 | 1123 | if (self.offset_table_free_list.popOrNull()) |i| { |
| ... | ... | @@ -1128,7 +1128,7 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { |
| 1128 | 1128 | self.offset_table_count_dirty = true; |
| 1129 | 1129 | } |
| 1130 | 1130 | |
| 1131 | | self.local_symbols.items[decl.link.macho.local_sym_index] = .{ |
| 1131 | self.locals.items[decl.link.macho.local_sym_index] = .{ |
| 1132 | 1132 | .n_strx = 0, |
| 1133 | 1133 | .n_type = 0, |
| 1134 | 1134 | .n_sect = 0, |
| ... | ... | @@ -1189,7 +1189,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1189 | 1189 | |
| 1190 | 1190 | const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); |
| 1191 | 1191 | assert(decl.link.macho.local_sym_index != 0); // Caller forgot to call allocateDeclIndexes() |
| 1192 | | const symbol = &self.local_symbols.items[decl.link.macho.local_sym_index]; |
| 1192 | const symbol = &self.locals.items[decl.link.macho.local_sym_index]; |
| 1193 | 1193 | |
| 1194 | 1194 | if (decl.link.macho.size != 0) { |
| 1195 | 1195 | const capacity = decl.link.macho.capacity(self.*); |
| ... | ... | @@ -1285,7 +1285,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1285 | 1285 | try self.writeStubInStubHelper(fixup.symbol); |
| 1286 | 1286 | try self.writeLazySymbolPointer(fixup.symbol); |
| 1287 | 1287 | |
| 1288 | | const extern_sym = &self.extern_lazy_symbols.items()[fixup.symbol].value; |
| 1288 | const extern_sym = &self.lazy_imports.items()[fixup.symbol].value; |
| 1289 | 1289 | extern_sym.segment = self.data_segment_cmd_index.?; |
| 1290 | 1290 | extern_sym.offset = fixup.symbol * @sizeOf(u64); |
| 1291 | 1291 | self.rebase_info_dirty = true; |
| ... | ... | @@ -1329,9 +1329,9 @@ pub fn updateDeclExports( |
| 1329 | 1329 | const tracy = trace(@src()); |
| 1330 | 1330 | defer tracy.end(); |
| 1331 | 1331 | |
| 1332 | | try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len); |
| 1332 | try self.globals.ensureCapacity(self.base.allocator, self.globals.items.len + exports.len); |
| 1333 | 1333 | if (decl.link.macho.local_sym_index == 0) return; |
| 1334 | | const decl_sym = &self.local_symbols.items[decl.link.macho.local_sym_index]; |
| 1334 | const decl_sym = &self.locals.items[decl.link.macho.local_sym_index]; |
| 1335 | 1335 | |
| 1336 | 1336 | for (exports) |exp| { |
| 1337 | 1337 | if (exp.options.section) |section_name| { |
| ... | ... | @@ -1364,7 +1364,7 @@ pub fn updateDeclExports( |
| 1364 | 1364 | }; |
| 1365 | 1365 | const n_type = decl_sym.n_type | macho.N_EXT; |
| 1366 | 1366 | if (exp.link.macho.sym_index) |i| { |
| 1367 | | const sym = &self.global_symbols.items[i]; |
| 1367 | const sym = &self.globals.items[i]; |
| 1368 | 1368 | sym.* = .{ |
| 1369 | 1369 | .n_strx = try self.updateString(sym.n_strx, exp.options.name), |
| 1370 | 1370 | .n_type = n_type, |
| ... | ... | @@ -1374,12 +1374,12 @@ pub fn updateDeclExports( |
| 1374 | 1374 | }; |
| 1375 | 1375 | } else { |
| 1376 | 1376 | const name_str_index = try self.makeString(exp.options.name); |
| 1377 | | const i = if (self.global_symbol_free_list.popOrNull()) |i| i else blk: { |
| 1378 | | _ = self.global_symbols.addOneAssumeCapacity(); |
| 1377 | const i = if (self.globals_free_list.popOrNull()) |i| i else blk: { |
| 1378 | _ = self.globals.addOneAssumeCapacity(); |
| 1379 | 1379 | self.export_info_dirty = true; |
| 1380 | | break :blk self.global_symbols.items.len - 1; |
| 1380 | break :blk self.globals.items.len - 1; |
| 1381 | 1381 | }; |
| 1382 | | self.global_symbols.items[i] = .{ |
| 1382 | self.globals.items[i] = .{ |
| 1383 | 1383 | .n_strx = name_str_index, |
| 1384 | 1384 | .n_type = n_type, |
| 1385 | 1385 | .n_sect = @intCast(u8, self.text_section_index.?) + 1, |
| ... | ... | @@ -1394,18 +1394,18 @@ pub fn updateDeclExports( |
| 1394 | 1394 | |
| 1395 | 1395 | pub fn deleteExport(self: *MachO, exp: Export) void { |
| 1396 | 1396 | const sym_index = exp.sym_index orelse return; |
| 1397 | | self.global_symbol_free_list.append(self.base.allocator, sym_index) catch {}; |
| 1398 | | self.global_symbols.items[sym_index].n_type = 0; |
| 1397 | self.globals_free_list.append(self.base.allocator, sym_index) catch {}; |
| 1398 | self.globals.items[sym_index].n_type = 0; |
| 1399 | 1399 | } |
| 1400 | 1400 | |
| 1401 | 1401 | pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 1402 | 1402 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| 1403 | 1403 | self.freeTextBlock(&decl.link.macho); |
| 1404 | 1404 | if (decl.link.macho.local_sym_index != 0) { |
| 1405 | | self.local_symbol_free_list.append(self.base.allocator, decl.link.macho.local_sym_index) catch {}; |
| 1405 | self.locals_free_list.append(self.base.allocator, decl.link.macho.local_sym_index) catch {}; |
| 1406 | 1406 | self.offset_table_free_list.append(self.base.allocator, decl.link.macho.offset_table_index) catch {}; |
| 1407 | 1407 | |
| 1408 | | self.local_symbols.items[decl.link.macho.local_sym_index].n_type = 0; |
| 1408 | self.locals.items[decl.link.macho.local_sym_index].n_type = 0; |
| 1409 | 1409 | |
| 1410 | 1410 | decl.link.macho.local_sym_index = 0; |
| 1411 | 1411 | } |
| ... | ... | @@ -1413,7 +1413,7 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 1413 | 1413 | |
| 1414 | 1414 | pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 { |
| 1415 | 1415 | assert(decl.link.macho.local_sym_index != 0); |
| 1416 | | return self.local_symbols.items[decl.link.macho.local_sym_index].n_value; |
| 1416 | return self.locals.items[decl.link.macho.local_sym_index].n_value; |
| 1417 | 1417 | } |
| 1418 | 1418 | |
| 1419 | 1419 | pub fn populateMissingMetadata(self: *MachO) !void { |
| ... | ... | @@ -2060,11 +2060,11 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2060 | 2060 | self.header_dirty = true; |
| 2061 | 2061 | self.load_commands_dirty = true; |
| 2062 | 2062 | } |
| 2063 | | if (!self.extern_nonlazy_symbols.contains("dyld_stub_binder")) { |
| 2064 | | const index = @intCast(u32, self.extern_nonlazy_symbols.items().len); |
| 2063 | if (!self.nonlazy_imports.contains("dyld_stub_binder")) { |
| 2064 | const index = @intCast(u32, self.nonlazy_imports.items().len); |
| 2065 | 2065 | const name = try self.base.allocator.dupe(u8, "dyld_stub_binder"); |
| 2066 | 2066 | const offset = try self.makeString("dyld_stub_binder"); |
| 2067 | | try self.extern_nonlazy_symbols.putNoClobber(self.base.allocator, name, .{ |
| 2067 | try self.nonlazy_imports.putNoClobber(self.base.allocator, name, .{ |
| 2068 | 2068 | .inner = .{ |
| 2069 | 2069 | .n_strx = offset, |
| 2070 | 2070 | .n_type = std.macho.N_UNDF | std.macho.N_EXT, |
| ... | ... | @@ -2159,7 +2159,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, |
| 2159 | 2159 | const big_block = self.text_block_free_list.items[i]; |
| 2160 | 2160 | // We now have a pointer to a live text block that has too much capacity. |
| 2161 | 2161 | // Is it enough that we could fit this new text block? |
| 2162 | | const sym = self.local_symbols.items[big_block.local_sym_index]; |
| 2162 | const sym = self.locals.items[big_block.local_sym_index]; |
| 2163 | 2163 | const capacity = big_block.capacity(self.*); |
| 2164 | 2164 | const ideal_capacity = padToIdeal(capacity); |
| 2165 | 2165 | const ideal_capacity_end_vaddr = sym.n_value + ideal_capacity; |
| ... | ... | @@ -2190,7 +2190,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, |
| 2190 | 2190 | } |
| 2191 | 2191 | break :blk new_start_vaddr; |
| 2192 | 2192 | } else if (self.last_text_block) |last| { |
| 2193 | | const last_symbol = self.local_symbols.items[last.local_sym_index]; |
| 2193 | const last_symbol = self.locals.items[last.local_sym_index]; |
| 2194 | 2194 | // TODO We should pad out the excess capacity with NOPs. For executables, |
| 2195 | 2195 | // no padding seems to be OK, but it will probably not be for objects. |
| 2196 | 2196 | const ideal_capacity = padToIdeal(last.size); |
| ... | ... | @@ -2288,11 +2288,11 @@ fn updateString(self: *MachO, old_str_off: u32, new_name: []const u8) !u32 { |
| 2288 | 2288 | } |
| 2289 | 2289 | |
| 2290 | 2290 | pub fn addExternSymbol(self: *MachO, name: []const u8) !u32 { |
| 2291 | | const index = @intCast(u32, self.extern_lazy_symbols.items().len); |
| 2291 | const index = @intCast(u32, self.lazy_imports.items().len); |
| 2292 | 2292 | const offset = try self.makeString(name); |
| 2293 | 2293 | const sym_name = try self.base.allocator.dupe(u8, name); |
| 2294 | 2294 | const dylib_ordinal = 1; // TODO this is now hardcoded, since we only support libSystem. |
| 2295 | | try self.extern_lazy_symbols.putNoClobber(self.base.allocator, sym_name, .{ |
| 2295 | try self.lazy_imports.putNoClobber(self.base.allocator, sym_name, .{ |
| 2296 | 2296 | .inner = .{ |
| 2297 | 2297 | .n_strx = offset, |
| 2298 | 2298 | .n_type = macho.N_UNDF | macho.N_EXT, |
| ... | ... | @@ -2591,9 +2591,9 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void { |
| 2591 | 2591 | |
| 2592 | 2592 | fn relocateSymbolTable(self: *MachO) !void { |
| 2593 | 2593 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 2594 | | const nlocals = self.local_symbols.items.len; |
| 2595 | | const nglobals = self.global_symbols.items.len; |
| 2596 | | const nundefs = self.extern_lazy_symbols.items().len + self.extern_nonlazy_symbols.items().len; |
| 2594 | const nlocals = self.locals.items.len; |
| 2595 | const nglobals = self.globals.items.len; |
| 2596 | const nundefs = self.lazy_imports.items().len + self.nonlazy_imports.items().len; |
| 2597 | 2597 | const nsyms = nlocals + nglobals + nundefs; |
| 2598 | 2598 | |
| 2599 | 2599 | if (symtab.nsyms < nsyms) { |
| ... | ... | @@ -2628,7 +2628,7 @@ fn writeLocalSymbol(self: *MachO, index: usize) !void { |
| 2628 | 2628 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 2629 | 2629 | const off = symtab.symoff + @sizeOf(macho.nlist_64) * index; |
| 2630 | 2630 | log.debug("writing local symbol {} at 0x{x}", .{ index, off }); |
| 2631 | | try self.base.file.?.pwriteAll(mem.asBytes(&self.local_symbols.items[index]), off); |
| 2631 | try self.base.file.?.pwriteAll(mem.asBytes(&self.locals.items[index]), off); |
| 2632 | 2632 | } |
| 2633 | 2633 | |
| 2634 | 2634 | fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| ... | ... | @@ -2637,17 +2637,17 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 2637 | 2637 | |
| 2638 | 2638 | try self.relocateSymbolTable(); |
| 2639 | 2639 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 2640 | | const nlocals = self.local_symbols.items.len; |
| 2641 | | const nglobals = self.global_symbols.items.len; |
| 2640 | const nlocals = self.locals.items.len; |
| 2641 | const nglobals = self.globals.items.len; |
| 2642 | 2642 | |
| 2643 | | const nundefs = self.extern_lazy_symbols.items().len + self.extern_nonlazy_symbols.items().len; |
| 2643 | const nundefs = self.lazy_imports.items().len + self.nonlazy_imports.items().len; |
| 2644 | 2644 | var undefs = std.ArrayList(macho.nlist_64).init(self.base.allocator); |
| 2645 | 2645 | defer undefs.deinit(); |
| 2646 | 2646 | try undefs.ensureCapacity(nundefs); |
| 2647 | | for (self.extern_lazy_symbols.items()) |entry| { |
| 2647 | for (self.lazy_imports.items()) |entry| { |
| 2648 | 2648 | undefs.appendAssumeCapacity(entry.value.inner); |
| 2649 | 2649 | } |
| 2650 | | for (self.extern_nonlazy_symbols.items()) |entry| { |
| 2650 | for (self.nonlazy_imports.items()) |entry| { |
| 2651 | 2651 | undefs.appendAssumeCapacity(entry.value.inner); |
| 2652 | 2652 | } |
| 2653 | 2653 | |
| ... | ... | @@ -2657,7 +2657,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 2657 | 2657 | const globals_off = locals_off + locals_size; |
| 2658 | 2658 | const globals_size = nglobals * @sizeOf(macho.nlist_64); |
| 2659 | 2659 | log.debug("writing global symbols from 0x{x} to 0x{x}", .{ globals_off, globals_size + globals_off }); |
| 2660 | | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.global_symbols.items), globals_off); |
| 2660 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.globals.items), globals_off); |
| 2661 | 2661 | |
| 2662 | 2662 | const undefs_off = globals_off + globals_size; |
| 2663 | 2663 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| ... | ... | @@ -2688,8 +2688,8 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2688 | 2688 | const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2689 | 2689 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| 2690 | 2690 | |
| 2691 | | const lazy = self.extern_lazy_symbols.items(); |
| 2692 | | const nonlazy = self.extern_nonlazy_symbols.items(); |
| 2691 | const lazy = self.lazy_imports.items(); |
| 2692 | const nonlazy = self.nonlazy_imports.items(); |
| 2693 | 2693 | const allocated_size = self.allocatedSizeLinkedit(dysymtab.indirectsymoff); |
| 2694 | 2694 | const nindirectsyms = @intCast(u32, lazy.len * 2 + nonlazy.len); |
| 2695 | 2695 | const needed_size = @intCast(u32, nindirectsyms * @sizeOf(u32)); |
| ... | ... | @@ -2710,20 +2710,20 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2710 | 2710 | var writer = stream.writer(); |
| 2711 | 2711 | |
| 2712 | 2712 | stubs.reserved1 = 0; |
| 2713 | | for (self.extern_lazy_symbols.items()) |_, i| { |
| 2713 | for (self.lazy_imports.items()) |_, i| { |
| 2714 | 2714 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| 2715 | 2715 | try writer.writeIntLittle(u32, symtab_idx); |
| 2716 | 2716 | } |
| 2717 | 2717 | |
| 2718 | 2718 | const base_id = @intCast(u32, lazy.len); |
| 2719 | 2719 | got.reserved1 = base_id; |
| 2720 | | for (self.extern_nonlazy_symbols.items()) |_, i| { |
| 2720 | for (self.nonlazy_imports.items()) |_, i| { |
| 2721 | 2721 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i + base_id); |
| 2722 | 2722 | try writer.writeIntLittle(u32, symtab_idx); |
| 2723 | 2723 | } |
| 2724 | 2724 | |
| 2725 | 2725 | la_symbol_ptr.reserved1 = got.reserved1 + @intCast(u32, nonlazy.len); |
| 2726 | | for (self.extern_lazy_symbols.items()) |_, i| { |
| 2726 | for (self.lazy_imports.items()) |_, i| { |
| 2727 | 2727 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| 2728 | 2728 | try writer.writeIntLittle(u32, symtab_idx); |
| 2729 | 2729 | } |
| ... | ... | @@ -2789,7 +2789,7 @@ fn writeCodeSignature(self: *MachO) !void { |
| 2789 | 2789 | |
| 2790 | 2790 | fn writeExportTrie(self: *MachO) !void { |
| 2791 | 2791 | if (!self.export_info_dirty) return; |
| 2792 | | if (self.global_symbols.items.len == 0) return; |
| 2792 | if (self.globals.items.len == 0) return; |
| 2793 | 2793 | |
| 2794 | 2794 | const tracy = trace(@src()); |
| 2795 | 2795 | defer tracy.end(); |
| ... | ... | @@ -2798,7 +2798,7 @@ fn writeExportTrie(self: *MachO) !void { |
| 2798 | 2798 | defer trie.deinit(); |
| 2799 | 2799 | |
| 2800 | 2800 | const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2801 | | for (self.global_symbols.items) |symbol| { |
| 2801 | for (self.globals.items) |symbol| { |
| 2802 | 2802 | // TODO figure out if we should put all global symbols into the export trie |
| 2803 | 2803 | const name = self.getString(symbol.n_strx); |
| 2804 | 2804 | assert(symbol.n_value >= text_segment.inner.vmaddr); |
| ... | ... | @@ -2840,12 +2840,12 @@ fn writeRebaseInfoTable(self: *MachO) !void { |
| 2840 | 2840 | const tracy = trace(@src()); |
| 2841 | 2841 | defer tracy.end(); |
| 2842 | 2842 | |
| 2843 | | const size = try rebaseInfoSize(self.extern_lazy_symbols.items()); |
| 2843 | const size = try rebaseInfoSize(self.lazy_imports.items()); |
| 2844 | 2844 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); |
| 2845 | 2845 | defer self.base.allocator.free(buffer); |
| 2846 | 2846 | |
| 2847 | 2847 | var stream = std.io.fixedBufferStream(buffer); |
| 2848 | | try writeRebaseInfo(self.extern_lazy_symbols.items(), stream.writer()); |
| 2848 | try writeRebaseInfo(self.lazy_imports.items(), stream.writer()); |
| 2849 | 2849 | |
| 2850 | 2850 | const linkedit_segment = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2851 | 2851 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| ... | ... | @@ -2872,12 +2872,12 @@ fn writeBindingInfoTable(self: *MachO) !void { |
| 2872 | 2872 | const tracy = trace(@src()); |
| 2873 | 2873 | defer tracy.end(); |
| 2874 | 2874 | |
| 2875 | | const size = try bindInfoSize(self.extern_nonlazy_symbols.items()); |
| 2875 | const size = try bindInfoSize(self.nonlazy_imports.items()); |
| 2876 | 2876 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); |
| 2877 | 2877 | defer self.base.allocator.free(buffer); |
| 2878 | 2878 | |
| 2879 | 2879 | var stream = std.io.fixedBufferStream(buffer); |
| 2880 | | try writeBindInfo(self.extern_nonlazy_symbols.items(), stream.writer()); |
| 2880 | try writeBindInfo(self.nonlazy_imports.items(), stream.writer()); |
| 2881 | 2881 | |
| 2882 | 2882 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2883 | 2883 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| ... | ... | @@ -2901,12 +2901,12 @@ fn writeBindingInfoTable(self: *MachO) !void { |
| 2901 | 2901 | fn writeLazyBindingInfoTable(self: *MachO) !void { |
| 2902 | 2902 | if (!self.lazy_binding_info_dirty) return; |
| 2903 | 2903 | |
| 2904 | | const size = try lazyBindInfoSize(self.extern_lazy_symbols.items()); |
| 2904 | const size = try lazyBindInfoSize(self.lazy_imports.items()); |
| 2905 | 2905 | var buffer = try self.base.allocator.alloc(u8, @intCast(usize, size)); |
| 2906 | 2906 | defer self.base.allocator.free(buffer); |
| 2907 | 2907 | |
| 2908 | 2908 | var stream = std.io.fixedBufferStream(buffer); |
| 2909 | | try writeLazyBindInfo(self.extern_lazy_symbols.items(), stream.writer()); |
| 2909 | try writeLazyBindInfo(self.lazy_imports.items(), stream.writer()); |
| 2910 | 2910 | |
| 2911 | 2911 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2912 | 2912 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| ... | ... | @@ -2929,7 +2929,7 @@ fn writeLazyBindingInfoTable(self: *MachO) !void { |
| 2929 | 2929 | } |
| 2930 | 2930 | |
| 2931 | 2931 | fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 2932 | | if (self.extern_lazy_symbols.items().len == 0) return; |
| 2932 | if (self.lazy_imports.items().len == 0) return; |
| 2933 | 2933 | |
| 2934 | 2934 | var stream = std.io.fixedBufferStream(buffer); |
| 2935 | 2935 | var reader = stream.reader(); |
| ... | ... | @@ -2975,7 +2975,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 2975 | 2975 | else => {}, |
| 2976 | 2976 | } |
| 2977 | 2977 | } |
| 2978 | | assert(self.extern_lazy_symbols.items().len <= offsets.items.len); |
| 2978 | assert(self.lazy_imports.items().len <= offsets.items.len); |
| 2979 | 2979 | |
| 2980 | 2980 | const stub_size: u4 = switch (self.base.options.target.cpu.arch) { |
| 2981 | 2981 | .x86_64 => 10, |
| ... | ... | @@ -2988,7 +2988,7 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void { |
| 2988 | 2988 | else => unreachable, |
| 2989 | 2989 | }; |
| 2990 | 2990 | var buf: [@sizeOf(u32)]u8 = undefined; |
| 2991 | | for (self.extern_lazy_symbols.items()) |_, i| { |
| 2991 | for (self.lazy_imports.items()) |_, i| { |
| 2992 | 2992 | const placeholder_off = self.stub_helper_stubs_start_off.? + i * stub_size + off; |
| 2993 | 2993 | mem.writeIntLittle(u32, &buf, offsets.items[i]); |
| 2994 | 2994 | try self.base.file.?.pwriteAll(&buf, placeholder_off); |
| ... | ... | @@ -3193,12 +3193,12 @@ fn parseSymbolTable(self: *MachO) !void { |
| 3193 | 3193 | const nread = try self.base.file.?.preadAll(@ptrCast([*]u8, buffer)[0 .. symtab.nsyms * @sizeOf(macho.nlist_64)], symtab.symoff); |
| 3194 | 3194 | assert(@divExact(nread, @sizeOf(macho.nlist_64)) == buffer.len); |
| 3195 | 3195 | |
| 3196 | | try self.local_symbols.ensureCapacity(self.base.allocator, dysymtab.nlocalsym); |
| 3197 | | try self.global_symbols.ensureCapacity(self.base.allocator, dysymtab.nextdefsym); |
| 3196 | try self.locals.ensureCapacity(self.base.allocator, dysymtab.nlocalsym); |
| 3197 | try self.globals.ensureCapacity(self.base.allocator, dysymtab.nextdefsym); |
| 3198 | 3198 | try self.undef_symbols.ensureCapacity(self.base.allocator, dysymtab.nundefsym); |
| 3199 | 3199 | |
| 3200 | | self.local_symbols.appendSliceAssumeCapacity(buffer[dysymtab.ilocalsym .. dysymtab.ilocalsym + dysymtab.nlocalsym]); |
| 3201 | | self.global_symbols.appendSliceAssumeCapacity(buffer[dysymtab.iextdefsym .. dysymtab.iextdefsym + dysymtab.nextdefsym]); |
| 3200 | self.locals.appendSliceAssumeCapacity(buffer[dysymtab.ilocalsym .. dysymtab.ilocalsym + dysymtab.nlocalsym]); |
| 3201 | self.globals.appendSliceAssumeCapacity(buffer[dysymtab.iextdefsym .. dysymtab.iextdefsym + dysymtab.nextdefsym]); |
| 3202 | 3202 | self.undef_symbols.appendSliceAssumeCapacity(buffer[dysymtab.iundefsym .. dysymtab.iundefsym + dysymtab.nundefsym]); |
| 3203 | 3203 | } |
| 3204 | 3204 | |