| author | |
| committer | |
| log | 5a6a1f8a8ad1475d328c998824981c7b310987d2 |
| tree | 757e2d9bbf14e8ee96b8a2911d6a713dc95c3ff9 |
| parent | 98da660e453789f578c04e641286bdf8ff84bcd4 |
19 files changed, 274 insertions(+), 191 deletions(-)
src/arch/wasm/Emit.zig+2-1| ... | ... | @@ -406,7 +406,8 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 406 | 406 | const extra_index = emit.mir.instructions.items(.data)[inst].payload; |
| 407 | 407 | const mem = emit.mir.extraData(Mir.Memory, extra_index).data; |
| 408 | 408 | const mem_offset = emit.offset() + 1; |
| 409 | const is_wasm32 = emit.bin_file.base.options.target.cpu.arch == .wasm32; | |
| 409 | const target = emit.bin_file.comp.root_mod.resolved_target.result; | |
| 410 | const is_wasm32 = target.cpu.arch == .wasm32; | |
| 410 | 411 | if (is_wasm32) { |
| 411 | 412 | try emit.code.append(std.wasm.opcode(.i32_const)); |
| 412 | 413 | var buf: [5]u8 = undefined; |
src/link/Coff.zig+7-4| ... | ... | @@ -1467,6 +1467,7 @@ pub fn updateExports( |
| 1467 | 1467 | } |
| 1468 | 1468 | |
| 1469 | 1469 | const ip = &mod.intern_pool; |
| 1470 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1470 | 1471 | |
| 1471 | 1472 | if (self.base.options.use_llvm) { |
| 1472 | 1473 | // Even in the case of LLVM, we need to notice certain exported symbols in order to |
| ... | ... | @@ -1478,7 +1479,7 @@ pub fn updateExports( |
| 1478 | 1479 | }; |
| 1479 | 1480 | const exported_decl = mod.declPtr(exported_decl_index); |
| 1480 | 1481 | if (exported_decl.getOwnedFunction(mod) == null) continue; |
| 1481 | const winapi_cc = switch (self.base.options.target.cpu.arch) { | |
| 1482 | const winapi_cc = switch (target.cpu.arch) { | |
| 1482 | 1483 | .x86 => std.builtin.CallingConvention.Stdcall, |
| 1483 | 1484 | else => std.builtin.CallingConvention.C, |
| 1484 | 1485 | }; |
| ... | ... | @@ -1487,7 +1488,7 @@ pub fn updateExports( |
| 1487 | 1488 | self.base.options.link_libc) |
| 1488 | 1489 | { |
| 1489 | 1490 | mod.stage1_flags.have_c_main = true; |
| 1490 | } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) { | |
| 1491 | } else if (decl_cc == winapi_cc and target.os.tag == .windows) { | |
| 1491 | 1492 | if (ip.stringEqlSlice(exp.opts.name, "WinMain")) { |
| 1492 | 1493 | mod.stage1_flags.have_winmain = true; |
| 1493 | 1494 | } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) { |
| ... | ... | @@ -2200,6 +2201,7 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void { |
| 2200 | 2201 | } |
| 2201 | 2202 | |
| 2202 | 2203 | fn writeHeader(self: *Coff) !void { |
| 2204 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 2203 | 2205 | const gpa = self.base.comp.gpa; |
| 2204 | 2206 | var buffer = std.ArrayList(u8).init(gpa); |
| 2205 | 2207 | defer buffer.deinit(); |
| ... | ... | @@ -2225,7 +2227,7 @@ fn writeHeader(self: *Coff) !void { |
| 2225 | 2227 | const timestamp = std.time.timestamp(); |
| 2226 | 2228 | const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize())); |
| 2227 | 2229 | var coff_header = coff.CoffHeader{ |
| 2228 | .machine = coff.MachineType.fromTargetCpuArch(self.base.options.target.cpu.arch), | |
| 2230 | .machine = coff.MachineType.fromTargetCpuArch(target.cpu.arch), | |
| 2229 | 2231 | .number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section |
| 2230 | 2232 | .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))), |
| 2231 | 2233 | .pointer_to_symbol_table = self.strtab_offset orelse 0, |
| ... | ... | @@ -2451,8 +2453,9 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { |
| 2451 | 2453 | } |
| 2452 | 2454 | |
| 2453 | 2455 | pub fn getImageBase(self: Coff) u64 { |
| 2456 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 2454 | 2457 | const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) { |
| 2455 | .Exe => switch (self.base.options.target.cpu.arch) { | |
| 2458 | .Exe => switch (target.cpu.arch) { | |
| 2456 | 2459 | .aarch64 => @as(u64, 0x140000000), |
| 2457 | 2460 | .x86_64, .x86 => 0x400000, |
| 2458 | 2461 | else => unreachable, // unsupported target architecture |
src/link/Coff/Relocation.zig+2-1| ... | ... | @@ -107,7 +107,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base: |
| 107 | 107 | .ptr_width = coff_file.ptr_width, |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | switch (coff_file.base.options.target.cpu.arch) { | |
| 110 | const target = coff_file.base.comp.root_mod.resolved_target.result; | |
| 111 | switch (target.cpu.arch) { | |
| 111 | 112 | .aarch64 => self.resolveAarch64(ctx), |
| 112 | 113 | .x86, .x86_64 => self.resolveX86(ctx), |
| 113 | 114 | else => unreachable, // unhandled target architecture |
src/link/Coff/lld.zig+1-1| ... | ... | @@ -49,7 +49,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 49 | 49 | const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib; |
| 50 | 50 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe; |
| 51 | 51 | const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib; |
| 52 | const target = self.base.options.target; | |
| 52 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 53 | 53 | const optimize_mode = self.base.comp.root_mod.optimize_mode; |
| 54 | 54 | |
| 55 | 55 | // See link/Elf.zig for comments on how this mechanism works. |
src/link/Elf/Object.zig+2-1| ... | ... | @@ -54,7 +54,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 54 | 54 | |
| 55 | 55 | self.header = try reader.readStruct(elf.Elf64_Ehdr); |
| 56 | 56 | |
| 57 | if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) { | |
| 57 | const target = elf_file.base.comp.root_mod.resolved_target.result; | |
| 58 | if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) { | |
| 58 | 59 | try elf_file.reportParseError2( |
| 59 | 60 | self.index, |
| 60 | 61 | "invalid cpu architecture: {s}", |
src/link/Elf/SharedObject.zig+2-1| ... | ... | @@ -53,7 +53,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void { |
| 53 | 53 | |
| 54 | 54 | self.header = try reader.readStruct(elf.Elf64_Ehdr); |
| 55 | 55 | |
| 56 | if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) { | |
| 56 | const target = elf_file.base.comp.root_mod.resolved_target.result; | |
| 57 | if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) { | |
| 57 | 58 | try elf_file.reportParseError2( |
| 58 | 59 | self.index, |
| 59 | 60 | "invalid cpu architecture: {s}", |
src/link/Elf/synthetic_sections.zig+4-2| ... | ... | @@ -287,7 +287,8 @@ pub const ZigGotSection = struct { |
| 287 | 287 | zig_got.flags.dirty = false; |
| 288 | 288 | } |
| 289 | 289 | const entry_size: u16 = elf_file.archPtrWidthBytes(); |
| 290 | const endian = elf_file.base.options.target.cpu.arch.endian(); | |
| 290 | const target = elf_file.base.comp.root_mod.resolved_target.result; | |
| 291 | const endian = target.cpu.arch.endian(); | |
| 291 | 292 | const off = zig_got.entryOffset(index, elf_file); |
| 292 | 293 | const vaddr = zig_got.entryAddress(index, elf_file); |
| 293 | 294 | const entry = zig_got.entries.items[index]; |
| ... | ... | @@ -1575,7 +1576,8 @@ pub const ComdatGroupSection = struct { |
| 1575 | 1576 | |
| 1576 | 1577 | fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void { |
| 1577 | 1578 | const entry_size = elf_file.archPtrWidthBytes(); |
| 1578 | const endian = elf_file.base.options.target.cpu.arch.endian(); | |
| 1579 | const target = elf_file.base.comp.root_mod.resolved_target.result; | |
| 1580 | const endian = target.cpu.arch.endian(); | |
| 1579 | 1581 | switch (entry_size) { |
| 1580 | 1582 | 2 => try writer.writeInt(u16, @intCast(value), endian), |
| 1581 | 1583 | 4 => try writer.writeInt(u32, @intCast(value), endian), |
src/link/MachO.zig+78-48| ... | ... | @@ -143,7 +143,7 @@ tlv_table: TlvSymbolTable = .{}, |
| 143 | 143 | /// Hot-code swapping state. |
| 144 | 144 | hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, |
| 145 | 145 | |
| 146 | darwin_sdk_layout: ?SdkLayout, | |
| 146 | sdk_layout: ?SdkLayout, | |
| 147 | 147 | /// Size of the __PAGEZERO segment. |
| 148 | 148 | pagezero_vmsize: u64, |
| 149 | 149 | /// Minimum space for future expansion of the load commands. |
| ... | ... | @@ -184,20 +184,21 @@ pub const SdkLayout = enum { |
| 184 | 184 | |
| 185 | 185 | pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 186 | 186 | if (build_options.only_c) unreachable; |
| 187 | const target = options.comp.root_mod.resolved_target.result; | |
| 188 | const use_lld = build_options.have_llvm and options.comp.config.use_lld; | |
| 189 | const use_llvm = options.comp.config.use_llvm; | |
| 187 | const comp = options.comp; | |
| 188 | const target = comp.root_mod.resolved_target.result; | |
| 189 | const use_lld = build_options.have_llvm and comp.config.use_lld; | |
| 190 | const use_llvm = comp.config.use_llvm; | |
| 190 | 191 | assert(target.ofmt == .macho); |
| 191 | 192 | |
| 192 | const gpa = options.comp.gpa; | |
| 193 | const gpa = comp.gpa; | |
| 193 | 194 | const emit = options.emit; |
| 194 | 195 | const mode: Mode = mode: { |
| 195 | if (use_llvm or options.module == null or options.cache_mode == .whole) | |
| 196 | if (use_llvm or comp.module == null or comp.cache_mode == .whole) | |
| 196 | 197 | break :mode .zld; |
| 197 | 198 | break :mode .incremental; |
| 198 | 199 | }; |
| 199 | 200 | const sub_path = if (mode == .zld) blk: { |
| 200 | if (options.module == null) { | |
| 201 | if (comp.module == null) { | |
| 201 | 202 | // No point in opening a file, we would not write anything to it. |
| 202 | 203 | // Initialize with empty. |
| 203 | 204 | return createEmpty(arena, options); |
| ... | ... | @@ -225,13 +226,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 225 | 226 | .read = true, |
| 226 | 227 | .mode = link.File.determineMode( |
| 227 | 228 | use_lld, |
| 228 | options.comp.config.output_mode, | |
| 229 | options.comp.config.link_mode, | |
| 229 | comp.config.output_mode, | |
| 230 | comp.config.link_mode, | |
| 230 | 231 | ), |
| 231 | 232 | }); |
| 232 | 233 | self.base.file = file; |
| 233 | 234 | |
| 234 | if (!options.strip and options.module != null) { | |
| 235 | if (self.base.debug_format != .strip and comp.module != null) { | |
| 235 | 236 | // Create dSYM bundle. |
| 236 | 237 | log.debug("creating {s}.dSYM bundle", .{sub_path}); |
| 237 | 238 | |
| ... | ... | @@ -276,14 +277,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 276 | 277 | } |
| 277 | 278 | |
| 278 | 279 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 279 | const self = try arena.create(MachO); | |
| 280 | const optimize_mode = options.comp.root_mod.optimize_mode; | |
| 281 | const use_llvm = options.comp.config.use_llvm; | |
| 280 | const comp = options.comp; | |
| 281 | const optimize_mode = comp.root_mod.optimize_mode; | |
| 282 | const use_llvm = comp.config.use_llvm; | |
| 282 | 283 | |
| 284 | const self = try arena.create(MachO); | |
| 283 | 285 | self.* = .{ |
| 284 | 286 | .base = .{ |
| 285 | 287 | .tag = .macho, |
| 286 | .comp = options.comp, | |
| 288 | .comp = comp, | |
| 287 | 289 | .emit = options.emit, |
| 288 | 290 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), |
| 289 | 291 | .stack_size = options.stack_size orelse 16777216, |
| ... | ... | @@ -297,7 +299,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 297 | 299 | .function_sections = options.function_sections, |
| 298 | 300 | .data_sections = options.data_sections, |
| 299 | 301 | }, |
| 300 | .mode = if (use_llvm or options.module == null or options.cache_mode == .whole) | |
| 302 | .mode = if (use_llvm or comp.module == null or comp.cache_mode == .whole) | |
| 301 | 303 | .zld |
| 302 | 304 | else |
| 303 | 305 | .incremental, |
| ... | ... | @@ -305,9 +307,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO { |
| 305 | 307 | .headerpad_size = options.headerpad_size orelse default_headerpad_size, |
| 306 | 308 | .headerpad_max_install_names = options.headerpad_max_install_names, |
| 307 | 309 | .dead_strip_dylibs = options.dead_strip_dylibs, |
| 310 | .sdk_layout = options.darwin_sdk_layout, | |
| 311 | .frameworks = options.frameworks, | |
| 312 | .install_name = options.install_name, | |
| 313 | .entitlements = options.entitlements, | |
| 308 | 314 | }; |
| 309 | 315 | |
| 310 | if (use_llvm and options.module != null) { | |
| 316 | if (use_llvm and comp.module != null) { | |
| 311 | 317 | self.llvm_object = try LlvmObject.create(arena, options); |
| 312 | 318 | } |
| 313 | 319 | |
| ... | ... | @@ -357,6 +363,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 357 | 363 | |
| 358 | 364 | const output_mode = self.base.comp.config.output_mode; |
| 359 | 365 | const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| 366 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 360 | 367 | |
| 361 | 368 | if (self.lazy_syms.getPtr(.none)) |metadata| { |
| 362 | 369 | // Most lazy symbols can be updated on first use, but |
| ... | ... | @@ -569,7 +576,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 569 | 576 | // written out to the file. |
| 570 | 577 | // The most important here is to have the correct vm and filesize of the __LINKEDIT segment |
| 571 | 578 | // where the code signature goes into. |
| 572 | var codesig = CodeSignature.init(getPageSize(self.base.options.target.cpu.arch)); | |
| 579 | var codesig = CodeSignature.init(getPageSize(target.cpu.arch)); | |
| 573 | 580 | codesig.code_directory.ident = self.base.emit.sub_path; |
| 574 | 581 | if (self.entitlements) |path| { |
| 575 | 582 | try codesig.addEntitlements(gpa, path); |
| ... | ... | @@ -619,7 +626,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 619 | 626 | .version = 0, |
| 620 | 627 | }); |
| 621 | 628 | { |
| 622 | const platform = Platform.fromTarget(self.base.options.target); | |
| 629 | const platform = Platform.fromTarget(target); | |
| 623 | 630 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); |
| 624 | 631 | if (platform.isBuildVersionCompatible()) { |
| 625 | 632 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| ... | ... | @@ -701,7 +708,7 @@ pub fn resolveLibSystem( |
| 701 | 708 | var checked_paths = std.ArrayList([]const u8).init(arena); |
| 702 | 709 | |
| 703 | 710 | success: { |
| 704 | if (self.base.options.darwin_sdk_layout) |sdk_layout| switch (sdk_layout) { | |
| 711 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { | |
| 705 | 712 | .sdk => { |
| 706 | 713 | const dir = try fs.path.join(arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" }); |
| 707 | 714 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success; |
| ... | ... | @@ -817,6 +824,7 @@ fn parseObject( |
| 817 | 824 | defer tracy.end(); |
| 818 | 825 | |
| 819 | 826 | const gpa = self.base.comp.gpa; |
| 827 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 820 | 828 | const mtime: u64 = mtime: { |
| 821 | 829 | const stat = file.stat() catch break :mtime 0; |
| 822 | 830 | break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000))); |
| ... | ... | @@ -839,8 +847,8 @@ fn parseObject( |
| 839 | 847 | else => unreachable, |
| 840 | 848 | }; |
| 841 | 849 | const detected_platform = object.getPlatform(); |
| 842 | const this_cpu_arch = self.base.options.target.cpu.arch; | |
| 843 | const this_platform = Platform.fromTarget(self.base.options.target); | |
| 850 | const this_cpu_arch = target.cpu.arch; | |
| 851 | const this_platform = Platform.fromTarget(target); | |
| 844 | 852 | |
| 845 | 853 | if (this_cpu_arch != detected_cpu_arch or |
| 846 | 854 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -867,8 +875,10 @@ pub fn parseLibrary( |
| 867 | 875 | const tracy = trace(@src()); |
| 868 | 876 | defer tracy.end(); |
| 869 | 877 | |
| 878 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 879 | ||
| 870 | 880 | if (fat.isFatLibrary(file)) { |
| 871 | const offset = try self.parseFatLibrary(file, self.base.options.target.cpu.arch, ctx); | |
| 881 | const offset = try self.parseFatLibrary(file, target.cpu.arch, ctx); | |
| 872 | 882 | try file.seekTo(offset); |
| 873 | 883 | |
| 874 | 884 | if (Archive.isArchive(file, offset)) { |
| ... | ... | @@ -934,6 +944,7 @@ fn parseArchive( |
| 934 | 944 | ctx: *ParseErrorCtx, |
| 935 | 945 | ) ParseError!void { |
| 936 | 946 | const gpa = self.base.comp.gpa; |
| 947 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 937 | 948 | |
| 938 | 949 | // We take ownership of the file so that we can store it for the duration of symbol resolution. |
| 939 | 950 | // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF? |
| ... | ... | @@ -963,8 +974,8 @@ fn parseArchive( |
| 963 | 974 | else => unreachable, |
| 964 | 975 | }; |
| 965 | 976 | const detected_platform = object.getPlatform(); |
| 966 | const this_cpu_arch = self.base.options.target.cpu.arch; | |
| 967 | const this_platform = Platform.fromTarget(self.base.options.target); | |
| 977 | const this_cpu_arch = target.cpu.arch; | |
| 978 | const this_platform = Platform.fromTarget(target); | |
| 968 | 979 | |
| 969 | 980 | if (this_cpu_arch != detected_cpu_arch or |
| 970 | 981 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -1015,6 +1026,7 @@ fn parseDylib( |
| 1015 | 1026 | ctx: *ParseErrorCtx, |
| 1016 | 1027 | ) ParseError!void { |
| 1017 | 1028 | const gpa = self.base.comp.gpa; |
| 1029 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1018 | 1030 | const file_stat = try file.stat(); |
| 1019 | 1031 | const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow; |
| 1020 | 1032 | |
| ... | ... | @@ -1038,8 +1050,8 @@ fn parseDylib( |
| 1038 | 1050 | else => unreachable, |
| 1039 | 1051 | }; |
| 1040 | 1052 | const detected_platform = dylib.getPlatform(contents); |
| 1041 | const this_cpu_arch = self.base.options.target.cpu.arch; | |
| 1042 | const this_platform = Platform.fromTarget(self.base.options.target); | |
| 1053 | const this_cpu_arch = target.cpu.arch; | |
| 1054 | const this_platform = Platform.fromTarget(target); | |
| 1043 | 1055 | |
| 1044 | 1056 | if (this_cpu_arch != detected_cpu_arch or |
| 1045 | 1057 | (detected_platform != null and !detected_platform.?.eqlTarget(this_platform))) |
| ... | ... | @@ -1061,6 +1073,8 @@ fn parseLibStub( |
| 1061 | 1073 | ctx: *ParseErrorCtx, |
| 1062 | 1074 | ) ParseError!void { |
| 1063 | 1075 | const gpa = self.base.comp.gpa; |
| 1076 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1077 | ||
| 1064 | 1078 | var lib_stub = try LibStub.loadFromFile(gpa, file); |
| 1065 | 1079 | defer lib_stub.deinit(); |
| 1066 | 1080 | |
| ... | ... | @@ -1068,7 +1082,7 @@ fn parseLibStub( |
| 1068 | 1082 | |
| 1069 | 1083 | // Verify target |
| 1070 | 1084 | { |
| 1071 | var matcher = try Dylib.TargetMatcher.init(gpa, self.base.options.target); | |
| 1085 | var matcher = try Dylib.TargetMatcher.init(gpa, target); | |
| 1072 | 1086 | defer matcher.deinit(); |
| 1073 | 1087 | |
| 1074 | 1088 | const first_tbd = lib_stub.inner[0]; |
| ... | ... | @@ -1091,7 +1105,7 @@ fn parseLibStub( |
| 1091 | 1105 | |
| 1092 | 1106 | try dylib.parseFromStub( |
| 1093 | 1107 | gpa, |
| 1094 | self.base.options.target, | |
| 1108 | target, | |
| 1095 | 1109 | lib_stub, |
| 1096 | 1110 | @intCast(self.dylibs.items.len), // TODO defer it till later |
| 1097 | 1111 | dependent_libs, |
| ... | ... | @@ -1236,7 +1250,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1236 | 1250 | |
| 1237 | 1251 | fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void { |
| 1238 | 1252 | const segment = self.segments.items[segment_index]; |
| 1239 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 1253 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1254 | const cpu_arch = target.cpu.arch; | |
| 1240 | 1255 | const nwritten = if (!segment.isWriteable()) |
| 1241 | 1256 | try task.writeMemProtected(addr, code, cpu_arch) |
| 1242 | 1257 | else |
| ... | ... | @@ -1280,7 +1295,8 @@ fn writeStubHelperPreamble(self: *MachO) !void { |
| 1280 | 1295 | if (self.stub_helper_preamble_allocated) return; |
| 1281 | 1296 | |
| 1282 | 1297 | const gpa = self.base.comp.gpa; |
| 1283 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 1298 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1299 | const cpu_arch = target.cpu.arch; | |
| 1284 | 1300 | const size = stubs.stubHelperPreambleSize(cpu_arch); |
| 1285 | 1301 | |
| 1286 | 1302 | var buf = try std.ArrayList(u8).initCapacity(gpa, size); |
| ... | ... | @@ -1306,11 +1322,12 @@ fn writeStubHelperPreamble(self: *MachO) !void { |
| 1306 | 1322 | } |
| 1307 | 1323 | |
| 1308 | 1324 | fn writeStubTableEntry(self: *MachO, index: usize) !void { |
| 1325 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 1309 | 1326 | const stubs_sect_id = self.stubs_section_index.?; |
| 1310 | 1327 | const stub_helper_sect_id = self.stub_helper_section_index.?; |
| 1311 | 1328 | const laptr_sect_id = self.la_symbol_ptr_section_index.?; |
| 1312 | 1329 | |
| 1313 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 1330 | const cpu_arch = target.cpu.arch; | |
| 1314 | 1331 | const stub_entry_size = stubs.stubSize(cpu_arch); |
| 1315 | 1332 | const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch); |
| 1316 | 1333 | const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch); |
| ... | ... | @@ -2243,7 +2260,7 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2243 | 2260 | .flags = macho.S_SYMBOL_STUBS | |
| 2244 | 2261 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 2245 | 2262 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2246 | .reserved2 = stubs.stubSize(self.base.options.target.cpu.arch), | |
| 2263 | .reserved2 = stubs.stubSize(target.cpu.arch), | |
| 2247 | 2264 | }); |
| 2248 | 2265 | self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{ |
| 2249 | 2266 | .flags = macho.S_REGULAR | |
| ... | ... | @@ -3116,7 +3133,8 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3116 | 3133 | assert(self.mode == .incremental); |
| 3117 | 3134 | |
| 3118 | 3135 | const gpa = self.base.comp.gpa; |
| 3119 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 3136 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3137 | const cpu_arch = target.cpu.arch; | |
| 3120 | 3138 | const pagezero_vmsize = self.calcPagezeroSize(); |
| 3121 | 3139 | |
| 3122 | 3140 | if (self.pagezero_segment_cmd_index == null) { |
| ... | ... | @@ -3263,7 +3281,8 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 3263 | 3281 | |
| 3264 | 3282 | fn calcPagezeroSize(self: *MachO) u64 { |
| 3265 | 3283 | const output_mode = self.base.comp.config.output_mode; |
| 3266 | const page_size = getPageSize(self.base.options.target.cpu.arch); | |
| 3284 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3285 | const page_size = getPageSize(target.cpu.arch); | |
| 3267 | 3286 | const aligned_pagezero_vmsize = mem.alignBackward(u64, self.pagezero_vmsize, page_size); |
| 3268 | 3287 | if (output_mode == .Lib) return 0; |
| 3269 | 3288 | if (aligned_pagezero_vmsize == 0) return 0; |
| ... | ... | @@ -3305,7 +3324,8 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 3305 | 3324 | reserved2: u32 = 0, |
| 3306 | 3325 | }) !u8 { |
| 3307 | 3326 | const gpa = self.base.comp.gpa; |
| 3308 | const page_size = getPageSize(self.base.options.target.cpu.arch); | |
| 3327 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3328 | const page_size = getPageSize(target.cpu.arch); | |
| 3309 | 3329 | // In incremental context, we create one section per segment pairing. This way, |
| 3310 | 3330 | // we can move the segment in raw file as we please. |
| 3311 | 3331 | const segment_id = @as(u8, @intCast(self.segments.items.len)); |
| ... | ... | @@ -3360,7 +3380,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 3360 | 3380 | const segment = &self.segments.items[segment_index]; |
| 3361 | 3381 | const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; |
| 3362 | 3382 | const sect_capacity = self.allocatedSize(header.offset); |
| 3363 | const page_size = getPageSize(self.base.options.target.cpu.arch); | |
| 3383 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3384 | const page_size = getPageSize(target.cpu.arch); | |
| 3364 | 3385 | |
| 3365 | 3386 | if (needed_size > sect_capacity) { |
| 3366 | 3387 | const new_offset = self.findFreeSpace(needed_size, page_size); |
| ... | ... | @@ -3400,7 +3421,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 3400 | 3421 | } |
| 3401 | 3422 | |
| 3402 | 3423 | fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 3403 | const page_size = getPageSize(self.base.options.target.cpu.arch); | |
| 3424 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3425 | const page_size = getPageSize(target.cpu.arch); | |
| 3404 | 3426 | const header = &self.sections.items(.header)[sect_id]; |
| 3405 | 3427 | const segment = self.getSegmentPtr(sect_id); |
| 3406 | 3428 | const increased_size = padToIdeal(needed_size); |
| ... | ... | @@ -3611,7 +3633,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void { |
| 3611 | 3633 | } |
| 3612 | 3634 | |
| 3613 | 3635 | pub fn writeLinkeditSegmentData(self: *MachO) !void { |
| 3614 | const page_size = getPageSize(self.base.options.target.cpu.arch); | |
| 3636 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3637 | const page_size = getPageSize(target.cpu.arch); | |
| 3615 | 3638 | const seg = self.getLinkeditSegmentPtr(); |
| 3616 | 3639 | seg.filesize = 0; |
| 3617 | 3640 | seg.vmsize = 0; |
| ... | ... | @@ -3698,7 +3721,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3698 | 3721 | } |
| 3699 | 3722 | |
| 3700 | 3723 | // Finally, unpack the rest. |
| 3701 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 3724 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3725 | const cpu_arch = target.cpu.arch; | |
| 3702 | 3726 | for (self.objects.items) |*object| { |
| 3703 | 3727 | for (object.atoms.items) |atom_index| { |
| 3704 | 3728 | const atom = self.getAtom(atom_index); |
| ... | ... | @@ -3744,14 +3768,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { |
| 3744 | 3768 | }, |
| 3745 | 3769 | else => unreachable, |
| 3746 | 3770 | } |
| 3747 | const target = Atom.parseRelocTarget(self, .{ | |
| 3771 | const reloc_target = Atom.parseRelocTarget(self, .{ | |
| 3748 | 3772 | .object_id = atom.getFile().?, |
| 3749 | 3773 | .rel = rel, |
| 3750 | 3774 | .code = code, |
| 3751 | 3775 | .base_offset = ctx.base_offset, |
| 3752 | 3776 | .base_addr = ctx.base_addr, |
| 3753 | 3777 | }); |
| 3754 | const target_sym = self.getSymbol(target); | |
| 3778 | const target_sym = self.getSymbol(reloc_target); | |
| 3755 | 3779 | if (target_sym.undf()) continue; |
| 3756 | 3780 | |
| 3757 | 3781 | const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr)); |
| ... | ... | @@ -3853,7 +3877,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void { |
| 3853 | 3877 | } |
| 3854 | 3878 | |
| 3855 | 3879 | // Finally, unpack the rest. |
| 3856 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 3880 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 3881 | const cpu_arch = target.cpu.arch; | |
| 3857 | 3882 | for (self.objects.items) |*object| { |
| 3858 | 3883 | for (object.atoms.items) |atom_index| { |
| 3859 | 3884 | const atom = self.getAtom(atom_index); |
| ... | ... | @@ -4072,7 +4097,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void { |
| 4072 | 4097 | |
| 4073 | 4098 | const header = self.sections.items(.header)[stub_helper_section_index]; |
| 4074 | 4099 | |
| 4075 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 4100 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4101 | const cpu_arch = target.cpu.arch; | |
| 4076 | 4102 | const preamble_size = stubs.stubHelperPreambleSize(cpu_arch); |
| 4077 | 4103 | const stub_size = stubs.stubHelperSize(cpu_arch); |
| 4078 | 4104 | const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch); |
| ... | ... | @@ -4708,13 +4734,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h |
| 4708 | 4734 | } |
| 4709 | 4735 | |
| 4710 | 4736 | pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void { |
| 4737 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4711 | 4738 | const seg = self.getLinkeditSegmentPtr(); |
| 4712 | 4739 | // Code signature data has to be 16-bytes aligned for Apple tools to recognize the file |
| 4713 | 4740 | // https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L271 |
| 4714 | 4741 | const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16); |
| 4715 | 4742 | const needed_size = code_sig.estimateSize(offset); |
| 4716 | 4743 | seg.filesize = offset + needed_size - seg.fileoff; |
| 4717 | seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(self.base.options.target.cpu.arch)); | |
| 4744 | seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(target.cpu.arch)); | |
| 4718 | 4745 | log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size }); |
| 4719 | 4746 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 4720 | 4747 | // except for code signature data. |
| ... | ... | @@ -4758,7 +4785,8 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 4758 | 4785 | var header: macho.mach_header_64 = .{}; |
| 4759 | 4786 | header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL; |
| 4760 | 4787 | |
| 4761 | switch (self.base.options.target.cpu.arch) { | |
| 4788 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 4789 | switch (target.cpu.arch) { | |
| 4762 | 4790 | .aarch64 => { |
| 4763 | 4791 | header.cputype = macho.CPU_TYPE_ARM64; |
| 4764 | 4792 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | ... | @@ -5123,9 +5151,10 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5123 | 5151 | } |
| 5124 | 5152 | |
| 5125 | 5153 | pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 { |
| 5154 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 5126 | 5155 | const index = self.stub_table.lookup.get(sym_with_loc) orelse return null; |
| 5127 | 5156 | const header = self.sections.items(.header)[self.stubs_section_index.?]; |
| 5128 | return header.addr + stubs.stubSize(self.base.options.target.cpu.arch) * index; | |
| 5157 | return header.addr + stubs.stubSize(target.cpu.arch) * index; | |
| 5129 | 5158 | } |
| 5130 | 5159 | |
| 5131 | 5160 | /// Returns symbol location corresponding to the set entrypoint if any. |
| ... | ... | @@ -5234,8 +5263,9 @@ pub fn handleAndReportParseError( |
| 5234 | 5263 | err: ParseError, |
| 5235 | 5264 | ctx: *const ParseErrorCtx, |
| 5236 | 5265 | ) error{OutOfMemory}!void { |
| 5266 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 5237 | 5267 | const gpa = self.base.comp.gpa; |
| 5238 | const cpu_arch = self.base.options.target.cpu.arch; | |
| 5268 | const cpu_arch = target.cpu.arch; | |
| 5239 | 5269 | switch (err) { |
| 5240 | 5270 | error.DylibAlreadyExists => {}, |
| 5241 | 5271 | error.IncompatibleDylibVersion => { |
| ... | ... | @@ -5270,7 +5300,7 @@ pub fn handleAndReportParseError( |
| 5270 | 5300 | error.InvalidTarget => try self.reportParseError( |
| 5271 | 5301 | path, |
| 5272 | 5302 | "invalid target: expected '{}', but found '{s}'", |
| 5273 | .{ Platform.fromTarget(self.base.options.target).fmtTarget(cpu_arch), targets_string.items }, | |
| 5303 | .{ Platform.fromTarget(target).fmtTarget(cpu_arch), targets_string.items }, | |
| 5274 | 5304 | ), |
| 5275 | 5305 | error.InvalidTargetFatLibrary => try self.reportParseError( |
| 5276 | 5306 | path, |
src/link/MachO/Atom.zig+17-11| ... | ... | @@ -387,7 +387,8 @@ pub fn calcInnerSymbolOffset(macho_file: *MachO, atom_index: Index, sym_index: u |
| 387 | 387 | } |
| 388 | 388 | |
| 389 | 389 | pub fn scanAtomRelocs(macho_file: *MachO, atom_index: Index, relocs: []align(1) const macho.relocation_info) !void { |
| 390 | const arch = macho_file.base.options.target.cpu.arch; | |
| 390 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 391 | const arch = target.cpu.arch; | |
| 391 | 392 | const atom = macho_file.getAtom(atom_index); |
| 392 | 393 | assert(atom.getFile() != null); // synthetic atoms do not have relocs |
| 393 | 394 | |
| ... | ... | @@ -434,6 +435,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 434 | 435 | const tracy = trace(@src()); |
| 435 | 436 | defer tracy.end(); |
| 436 | 437 | |
| 438 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 437 | 439 | const object = &macho_file.objects.items[ctx.object_id]; |
| 438 | 440 | log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name }); |
| 439 | 441 | |
| ... | ... | @@ -447,7 +449,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 447 | 449 | else |
| 448 | 450 | mem.readInt(u32, ctx.code[rel_offset..][0..4], .little); |
| 449 | 451 | } else blk: { |
| 450 | assert(macho_file.base.options.target.cpu.arch == .x86_64); | |
| 452 | assert(target.cpu.arch == .x86_64); | |
| 451 | 453 | const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) { |
| 452 | 454 | .X86_64_RELOC_SIGNED => 0, |
| 453 | 455 | .X86_64_RELOC_SIGNED_1 => 1, |
| ... | ... | @@ -467,18 +469,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct { |
| 467 | 469 | |
| 468 | 470 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 }; |
| 469 | 471 | const sym = macho_file.getSymbol(sym_loc); |
| 470 | const target = if (sym.sect() and !sym.ext()) | |
| 472 | const reloc_target = if (sym.sect() and !sym.ext()) | |
| 471 | 473 | sym_loc |
| 472 | 474 | else if (object.getGlobal(sym_index)) |global_index| |
| 473 | 475 | macho_file.globals.items[global_index] |
| 474 | 476 | else |
| 475 | 477 | sym_loc; |
| 476 | 478 | log.debug(" | target %{d} ('{s}') in object({?d})", .{ |
| 477 | target.sym_index, | |
| 478 | macho_file.getSymbolName(target), | |
| 479 | target.getFile(), | |
| 479 | reloc_target.sym_index, | |
| 480 | macho_file.getSymbolName(reloc_target), | |
| 481 | reloc_target.getFile(), | |
| 480 | 482 | }); |
| 481 | return target; | |
| 483 | return reloc_target; | |
| 482 | 484 | } |
| 483 | 485 | |
| 484 | 486 | pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index { |
| ... | ... | @@ -599,7 +601,8 @@ pub fn resolveRelocs( |
| 599 | 601 | atom_code: []u8, |
| 600 | 602 | atom_relocs: []align(1) const macho.relocation_info, |
| 601 | 603 | ) !void { |
| 602 | const arch = macho_file.base.options.target.cpu.arch; | |
| 604 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 605 | const arch = target.cpu.arch; | |
| 603 | 606 | const atom = macho_file.getAtom(atom_index); |
| 604 | 607 | assert(atom.getFile() != null); // synthetic atoms do not have relocs |
| 605 | 608 | |
| ... | ... | @@ -1192,7 +1195,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca |
| 1192 | 1195 | } |
| 1193 | 1196 | |
| 1194 | 1197 | pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1195 | switch (macho_file.base.options.target.cpu.arch) { | |
| 1198 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 1199 | switch (target.cpu.arch) { | |
| 1196 | 1200 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1197 | 1201 | .ARM64_RELOC_GOT_LOAD_PAGE21, |
| 1198 | 1202 | .ARM64_RELOC_GOT_LOAD_PAGEOFF12, |
| ... | ... | @@ -1211,7 +1215,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1211 | 1215 | } |
| 1212 | 1216 | |
| 1213 | 1217 | pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1214 | switch (macho_file.base.options.target.cpu.arch) { | |
| 1218 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 1219 | switch (target.cpu.arch) { | |
| 1215 | 1220 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1216 | 1221 | .ARM64_RELOC_TLVP_LOAD_PAGE21, |
| 1217 | 1222 | .ARM64_RELOC_TLVP_LOAD_PAGEOFF12, |
| ... | ... | @@ -1227,7 +1232,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1227 | 1232 | } |
| 1228 | 1233 | |
| 1229 | 1234 | pub fn relocIsStub(macho_file: *MachO, rel: macho.relocation_info) bool { |
| 1230 | switch (macho_file.base.options.target.cpu.arch) { | |
| 1235 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 1236 | switch (target.cpu.arch) { | |
| 1231 | 1237 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 1232 | 1238 | .ARM64_RELOC_BRANCH26 => return true, |
| 1233 | 1239 | else => return false, |
src/link/MachO/DebugSymbols.zig+10-4| ... | ... | @@ -39,10 +39,12 @@ pub const Reloc = struct { |
| 39 | 39 | /// You must call this function *after* `MachO.populateMissingMetadata()` |
| 40 | 40 | /// has been called to get a viable debug symbols output. |
| 41 | 41 | pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void { |
| 42 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 43 | ||
| 42 | 44 | if (self.dwarf_segment_cmd_index == null) { |
| 43 | 45 | self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len)); |
| 44 | 46 | |
| 45 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 47 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 46 | 48 | const off = @as(u64, @intCast(page_size)); |
| 47 | 49 | const ideal_size: u16 = 200 + 128 + 160 + 250; |
| 48 | 50 | const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size); |
| ... | ... | @@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void { |
| 332 | 334 | file_size = @max(file_size, header.offset + header.size); |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 337 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 338 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 336 | 339 | const aligned_size = mem.alignForward(u64, file_size, page_size); |
| 337 | 340 | dwarf_segment.vmaddr = base_vmaddr; |
| 338 | 341 | dwarf_segment.filesize = aligned_size; |
| ... | ... | @@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype) |
| 394 | 397 | } |
| 395 | 398 | |
| 396 | 399 | fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 400 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 401 | ||
| 397 | 402 | var header: macho.mach_header_64 = .{}; |
| 398 | 403 | header.filetype = macho.MH_DSYM; |
| 399 | 404 | |
| 400 | switch (macho_file.base.options.target.cpu.arch) { | |
| 405 | switch (target.cpu.arch) { | |
| 401 | 406 | .aarch64 => { |
| 402 | 407 | header.cputype = macho.CPU_TYPE_ARM64; |
| 403 | 408 | header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL; |
| ... | ... | @@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void { |
| 435 | 440 | try self.writeSymtab(macho_file); |
| 436 | 441 | try self.writeStrtab(); |
| 437 | 442 | |
| 438 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 443 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 444 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 439 | 445 | const seg = &self.segments.items[self.linkedit_segment_cmd_index.?]; |
| 440 | 446 | const aligned_size = mem.alignForward(u64, seg.filesize, page_size); |
| 441 | 447 | seg.vmsize = aligned_size; |
src/link/MachO/Object.zig+18-15| ... | ... | @@ -355,6 +355,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIn |
| 355 | 355 | /// into subsections where each subsection then represents an Atom. |
| 356 | 356 | pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 357 | 357 | const gpa = macho_file.base.allocator; |
| 358 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 358 | 359 | |
| 359 | 360 | const sections = self.getSourceSections(); |
| 360 | 361 | for (sections, 0..) |sect, id| { |
| ... | ... | @@ -448,7 +449,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) ! |
| 448 | 449 | |
| 449 | 450 | try self.parseRelocs(gpa, section.id); |
| 450 | 451 | |
| 451 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 452 | const cpu_arch = target.cpu.arch; | |
| 452 | 453 | const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1); |
| 453 | 454 | const sect_start_index = sect_sym_index + sect_loc.index; |
| 454 | 455 | |
| ... | ... | @@ -676,7 +677,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 676 | 677 | macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{}); |
| 677 | 678 | } |
| 678 | 679 | |
| 679 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 680 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 681 | const cpu_arch = target.cpu.arch; | |
| 680 | 682 | try self.parseRelocs(gpa, sect_id); |
| 681 | 683 | const relocs = self.getRelocs(sect_id); |
| 682 | 684 | |
| ... | ... | @@ -704,7 +706,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 704 | 706 | }); |
| 705 | 707 | |
| 706 | 708 | if (record.tag == .fde) { |
| 707 | const target = blk: { | |
| 709 | const reloc_target = blk: { | |
| 708 | 710 | switch (cpu_arch) { |
| 709 | 711 | .aarch64 => { |
| 710 | 712 | assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed |
| ... | ... | @@ -714,13 +716,13 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 714 | 716 | @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED) |
| 715 | 717 | break rel; |
| 716 | 718 | } else unreachable; |
| 717 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 719 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 718 | 720 | .object_id = object_id, |
| 719 | 721 | .rel = rel, |
| 720 | 722 | .code = it.data[offset..], |
| 721 | 723 | .base_offset = @as(i32, @intCast(offset)), |
| 722 | 724 | }); |
| 723 | break :blk target; | |
| 725 | break :blk reloc_target; | |
| 724 | 726 | }, |
| 725 | 727 | .x86_64 => { |
| 726 | 728 | const target_address = record.getTargetSymbolAddress(.{ |
| ... | ... | @@ -728,16 +730,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 728 | 730 | .base_offset = offset, |
| 729 | 731 | }); |
| 730 | 732 | const target_sym_index = self.getSymbolByAddress(target_address, null); |
| 731 | const target = if (self.getGlobal(target_sym_index)) |global_index| | |
| 733 | const reloc_target = if (self.getGlobal(target_sym_index)) |global_index| | |
| 732 | 734 | macho_file.globals.items[global_index] |
| 733 | 735 | else |
| 734 | 736 | SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 }; |
| 735 | break :blk target; | |
| 737 | break :blk reloc_target; | |
| 736 | 738 | }, |
| 737 | 739 | else => unreachable, |
| 738 | 740 | } |
| 739 | 741 | }; |
| 740 | if (target.getFile() != object_id) { | |
| 742 | if (reloc_target.getFile() != object_id) { | |
| 741 | 743 | log.debug("FDE at offset {x} marked DEAD", .{offset}); |
| 742 | 744 | self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true; |
| 743 | 745 | } else { |
| ... | ... | @@ -746,12 +748,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 746 | 748 | // very problematic when using Zig's @export feature to re-export symbols under |
| 747 | 749 | // additional names. For that reason, we need to ensure we record aliases here |
| 748 | 750 | // too so that we can tie them with their matching unwind records and vice versa. |
| 749 | const aliases = self.getSymbolAliases(target.sym_index); | |
| 751 | const aliases = self.getSymbolAliases(reloc_target.sym_index); | |
| 750 | 752 | var i: u32 = 0; |
| 751 | 753 | while (i < aliases.len) : (i += 1) { |
| 752 | 754 | const actual_target = SymbolWithLoc{ |
| 753 | 755 | .sym_index = i + aliases.start, |
| 754 | .file = target.file, | |
| 756 | .file = reloc_target.file, | |
| 755 | 757 | }; |
| 756 | 758 | log.debug("FDE at offset {x} tracks {s}", .{ |
| 757 | 759 | offset, |
| ... | ... | @@ -766,7 +768,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 766 | 768 | |
| 767 | 769 | fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 768 | 770 | const gpa = macho_file.base.allocator; |
| 769 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 771 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 772 | const cpu_arch = target.cpu.arch; | |
| 770 | 773 | const sect_id = self.unwind_info_sect_id orelse { |
| 771 | 774 | // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`, |
| 772 | 775 | // we will try fully synthesising unwind info records to somewhat match Apple ld's |
| ... | ... | @@ -818,13 +821,13 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 818 | 821 | |
| 819 | 822 | // Find function symbol that this record describes |
| 820 | 823 | const rel = relocs[rel_pos.start..][rel_pos.len - 1]; |
| 821 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 824 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 822 | 825 | .object_id = object_id, |
| 823 | 826 | .rel = rel, |
| 824 | 827 | .code = mem.asBytes(&record), |
| 825 | 828 | .base_offset = @as(i32, @intCast(offset)), |
| 826 | 829 | }); |
| 827 | if (target.getFile() != object_id) { | |
| 830 | if (reloc_target.getFile() != object_id) { | |
| 828 | 831 | log.debug("unwind record {d} marked DEAD", .{record_id}); |
| 829 | 832 | self.unwind_relocs_lookup[record_id].dead = true; |
| 830 | 833 | } else { |
| ... | ... | @@ -833,12 +836,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 833 | 836 | // very problematic when using Zig's @export feature to re-export symbols under |
| 834 | 837 | // additional names. For that reason, we need to ensure we record aliases here |
| 835 | 838 | // too so that we can tie them with their matching unwind records and vice versa. |
| 836 | const aliases = self.getSymbolAliases(target.sym_index); | |
| 839 | const aliases = self.getSymbolAliases(reloc_target.sym_index); | |
| 837 | 840 | var i: u32 = 0; |
| 838 | 841 | while (i < aliases.len) : (i += 1) { |
| 839 | 842 | const actual_target = SymbolWithLoc{ |
| 840 | 843 | .sym_index = i + aliases.start, |
| 841 | .file = target.file, | |
| 844 | .file = reloc_target.file, | |
| 842 | 845 | }; |
| 843 | 846 | log.debug("unwind record {d} tracks {s}", .{ |
| 844 | 847 | record_id, |
src/link/MachO/Relocation.zig+4-2| ... | ... | @@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool { |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 { |
| 61 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 61 | 62 | if (self.isStubTrampoline(macho_file)) { |
| 62 | 63 | const index = macho_file.stub_table.lookup.get(self.target) orelse return null; |
| 63 | 64 | const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?]; |
| 64 | 65 | return header.addr + |
| 65 | index * @import("stubs.zig").stubSize(macho_file.base.options.target.cpu.arch); | |
| 66 | index * @import("stubs.zig").stubSize(target.cpu.arch); | |
| 66 | 67 | } |
| 67 | 68 | switch (self.type) { |
| 68 | 69 | .got, .got_page, .got_pageoff => { |
| ... | ... | @@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 { |
| 84 | 85 | } |
| 85 | 86 | |
| 86 | 87 | pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void { |
| 87 | const arch = macho_file.base.options.target.cpu.arch; | |
| 88 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 89 | const arch = target.cpu.arch; | |
| 88 | 90 | const atom = macho_file.getAtom(atom_index); |
| 89 | 91 | const source_sym = atom.getSymbol(macho_file); |
| 90 | 92 | const source_addr = source_sym.n_value + self.offset; |
src/link/MachO/UnwindInfo.zig+16-13| ... | ... | @@ -184,7 +184,8 @@ pub fn deinit(info: *UnwindInfo) void { |
| 184 | 184 | pub fn scanRelocs(macho_file: *MachO) !void { |
| 185 | 185 | if (macho_file.unwind_info_section_index == null) return; |
| 186 | 186 | |
| 187 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 187 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 188 | const cpu_arch = target.cpu.arch; | |
| 188 | 189 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| 189 | 190 | const unwind_records = object.getUnwindRecords(); |
| 190 | 191 | for (object.exec_atoms.items) |atom_index| { |
| ... | ... | @@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void { |
| 196 | 197 | if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) { |
| 197 | 198 | if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| { |
| 198 | 199 | // Personality function; add GOT pointer. |
| 199 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 200 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 200 | 201 | .object_id = @as(u32, @intCast(object_id)), |
| 201 | 202 | .rel = rel, |
| 202 | 203 | .code = mem.asBytes(&record), |
| 203 | 204 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 204 | 205 | }); |
| 205 | try macho_file.addGotEntry(target); | |
| 206 | try macho_file.addGotEntry(reloc_target); | |
| 206 | 207 | } |
| 207 | 208 | } |
| 208 | 209 | } |
| ... | ... | @@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void { |
| 213 | 214 | pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 214 | 215 | if (macho_file.unwind_info_section_index == null) return; |
| 215 | 216 | |
| 216 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 217 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 218 | const cpu_arch = target.cpu.arch; | |
| 217 | 219 | |
| 218 | 220 | var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa); |
| 219 | 221 | defer records.deinit(); |
| ... | ... | @@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 247 | 249 | @as(u32, @intCast(object_id)), |
| 248 | 250 | record_id, |
| 249 | 251 | )) |rel| { |
| 250 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 252 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 251 | 253 | .object_id = @as(u32, @intCast(object_id)), |
| 252 | 254 | .rel = rel, |
| 253 | 255 | .code = mem.asBytes(&record), |
| 254 | 256 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 255 | 257 | }); |
| 256 | const personality_index = info.getPersonalityFunction(target) orelse inner: { | |
| 258 | const personality_index = info.getPersonalityFunction(reloc_target) orelse inner: { | |
| 257 | 259 | const personality_index = info.personalities_count; |
| 258 | info.personalities[personality_index] = target; | |
| 260 | info.personalities[personality_index] = reloc_target; | |
| 259 | 261 | info.personalities_count += 1; |
| 260 | 262 | break :inner personality_index; |
| 261 | 263 | }; |
| ... | ... | @@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void { |
| 265 | 267 | } |
| 266 | 268 | |
| 267 | 269 | if (getLsdaReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| { |
| 268 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 270 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 269 | 271 | .object_id = @as(u32, @intCast(object_id)), |
| 270 | 272 | .rel = rel, |
| 271 | 273 | .code = mem.asBytes(&record), |
| 272 | 274 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 273 | 275 | }); |
| 274 | record.lsda = @as(u64, @bitCast(target)); | |
| 276 | record.lsda = @as(u64, @bitCast(reloc_target)); | |
| 275 | 277 | } |
| 276 | 278 | } |
| 277 | 279 | break :blk record; |
| ... | ... | @@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void { |
| 557 | 559 | const text_sect = macho_file.sections.items(.header)[text_sect_id]; |
| 558 | 560 | |
| 559 | 561 | var personalities: [max_personalities]u32 = undefined; |
| 560 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 562 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 563 | const cpu_arch = target.cpu.arch; | |
| 561 | 564 | |
| 562 | 565 | log.debug("Personalities:", .{}); |
| 563 | for (info.personalities[0..info.personalities_count], 0..) |target, i| { | |
| 564 | const addr = macho_file.getGotEntryAddress(target).?; | |
| 566 | for (info.personalities[0..info.personalities_count], 0..) |reloc_target, i| { | |
| 567 | const addr = macho_file.getGotEntryAddress(reloc_target).?; | |
| 565 | 568 | personalities[i] = @as(u32, @intCast(addr - seg.vmaddr)); |
| 566 | log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(target) }); | |
| 569 | log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(reloc_target) }); | |
| 567 | 570 | } |
| 568 | 571 | |
| 569 | 572 | for (info.records.items) |*rec| { |
src/link/MachO/dead_strip.zig+33-29| ... | ... | @@ -118,7 +118,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void |
| 118 | 118 | |
| 119 | 119 | alive.putAssumeCapacityNoClobber(atom_index, {}); |
| 120 | 120 | |
| 121 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 121 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 122 | const cpu_arch = target.cpu.arch; | |
| 122 | 123 | |
| 123 | 124 | const sym = macho_file.getSymbol(atom.getSymbolWithLoc()); |
| 124 | 125 | const header = macho_file.sections.items(.header)[sym.n_sect - 1]; |
| ... | ... | @@ -129,7 +130,7 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void |
| 129 | 130 | const ctx = Atom.getRelocContext(macho_file, atom_index); |
| 130 | 131 | |
| 131 | 132 | for (relocs) |rel| { |
| 132 | const target = switch (cpu_arch) { | |
| 133 | const reloc_target = switch (cpu_arch) { | |
| 133 | 134 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 134 | 135 | .ARM64_RELOC_ADDEND => continue, |
| 135 | 136 | else => Atom.parseRelocTarget(macho_file, .{ |
| ... | ... | @@ -149,19 +150,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void |
| 149 | 150 | }), |
| 150 | 151 | else => unreachable, |
| 151 | 152 | }; |
| 152 | const target_sym = macho_file.getSymbol(target); | |
| 153 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 153 | 154 | |
| 154 | 155 | if (target_sym.undf()) continue; |
| 155 | if (target.getFile() == null) { | |
| 156 | const target_sym_name = macho_file.getSymbolName(target); | |
| 156 | if (reloc_target.getFile() == null) { | |
| 157 | const target_sym_name = macho_file.getSymbolName(reloc_target); | |
| 157 | 158 | if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue; |
| 158 | 159 | if (mem.eql(u8, "___dso_handle", target_sym_name)) continue; |
| 159 | 160 | |
| 160 | 161 | unreachable; // referenced symbol not found |
| 161 | 162 | } |
| 162 | 163 | |
| 163 | const object = macho_file.objects.items[target.getFile().?]; | |
| 164 | const target_atom_index = object.getAtomIndexForSymbol(target.sym_index).?; | |
| 164 | const object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 165 | const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index).?; | |
| 165 | 166 | log.debug(" following ATOM({d}, %{d}, {?d})", .{ |
| 166 | 167 | target_atom_index, |
| 167 | 168 | macho_file.getAtom(target_atom_index).sym_index, |
| ... | ... | @@ -178,7 +179,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool |
| 178 | 179 | |
| 179 | 180 | log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() }); |
| 180 | 181 | |
| 181 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 182 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 183 | const cpu_arch = target.cpu.arch; | |
| 182 | 184 | |
| 183 | 185 | const sym = macho_file.getSymbol(sym_loc); |
| 184 | 186 | const header = macho_file.sections.items(.header)[sym.n_sect - 1]; |
| ... | ... | @@ -189,7 +191,7 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool |
| 189 | 191 | const ctx = Atom.getRelocContext(macho_file, atom_index); |
| 190 | 192 | |
| 191 | 193 | for (relocs) |rel| { |
| 192 | const target = switch (cpu_arch) { | |
| 194 | const reloc_target = switch (cpu_arch) { | |
| 193 | 195 | .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) { |
| 194 | 196 | .ARM64_RELOC_ADDEND => continue, |
| 195 | 197 | else => Atom.parseRelocTarget(macho_file, .{ |
| ... | ... | @@ -210,9 +212,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool |
| 210 | 212 | else => unreachable, |
| 211 | 213 | }; |
| 212 | 214 | |
| 213 | const object = macho_file.objects.items[target.getFile().?]; | |
| 214 | const target_atom_index = object.getAtomIndexForSymbol(target.sym_index) orelse { | |
| 215 | log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(target)}); | |
| 215 | const object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 216 | const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index) orelse { | |
| 217 | log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(reloc_target)}); | |
| 216 | 218 | continue; |
| 217 | 219 | }; |
| 218 | 220 | if (alive.contains(target_atom_index)) { |
| ... | ... | @@ -271,7 +273,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void { |
| 271 | 273 | |
| 272 | 274 | fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void { |
| 273 | 275 | const object = &macho_file.objects.items[object_id]; |
| 274 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 276 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 277 | const cpu_arch = target.cpu.arch; | |
| 275 | 278 | |
| 276 | 279 | const unwind_records = object.getUnwindRecords(); |
| 277 | 280 | |
| ... | ... | @@ -310,29 +313,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void |
| 310 | 313 | markEhFrameRecords(macho_file, object_id, atom_index, alive); |
| 311 | 314 | } else { |
| 312 | 315 | if (UnwindInfo.getPersonalityFunctionReloc(macho_file, object_id, record_id)) |rel| { |
| 313 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 316 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 314 | 317 | .object_id = object_id, |
| 315 | 318 | .rel = rel, |
| 316 | 319 | .code = mem.asBytes(&record), |
| 317 | 320 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 318 | 321 | }); |
| 319 | const target_sym = macho_file.getSymbol(target); | |
| 322 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 320 | 323 | if (!target_sym.undf()) { |
| 321 | const target_object = macho_file.objects.items[target.getFile().?]; | |
| 322 | const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?; | |
| 324 | const target_object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 325 | const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?; | |
| 323 | 326 | markLive(macho_file, target_atom_index, alive); |
| 324 | 327 | } |
| 325 | 328 | } |
| 326 | 329 | |
| 327 | 330 | if (UnwindInfo.getLsdaReloc(macho_file, object_id, record_id)) |rel| { |
| 328 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 331 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 329 | 332 | .object_id = object_id, |
| 330 | 333 | .rel = rel, |
| 331 | 334 | .code = mem.asBytes(&record), |
| 332 | 335 | .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))), |
| 333 | 336 | }); |
| 334 | const target_object = macho_file.objects.items[target.getFile().?]; | |
| 335 | const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?; | |
| 337 | const target_object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 338 | const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?; | |
| 336 | 339 | markLive(macho_file, target_atom_index, alive); |
| 337 | 340 | } |
| 338 | 341 | } |
| ... | ... | @@ -341,7 +344,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void |
| 341 | 344 | } |
| 342 | 345 | |
| 343 | 346 | fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index, alive: *AtomTable) void { |
| 344 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 347 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 348 | const cpu_arch = target.cpu.arch; | |
| 345 | 349 | const object = &macho_file.objects.items[object_id]; |
| 346 | 350 | var it = object.getEhFrameRecordsIterator(); |
| 347 | 351 | var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index); |
| ... | ... | @@ -361,16 +365,16 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index |
| 361 | 365 | // Mark FDE references which should include any referenced LSDA record |
| 362 | 366 | const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset); |
| 363 | 367 | for (relocs) |rel| { |
| 364 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 368 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 365 | 369 | .object_id = object_id, |
| 366 | 370 | .rel = rel, |
| 367 | 371 | .code = fde.data, |
| 368 | 372 | .base_offset = @as(i32, @intCast(fde_offset)) + 4, |
| 369 | 373 | }); |
| 370 | const target_sym = macho_file.getSymbol(target); | |
| 374 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 371 | 375 | if (!target_sym.undf()) blk: { |
| 372 | const target_object = macho_file.objects.items[target.getFile().?]; | |
| 373 | const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index) orelse | |
| 376 | const target_object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 377 | const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index) orelse | |
| 374 | 378 | break :blk; |
| 375 | 379 | markLive(macho_file, target_atom_index, alive); |
| 376 | 380 | } |
| ... | ... | @@ -394,11 +398,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index |
| 394 | 398 | |
| 395 | 399 | // Mark CIE references which should include any referenced personalities |
| 396 | 400 | // that are defined locally. |
| 397 | if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |target| { | |
| 398 | const target_sym = macho_file.getSymbol(target); | |
| 401 | if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |reloc_target| { | |
| 402 | const target_sym = macho_file.getSymbol(reloc_target); | |
| 399 | 403 | if (!target_sym.undf()) { |
| 400 | const target_object = macho_file.objects.items[target.getFile().?]; | |
| 401 | const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?; | |
| 404 | const target_object = macho_file.objects.items[reloc_target.getFile().?]; | |
| 405 | const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?; | |
| 402 | 406 | markLive(macho_file, target_atom_index, alive); |
| 403 | 407 | } |
| 404 | 408 | } |
src/link/MachO/eh_frame.zig+20-15| ... | ... | @@ -35,7 +35,8 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error |
| 35 | 35 | sect.@"align" = 3; |
| 36 | 36 | sect.size = 0; |
| 37 | 37 | |
| 38 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 38 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 39 | const cpu_arch = target.cpu.arch; | |
| 39 | 40 | const gpa = macho_file.base.allocator; |
| 40 | 41 | var size: u32 = 0; |
| 41 | 42 | |
| ... | ... | @@ -86,7 +87,8 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 86 | 87 | const seg_id = macho_file.sections.items(.segment_index)[sect_id]; |
| 87 | 88 | const seg = macho_file.segments.items[seg_id]; |
| 88 | 89 | |
| 89 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 90 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 91 | const cpu_arch = target.cpu.arch; | |
| 90 | 92 | const gpa = macho_file.base.allocator; |
| 91 | 93 | |
| 92 | 94 | var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa); |
| ... | ... | @@ -109,11 +111,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 109 | 111 | |
| 110 | 112 | for (object.exec_atoms.items) |atom_index| { |
| 111 | 113 | var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index); |
| 112 | while (inner_syms_it.next()) |target| { | |
| 113 | const fde_record_offset = object.eh_frame_records_lookup.get(target) orelse continue; | |
| 114 | while (inner_syms_it.next()) |reloc_target| { | |
| 115 | const fde_record_offset = object.eh_frame_records_lookup.get(reloc_target) orelse continue; | |
| 114 | 116 | if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue; |
| 115 | 117 | |
| 116 | const record_id = unwind_info.records_lookup.get(target) orelse continue; | |
| 118 | const record_id = unwind_info.records_lookup.get(reloc_target) orelse continue; | |
| 117 | 119 | const record = &unwind_info.records.items[record_id]; |
| 118 | 120 | |
| 119 | 121 | // TODO skip this check if no __compact_unwind is present |
| ... | ... | @@ -153,7 +155,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 153 | 155 | .aarch64 => {}, // relocs take care of LSDA pointers |
| 154 | 156 | .x86_64 => { |
| 155 | 157 | // We need to relocate target symbol address ourselves. |
| 156 | const atom_sym = macho_file.getSymbol(target); | |
| 158 | const atom_sym = macho_file.getSymbol(reloc_target); | |
| 157 | 159 | try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{ |
| 158 | 160 | .base_addr = sect.addr, |
| 159 | 161 | .base_offset = eh_frame_offset, |
| ... | ... | @@ -278,7 +280,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 278 | 280 | object_id: u32, |
| 279 | 281 | source_offset: u32, |
| 280 | 282 | ) ?SymbolWithLoc { |
| 281 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 283 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 284 | const cpu_arch = target.cpu.arch; | |
| 282 | 285 | const relocs = getRelocs(macho_file, object_id, source_offset); |
| 283 | 286 | for (relocs) |rel| { |
| 284 | 287 | switch (cpu_arch) { |
| ... | ... | @@ -301,13 +304,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 301 | 304 | }, |
| 302 | 305 | else => unreachable, |
| 303 | 306 | } |
| 304 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 307 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 305 | 308 | .object_id = object_id, |
| 306 | 309 | .rel = rel, |
| 307 | 310 | .code = rec.data, |
| 308 | 311 | .base_offset = @as(i32, @intCast(source_offset)) + 4, |
| 309 | 312 | }); |
| 310 | return target; | |
| 313 | return reloc_target; | |
| 311 | 314 | } |
| 312 | 315 | return null; |
| 313 | 316 | } |
| ... | ... | @@ -319,11 +322,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 319 | 322 | }) !void { |
| 320 | 323 | comptime assert(is_mutable); |
| 321 | 324 | |
| 322 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 325 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 326 | const cpu_arch = target.cpu.arch; | |
| 323 | 327 | const relocs = getRelocs(macho_file, object_id, ctx.source_offset); |
| 324 | 328 | |
| 325 | 329 | for (relocs) |rel| { |
| 326 | const target = Atom.parseRelocTarget(macho_file, .{ | |
| 330 | const reloc_target = Atom.parseRelocTarget(macho_file, .{ | |
| 327 | 331 | .object_id = object_id, |
| 328 | 332 | .rel = rel, |
| 329 | 333 | .code = rec.data, |
| ... | ... | @@ -340,14 +344,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 340 | 344 | // Address of the __eh_frame in the source object file |
| 341 | 345 | }, |
| 342 | 346 | .ARM64_RELOC_POINTER_TO_GOT => { |
| 343 | const target_addr = macho_file.getGotEntryAddress(target).?; | |
| 347 | const target_addr = macho_file.getGotEntryAddress(reloc_target).?; | |
| 344 | 348 | const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse |
| 345 | 349 | return error.Overflow; |
| 346 | 350 | mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little); |
| 347 | 351 | }, |
| 348 | 352 | .ARM64_RELOC_UNSIGNED => { |
| 349 | 353 | assert(rel.r_extern == 1); |
| 350 | const target_addr = Atom.getRelocTargetAddress(macho_file, target, false); | |
| 354 | const target_addr = Atom.getRelocTargetAddress(macho_file, reloc_target, false); | |
| 351 | 355 | const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr)); |
| 352 | 356 | mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little); |
| 353 | 357 | }, |
| ... | ... | @@ -358,7 +362,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 358 | 362 | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); |
| 359 | 363 | switch (rel_type) { |
| 360 | 364 | .X86_64_RELOC_GOT => { |
| 361 | const target_addr = macho_file.getGotEntryAddress(target).?; | |
| 365 | const target_addr = macho_file.getGotEntryAddress(reloc_target).?; | |
| 362 | 366 | const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little); |
| 363 | 367 | const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend)); |
| 364 | 368 | const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0); |
| ... | ... | @@ -374,7 +378,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type { |
| 374 | 378 | |
| 375 | 379 | pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 { |
| 376 | 380 | assert(rec.tag == .fde); |
| 377 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 381 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 382 | const cpu_arch = target.cpu.arch; | |
| 378 | 383 | const addend = mem.readInt(u32, rec.data[0..4], .little); |
| 379 | 384 | switch (cpu_arch) { |
| 380 | 385 | .aarch64 => { |
src/link/MachO/load_commands.zig+3-3| ... | ... | @@ -472,11 +472,11 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe |
| 472 | 472 | defer arena_allocator.deinit(); |
| 473 | 473 | const arena = arena_allocator.allocator(); |
| 474 | 474 | |
| 475 | const options = comp.bin_file.options; | |
| 475 | const macho_file = comp.bin_file.cast(MachO).?; | |
| 476 | 476 | |
| 477 | const sdk_layout = options.darwin_sdk_layout orelse return null; | |
| 477 | const sdk_layout = macho_file.sdk_layout orelse return null; | |
| 478 | 478 | const sdk_dir = switch (sdk_layout) { |
| 479 | .sdk => options.sysroot.?, | |
| 479 | .sdk => macho_file.sysroot.?, | |
| 480 | 480 | .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null, |
| 481 | 481 | }; |
| 482 | 482 | if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { |
src/link/MachO/zld.zig+18-11| ... | ... | @@ -458,7 +458,7 @@ pub fn linkWithZld( |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | try writeAtoms(macho_file); |
| 461 | if (macho_file.base.options.target.cpu.arch == .aarch64) try writeThunks(macho_file); | |
| 461 | if (target.cpu.arch == .aarch64) try writeThunks(macho_file); | |
| 462 | 462 | try writeDyldPrivateAtom(macho_file); |
| 463 | 463 | |
| 464 | 464 | if (macho_file.stubs_section_index) |_| { |
| ... | ... | @@ -557,7 +557,7 @@ pub fn linkWithZld( |
| 557 | 557 | .version = 0, |
| 558 | 558 | }); |
| 559 | 559 | { |
| 560 | const platform = Platform.fromTarget(macho_file.base.options.target); | |
| 560 | const platform = Platform.fromTarget(target); | |
| 561 | 561 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); |
| 562 | 562 | if (platform.isBuildVersionCompatible()) { |
| 563 | 563 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| ... | ... | @@ -610,7 +610,8 @@ pub fn linkWithZld( |
| 610 | 610 | |
| 611 | 611 | fn createSegments(macho_file: *MachO) !void { |
| 612 | 612 | const gpa = macho_file.base.allocator; |
| 613 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 613 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 614 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 614 | 615 | const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size); |
| 615 | 616 | if (macho_file.base.comp.config.output_mode != .Lib and aligned_pagezero_vmsize > 0) { |
| 616 | 617 | if (aligned_pagezero_vmsize != macho_file.pagezero_vmsize) { |
| ... | ... | @@ -755,7 +756,8 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void { |
| 755 | 756 | } |
| 756 | 757 | |
| 757 | 758 | fn writeThunks(macho_file: *MachO) !void { |
| 758 | assert(macho_file.base.options.target.cpu.arch == .aarch64); | |
| 759 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 760 | assert(target.cpu.arch == .aarch64); | |
| 759 | 761 | const gpa = macho_file.base.allocator; |
| 760 | 762 | |
| 761 | 763 | const sect_id = macho_file.text_section_index orelse return; |
| ... | ... | @@ -791,7 +793,8 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void { |
| 791 | 793 | |
| 792 | 794 | fn writeStubs(macho_file: *MachO) !void { |
| 793 | 795 | const gpa = macho_file.base.allocator; |
| 794 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 796 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 797 | const cpu_arch = target.cpu.arch; | |
| 795 | 798 | const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?]; |
| 796 | 799 | const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?]; |
| 797 | 800 | |
| ... | ... | @@ -813,7 +816,8 @@ fn writeStubs(macho_file: *MachO) !void { |
| 813 | 816 | |
| 814 | 817 | fn writeStubHelpers(macho_file: *MachO) !void { |
| 815 | 818 | const gpa = macho_file.base.allocator; |
| 816 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 819 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 820 | const cpu_arch = target.cpu.arch; | |
| 817 | 821 | const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?]; |
| 818 | 822 | |
| 819 | 823 | const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow; |
| ... | ... | @@ -856,7 +860,8 @@ fn writeStubHelpers(macho_file: *MachO) !void { |
| 856 | 860 | |
| 857 | 861 | fn writeLaSymbolPtrs(macho_file: *MachO) !void { |
| 858 | 862 | const gpa = macho_file.base.allocator; |
| 859 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 863 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 864 | const cpu_arch = target.cpu.arch; | |
| 860 | 865 | const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?]; |
| 861 | 866 | const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?]; |
| 862 | 867 | |
| ... | ... | @@ -964,11 +969,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void { |
| 964 | 969 | } |
| 965 | 970 | |
| 966 | 971 | fn calcSectionSizes(macho_file: *MachO) !void { |
| 972 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 967 | 973 | const slice = macho_file.sections.slice(); |
| 968 | 974 | for (slice.items(.header), 0..) |*header, sect_id| { |
| 969 | 975 | if (header.size == 0) continue; |
| 970 | 976 | if (macho_file.text_section_index) |txt| { |
| 971 | if (txt == sect_id and macho_file.base.options.target.cpu.arch == .aarch64) continue; | |
| 977 | if (txt == sect_id and target.cpu.arch == .aarch64) continue; | |
| 972 | 978 | } |
| 973 | 979 | |
| 974 | 980 | var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue; |
| ... | ... | @@ -991,7 +997,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 991 | 997 | } |
| 992 | 998 | } |
| 993 | 999 | |
| 994 | if (macho_file.text_section_index != null and macho_file.base.options.target.cpu.arch == .aarch64) { | |
| 1000 | if (macho_file.text_section_index != null and target.cpu.arch == .aarch64) { | |
| 995 | 1001 | // Create jump/branch range extenders if needed. |
| 996 | 1002 | try thunks.createThunks(macho_file, macho_file.text_section_index.?); |
| 997 | 1003 | } |
| ... | ... | @@ -1043,7 +1049,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 1043 | 1049 | header.@"align" = 3; |
| 1044 | 1050 | } |
| 1045 | 1051 | |
| 1046 | const cpu_arch = macho_file.base.options.target.cpu.arch; | |
| 1052 | const cpu_arch = target.cpu.arch; | |
| 1047 | 1053 | |
| 1048 | 1054 | if (macho_file.stubs_section_index) |sect_id| { |
| 1049 | 1055 | const header = &macho_file.sections.items(.header)[sect_id]; |
| ... | ... | @@ -1093,6 +1099,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u |
| 1093 | 1099 | } |
| 1094 | 1100 | |
| 1095 | 1101 | fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void { |
| 1102 | const target = macho_file.base.comp.root_mod.resolved_target.result; | |
| 1096 | 1103 | const segment = &macho_file.segments.items[segment_index]; |
| 1097 | 1104 | |
| 1098 | 1105 | if (mem.eql(u8, segment.segName(), "__PAGEZERO")) return; // allocated upon creation |
| ... | ... | @@ -1175,7 +1182,7 @@ fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void |
| 1175 | 1182 | segment.vmsize = start; |
| 1176 | 1183 | } |
| 1177 | 1184 | |
| 1178 | const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch); | |
| 1185 | const page_size = MachO.getPageSize(target.cpu.arch); | |
| 1179 | 1186 | segment.filesize = mem.alignForward(u64, segment.filesize, page_size); |
| 1180 | 1187 | segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size); |
| 1181 | 1188 | } |
src/link/Plan9.zig+30-25| ... | ... | @@ -206,7 +206,8 @@ pub const Atom = struct { |
| 206 | 206 | |
| 207 | 207 | // asserts that self.got_index != null |
| 208 | 208 | pub fn getOffsetTableAddress(self: Atom, plan9: *Plan9) u64 { |
| 209 | const ptr_bytes = @divExact(plan9.base.options.target.ptrBitWidth(), 8); | |
| 209 | const target = plan9.base.comp.root_mod.resolved_target.result; | |
| 210 | const ptr_bytes = @divExact(target.ptrBitWidth(), 8); | |
| 210 | 211 | const got_addr = plan9.bases.data; |
| 211 | 212 | const got_index = self.got_index.?; |
| 212 | 213 | return got_addr + got_index * ptr_bytes; |
| ... | ... | @@ -293,9 +294,11 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases { |
| 293 | 294 | }; |
| 294 | 295 | } |
| 295 | 296 | |
| 296 | pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 { | |
| 297 | if (options.use_llvm) | |
| 298 | return error.LLVMBackendDoesNotSupportPlan9; | |
| 297 | pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Plan9 { | |
| 298 | _ = arena; | |
| 299 | const target = options.comp.root_mod.resolved_target.result; | |
| 300 | const gpa = options.comp.gpa; | |
| 301 | ||
| 299 | 302 | const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) { |
| 300 | 303 | 0...32 => false, |
| 301 | 304 | 33...64 => true, |
| ... | ... | @@ -315,7 +318,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 { |
| 315 | 318 | }, |
| 316 | 319 | .sixtyfour_bit = sixtyfour_bit, |
| 317 | 320 | .bases = undefined, |
| 318 | .magic = try aout.magicFromArch(self.base.options.target.cpu.arch), | |
| 321 | .magic = try aout.magicFromArch(target.cpu.arch), | |
| 319 | 322 | }; |
| 320 | 323 | // a / will always be in a file path |
| 321 | 324 | try self.file_segments.put(gpa, "/", 1); |
| ... | ... | @@ -399,6 +402,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 399 | 402 | } |
| 400 | 403 | |
| 401 | 404 | const gpa = self.base.comp.gpa; |
| 405 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 402 | 406 | const func = mod.funcInfo(func_index); |
| 403 | 407 | const decl_index = func.owner_decl; |
| 404 | 408 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -414,7 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 414 | 418 | .end_line = undefined, |
| 415 | 419 | .pcop_change_index = null, |
| 416 | 420 | // we have already checked the target in the linker to make sure it is compatable |
| 417 | .pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable, | |
| 421 | .pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable, | |
| 418 | 422 | }; |
| 419 | 423 | defer dbg_info_output.dbg_line.deinit(); |
| 420 | 424 | |
| ... | ... | @@ -658,6 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 658 | 662 | } |
| 659 | 663 | |
| 660 | 664 | const gpa = comp.gpa; |
| 665 | const target = comp.root_mod.resolved_target.result; | |
| 661 | 666 | |
| 662 | 667 | const tracy = trace(@src()); |
| 663 | 668 | defer tracy.end(); |
| ... | ... | @@ -749,9 +754,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 749 | 754 | atom.offset = off; |
| 750 | 755 | log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off }); |
| 751 | 756 | if (!self.sixtyfour_bit) { |
| 752 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 757 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 753 | 758 | } else { |
| 754 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 759 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 755 | 760 | } |
| 756 | 761 | self.syms.items[atom.sym_index.?].value = off; |
| 757 | 762 | if (mod.decl_exports.get(decl_index)) |exports| { |
| ... | ... | @@ -778,9 +783,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 778 | 783 | text_i += code.len; |
| 779 | 784 | text_atom.offset = off; |
| 780 | 785 | if (!self.sixtyfour_bit) { |
| 781 | mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 786 | mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 782 | 787 | } else { |
| 783 | mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 788 | mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 784 | 789 | } |
| 785 | 790 | self.syms.items[text_atom.sym_index.?].value = off; |
| 786 | 791 | } |
| ... | ... | @@ -791,9 +796,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 791 | 796 | const val = self.getAddr(text_i, .t); |
| 792 | 797 | self.syms.items[etext_atom.sym_index.?].value = val; |
| 793 | 798 | if (!self.sixtyfour_bit) { |
| 794 | mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); | |
| 799 | mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian()); | |
| 795 | 800 | } else { |
| 796 | mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); | |
| 801 | mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian()); | |
| 797 | 802 | } |
| 798 | 803 | } |
| 799 | 804 | // global offset table is in data |
| ... | ... | @@ -815,9 +820,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 815 | 820 | data_i += code.len; |
| 816 | 821 | atom.offset = off; |
| 817 | 822 | if (!self.sixtyfour_bit) { |
| 818 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 823 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 819 | 824 | } else { |
| 820 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 825 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 821 | 826 | } |
| 822 | 827 | self.syms.items[atom.sym_index.?].value = off; |
| 823 | 828 | if (mod.decl_exports.get(decl_index)) |exports| { |
| ... | ... | @@ -838,9 +843,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 838 | 843 | data_i += code.len; |
| 839 | 844 | atom.offset = off; |
| 840 | 845 | if (!self.sixtyfour_bit) { |
| 841 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 846 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 842 | 847 | } else { |
| 843 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 848 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 844 | 849 | } |
| 845 | 850 | self.syms.items[atom.sym_index.?].value = off; |
| 846 | 851 | } |
| ... | ... | @@ -859,9 +864,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 859 | 864 | data_i += code.len; |
| 860 | 865 | atom.offset = off; |
| 861 | 866 | if (!self.sixtyfour_bit) { |
| 862 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 867 | mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 863 | 868 | } else { |
| 864 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 869 | mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 865 | 870 | } |
| 866 | 871 | self.syms.items[atom.sym_index.?].value = off; |
| 867 | 872 | } |
| ... | ... | @@ -879,9 +884,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 879 | 884 | data_i += code.len; |
| 880 | 885 | data_atom.offset = off; |
| 881 | 886 | if (!self.sixtyfour_bit) { |
| 882 | mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian()); | |
| 887 | mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian()); | |
| 883 | 888 | } else { |
| 884 | mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian()); | |
| 889 | mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian()); | |
| 885 | 890 | } |
| 886 | 891 | self.syms.items[data_atom.sym_index.?].value = off; |
| 887 | 892 | } |
| ... | ... | @@ -891,9 +896,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 891 | 896 | const val = self.getAddr(data_i, .b); |
| 892 | 897 | self.syms.items[edata_atom.sym_index.?].value = val; |
| 893 | 898 | if (!self.sixtyfour_bit) { |
| 894 | mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); | |
| 899 | mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian()); | |
| 895 | 900 | } else { |
| 896 | mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); | |
| 901 | mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian()); | |
| 897 | 902 | } |
| 898 | 903 | } |
| 899 | 904 | // end symbol (same as edata because native backends don't do .bss yet) |
| ... | ... | @@ -902,10 +907,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 902 | 907 | const val = self.getAddr(data_i, .b); |
| 903 | 908 | self.syms.items[end_atom.sym_index.?].value = val; |
| 904 | 909 | if (!self.sixtyfour_bit) { |
| 905 | mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian()); | |
| 910 | mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian()); | |
| 906 | 911 | } else { |
| 907 | 912 | log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val }); |
| 908 | mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian()); | |
| 913 | mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian()); | |
| 909 | 914 | } |
| 910 | 915 | } |
| 911 | 916 | } |
| ... | ... | @@ -942,7 +947,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No |
| 942 | 947 | const source_atom = self.getAtom(source_atom_index); |
| 943 | 948 | const source_atom_symbol = self.syms.items[source_atom.sym_index.?]; |
| 944 | 949 | const code = source_atom.code.getCode(self); |
| 945 | const endian = self.base.options.target.cpu.arch.endian(); | |
| 950 | const endian = target.cpu.arch.endian(); | |
| 946 | 951 | for (kv.value_ptr.items) |reloc| { |
| 947 | 952 | const offset = reloc.offset; |
| 948 | 953 | const addend = reloc.addend; |
src/link/Wasm.zig+7-4| ... | ... | @@ -1119,7 +1119,8 @@ fn validateFeatures( |
| 1119 | 1119 | to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool, |
| 1120 | 1120 | emit_features_count: *u32, |
| 1121 | 1121 | ) !void { |
| 1122 | const cpu_features = wasm.base.options.target.cpu.features; | |
| 1122 | const target = wasm.base.comp.root_mod.resolved_target.result; | |
| 1123 | const cpu_features = target.cpu.features; | |
| 1123 | 1124 | const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects. |
| 1124 | 1125 | const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len; |
| 1125 | 1126 | |
| ... | ... | @@ -1752,6 +1753,7 @@ pub fn getDeclVAddr( |
| 1752 | 1753 | decl_index: InternPool.DeclIndex, |
| 1753 | 1754 | reloc_info: link.File.RelocInfo, |
| 1754 | 1755 | ) !u64 { |
| 1756 | const target = wasm.base.comp.root_mod.resolved_target.result; | |
| 1755 | 1757 | const gpa = wasm.base.comp.gpa; |
| 1756 | 1758 | const mod = wasm.base.comp.module.?; |
| 1757 | 1759 | const decl = mod.declPtr(decl_index); |
| ... | ... | @@ -1762,7 +1764,7 @@ pub fn getDeclVAddr( |
| 1762 | 1764 | assert(reloc_info.parent_atom_index != 0); |
| 1763 | 1765 | const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; |
| 1764 | 1766 | const atom = wasm.getAtomPtr(atom_index); |
| 1765 | const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32; | |
| 1767 | const is_wasm32 = target.cpu.arch == .wasm32; | |
| 1766 | 1768 | if (decl.ty.zigTypeTag(mod) == .Fn) { |
| 1767 | 1769 | assert(reloc_info.addend == 0); // addend not allowed for function relocations |
| 1768 | 1770 | // We found a function pointer, so add it to our table, |
| ... | ... | @@ -1825,12 +1827,13 @@ pub fn lowerAnonDecl( |
| 1825 | 1827 | |
| 1826 | 1828 | pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 1827 | 1829 | const gpa = wasm.base.comp.gpa; |
| 1830 | const target = wasm.base.comp.root_mod.resolved_target.result; | |
| 1828 | 1831 | const atom_index = wasm.anon_decls.get(decl_val).?; |
| 1829 | 1832 | const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?; |
| 1830 | 1833 | |
| 1831 | 1834 | const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?; |
| 1832 | 1835 | const parent_atom = wasm.getAtomPtr(parent_atom_index); |
| 1833 | const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32; | |
| 1836 | const is_wasm32 = target.cpu.arch == .wasm32; | |
| 1834 | 1837 | const mod = wasm.base.comp.module.?; |
| 1835 | 1838 | const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val)); |
| 1836 | 1839 | if (ty.zigTypeTag(mod) == .Fn) { |
| ... | ... | @@ -4557,7 +4560,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 4557 | 4560 | break :blk null; |
| 4558 | 4561 | }; |
| 4559 | 4562 | |
| 4560 | const target = wasm.base.options.target; | |
| 4563 | const target = wasm.base.comp.root_mod.resolved_target.result; | |
| 4561 | 4564 | |
| 4562 | 4565 | const id_symlink_basename = "lld.id"; |
| 4563 | 4566 |