| author | |
| committer | |
| log | 2047a6b82d2e6cdbddde3e7f1c93df9e72216052 |
| tree | c9717626d48bc85a0e5dbe12bb2d815241ac9c94 |
| parent | 46297087871dec88c2b632d057f1e55b662126df |
28 files changed, 340 insertions(+), 341 deletions(-)
src/Compilation.zig+4-4| ... | ... | @@ -229,7 +229,7 @@ pub const Emit = struct { |
| 229 | 229 | |
| 230 | 230 | /// Returns the full path to `basename` if it were in the same directory as the |
| 231 | 231 | /// `Emit` sub_path. |
| 232 | pub fn basenamePath(emit: Emit, arena: Allocator, basename: [:0]const u8) ![:0]const u8 { | |
| 232 | pub fn basenamePath(emit: Emit, arena: Allocator, basename: []const u8) ![:0]const u8 { | |
| 233 | 233 | const full_path = if (emit.directory.path) |p| |
| 234 | 234 | try std.fs.path.join(arena, &[_][]const u8{ p, emit.sub_path }) |
| 235 | 235 | else |
| ... | ... | @@ -238,7 +238,7 @@ pub const Emit = struct { |
| 238 | 238 | if (std.fs.path.dirname(full_path)) |dirname| { |
| 239 | 239 | return try std.fs.path.joinZ(arena, &.{ dirname, basename }); |
| 240 | 240 | } else { |
| 241 | return basename; | |
| 241 | return try arena.dupeZ(u8, basename); | |
| 242 | 242 | } |
| 243 | 243 | } |
| 244 | 244 | }; |
| ... | ... | @@ -1038,8 +1038,8 @@ pub const InitOptions = struct { |
| 1038 | 1038 | linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null, |
| 1039 | 1039 | linker_module_definition_file: ?[]const u8 = null, |
| 1040 | 1040 | linker_sort_section: ?link.File.Elf.SortSection = null, |
| 1041 | major_subsystem_version: ?u32 = null, | |
| 1042 | minor_subsystem_version: ?u32 = null, | |
| 1041 | major_subsystem_version: ?u16 = null, | |
| 1042 | minor_subsystem_version: ?u16 = null, | |
| 1043 | 1043 | clang_passthrough_mode: bool = false, |
| 1044 | 1044 | verbose_cc: bool = false, |
| 1045 | 1045 | verbose_link: bool = false, |
src/Module.zig+3-8| ... | ... | @@ -4309,14 +4309,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err |
| 4309 | 4309 | decl.has_linksection_or_addrspace = has_linksection_or_addrspace; |
| 4310 | 4310 | decl.zir_decl_index = @enumFromInt(decl_sub_index); |
| 4311 | 4311 | if (decl.getOwnedFunction(mod) != null) { |
| 4312 | switch (comp.bin_file.tag) { | |
| 4313 | .coff, .elf, .macho, .plan9 => { | |
| 4314 | // TODO Look into detecting when this would be unnecessary by storing enough state | |
| 4315 | // in `Decl` to notice that the line number did not change. | |
| 4316 | comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); | |
| 4317 | }, | |
| 4318 | .c, .wasm, .spirv, .nvptx => {}, | |
| 4319 | } | |
| 4312 | // TODO Look into detecting when this would be unnecessary by storing enough state | |
| 4313 | // in `Decl` to notice that the line number did not change. | |
| 4314 | comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index }); | |
| 4320 | 4315 | } |
| 4321 | 4316 | } |
| 4322 | 4317 |
src/Sema.zig+1-1| ... | ... | @@ -20043,7 +20043,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 20043 | 20043 | |
| 20044 | 20044 | if (sema.owner_func_index != .none and |
| 20045 | 20045 | ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and |
| 20046 | mod.ownerModule().error_tracing and | |
| 20046 | block.ownerModule().error_tracing and | |
| 20047 | 20047 | mod.backendSupportsFeature(.error_return_trace)) |
| 20048 | 20048 | { |
| 20049 | 20049 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
src/arch/x86_64/CodeGen.zig+28-18| ... | ... | @@ -800,19 +800,20 @@ pub fn generate( |
| 800 | 800 | ) CodeGenError!Result { |
| 801 | 801 | const comp = bin_file.comp; |
| 802 | 802 | const gpa = comp.gpa; |
| 803 | const mod = comp.module.?; | |
| 804 | const func = mod.funcInfo(func_index); | |
| 805 | const fn_owner_decl = mod.declPtr(func.owner_decl); | |
| 803 | const zcu = comp.module.?; | |
| 804 | const func = zcu.funcInfo(func_index); | |
| 805 | const fn_owner_decl = zcu.declPtr(func.owner_decl); | |
| 806 | 806 | assert(fn_owner_decl.has_tv); |
| 807 | 807 | const fn_type = fn_owner_decl.ty; |
| 808 | const namespace = mod.namespacePtr(fn_owner_decl.src_namespace); | |
| 809 | const target = namespace.file_scope.mod.resolved_target.result; | |
| 808 | const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); | |
| 809 | const mod = namespace.file_scope.mod; | |
| 810 | 810 | |
| 811 | 811 | var function = Self{ |
| 812 | 812 | .gpa = gpa, |
| 813 | 813 | .air = air, |
| 814 | 814 | .liveness = liveness, |
| 815 | .target = target, | |
| 815 | .target = &mod.resolved_target.result, | |
| 816 | .mod = mod, | |
| 816 | 817 | .bin_file = bin_file, |
| 817 | 818 | .debug_output = debug_output, |
| 818 | 819 | .owner = .{ .func_index = func_index }, |
| ... | ... | @@ -843,7 +844,7 @@ pub fn generate( |
| 843 | 844 | |
| 844 | 845 | wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)}); |
| 845 | 846 | |
| 846 | const ip = &mod.intern_pool; | |
| 847 | const ip = &zcu.intern_pool; | |
| 847 | 848 | |
| 848 | 849 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 849 | 850 | function.frame_allocs.set( |
| ... | ... | @@ -858,7 +859,7 @@ pub fn generate( |
| 858 | 859 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), |
| 859 | 860 | ); |
| 860 | 861 | |
| 861 | const fn_info = mod.typeToFunc(fn_type).?; | |
| 862 | const fn_info = zcu.typeToFunc(fn_type).?; | |
| 862 | 863 | const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*); |
| 863 | 864 | var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) { |
| 864 | 865 | error.CodegenFail => return Result{ .fail = function.err_msg.? }, |
| ... | ... | @@ -877,14 +878,14 @@ pub fn generate( |
| 877 | 878 | function.args = call_info.args; |
| 878 | 879 | function.ret_mcv = call_info.return_value; |
| 879 | 880 | function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{ |
| 880 | .size = Type.usize.abiSize(mod), | |
| 881 | .alignment = Type.usize.abiAlignment(mod).min(call_info.stack_align), | |
| 881 | .size = Type.usize.abiSize(zcu), | |
| 882 | .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align), | |
| 882 | 883 | })); |
| 883 | 884 | function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{ |
| 884 | .size = Type.usize.abiSize(mod), | |
| 885 | .size = Type.usize.abiSize(zcu), | |
| 885 | 886 | .alignment = Alignment.min( |
| 886 | 887 | call_info.stack_align, |
| 887 | Alignment.fromNonzeroByteUnits(target.stackAlignment()), | |
| 888 | Alignment.fromNonzeroByteUnits(function.target.stackAlignment()), | |
| 888 | 889 | ), |
| 889 | 890 | })); |
| 890 | 891 | function.frame_allocs.set( |
| ... | ... | @@ -927,6 +928,9 @@ pub fn generate( |
| 927 | 928 | .mir = mir, |
| 928 | 929 | .cc = cc, |
| 929 | 930 | .src_loc = src_loc, |
| 931 | .output_mode = comp.config.output_mode, | |
| 932 | .link_mode = comp.config.link_mode, | |
| 933 | .pic = mod.pic, | |
| 930 | 934 | }, |
| 931 | 935 | .debug_output = debug_output, |
| 932 | 936 | .code = code, |
| ... | ... | @@ -970,16 +974,14 @@ pub fn generateLazy( |
| 970 | 974 | ) CodeGenError!Result { |
| 971 | 975 | const comp = bin_file.comp; |
| 972 | 976 | const gpa = comp.gpa; |
| 973 | const zcu = comp.module.?; | |
| 974 | const decl_index = lazy_sym.ty.getOwnerDecl(zcu); | |
| 975 | const decl = zcu.declPtr(decl_index); | |
| 976 | const namespace = zcu.namespacePtr(decl.src_namespace); | |
| 977 | const target = namespace.file_scope.mod.resolved_target.result; | |
| 977 | // This function is for generating global code, so we use the root module. | |
| 978 | const mod = comp.root_mod; | |
| 978 | 979 | var function = Self{ |
| 979 | 980 | .gpa = gpa, |
| 980 | 981 | .air = undefined, |
| 981 | 982 | .liveness = undefined, |
| 982 | .target = target, | |
| 983 | .target = &mod.resolved_target.result, | |
| 984 | .mod = mod, | |
| 983 | 985 | .bin_file = bin_file, |
| 984 | 986 | .debug_output = debug_output, |
| 985 | 987 | .owner = .{ .lazy_sym = lazy_sym }, |
| ... | ... | @@ -1020,6 +1022,9 @@ pub fn generateLazy( |
| 1020 | 1022 | .mir = mir, |
| 1021 | 1023 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), |
| 1022 | 1024 | .src_loc = src_loc, |
| 1025 | .output_mode = comp.config.output_mode, | |
| 1026 | .link_mode = comp.config.link_mode, | |
| 1027 | .pic = mod.pic, | |
| 1023 | 1028 | }, |
| 1024 | 1029 | .debug_output = debug_output, |
| 1025 | 1030 | .code = code, |
| ... | ... | @@ -1104,6 +1109,8 @@ fn formatWipMir( |
| 1104 | 1109 | _: std.fmt.FormatOptions, |
| 1105 | 1110 | writer: anytype, |
| 1106 | 1111 | ) @TypeOf(writer).Error!void { |
| 1112 | const comp = data.self.bin_file.comp; | |
| 1113 | const mod = comp.root_mod; | |
| 1107 | 1114 | var lower = Lower{ |
| 1108 | 1115 | .bin_file = data.self.bin_file, |
| 1109 | 1116 | .allocator = data.self.gpa, |
| ... | ... | @@ -1114,6 +1121,9 @@ fn formatWipMir( |
| 1114 | 1121 | }, |
| 1115 | 1122 | .cc = .Unspecified, |
| 1116 | 1123 | .src_loc = data.self.src_loc, |
| 1124 | .output_mode = comp.config.output_mode, | |
| 1125 | .link_mode = comp.config.link_mode, | |
| 1126 | .pic = mod.pic, | |
| 1117 | 1127 | }; |
| 1118 | 1128 | var first = true; |
| 1119 | 1129 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
src/codegen/llvm.zig+1-1| ... | ... | @@ -1168,7 +1168,7 @@ pub const Object = struct { |
| 1168 | 1168 | pre_ir_path: ?[]const u8, |
| 1169 | 1169 | pre_bc_path: ?[]const u8, |
| 1170 | 1170 | bin_path: ?[*:0]const u8, |
| 1171 | emit_asm: ?[*:0]const u8, | |
| 1171 | asm_path: ?[*:0]const u8, | |
| 1172 | 1172 | post_ir_path: ?[*:0]const u8, |
| 1173 | 1173 | post_bc_path: ?[*:0]const u8, |
| 1174 | 1174 |
src/link.zig+122-176| ... | ... | @@ -61,6 +61,7 @@ pub const File = struct { |
| 61 | 61 | intermediary_basename: ?[]const u8 = null, |
| 62 | 62 | disable_lld_caching: bool, |
| 63 | 63 | gc_sections: bool, |
| 64 | print_gc_sections: bool, | |
| 64 | 65 | build_id: std.zig.BuildId, |
| 65 | 66 | rpath_list: []const []const u8, |
| 66 | 67 | /// List of symbols forced as undefined in the symbol table |
| ... | ... | @@ -114,8 +115,8 @@ pub const File = struct { |
| 114 | 115 | disable_lld_caching: bool, |
| 115 | 116 | hash_style: Elf.HashStyle, |
| 116 | 117 | sort_section: ?Elf.SortSection, |
| 117 | major_subsystem_version: ?u32, | |
| 118 | minor_subsystem_version: ?u32, | |
| 118 | major_subsystem_version: ?u16, | |
| 119 | minor_subsystem_version: ?u16, | |
| 119 | 120 | gc_sections: ?bool, |
| 120 | 121 | allow_shlib_undefined: ?bool, |
| 121 | 122 | subsystem: ?std.Target.SubSystem, |
| ... | ... | @@ -181,9 +182,15 @@ pub const File = struct { |
| 181 | 182 | emit: Compilation.Emit, |
| 182 | 183 | options: OpenOptions, |
| 183 | 184 | ) !*File { |
| 184 | switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) { | |
| 185 | inline else => |tag| { | |
| 186 | const ptr = try tag.Type().open(arena, comp, emit, options); | |
| 185 | const tag = Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt); | |
| 186 | switch (tag) { | |
| 187 | .c => { | |
| 188 | const ptr = try C.open(arena, comp, emit, options); | |
| 189 | return &ptr.base; | |
| 190 | }, | |
| 191 | inline else => |t| { | |
| 192 | if (build_options.only_c) unreachable; | |
| 193 | const ptr = try t.Type().open(arena, comp, emit, options); | |
| 187 | 194 | return &ptr.base; |
| 188 | 195 | }, |
| 189 | 196 | } |
| ... | ... | @@ -195,9 +202,15 @@ pub const File = struct { |
| 195 | 202 | emit: Compilation.Emit, |
| 196 | 203 | options: OpenOptions, |
| 197 | 204 | ) !*File { |
| 198 | switch (Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt)) { | |
| 199 | inline else => |tag| { | |
| 200 | const ptr = try tag.Type().createEmpty(arena, comp, emit, options); | |
| 205 | const tag = Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt); | |
| 206 | switch (tag) { | |
| 207 | .c => { | |
| 208 | const ptr = try C.createEmpty(arena, comp, emit, options); | |
| 209 | return &ptr.base; | |
| 210 | }, | |
| 211 | inline else => |t| { | |
| 212 | if (build_options.only_c) unreachable; | |
| 213 | const ptr = try t.Type().createEmpty(arena, comp, emit, options); | |
| 201 | 214 | return &ptr.base; |
| 202 | 215 | }, |
| 203 | 216 | } |
| ... | ... | @@ -360,16 +373,12 @@ pub const File = struct { |
| 360 | 373 | pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 { |
| 361 | 374 | if (build_options.only_c) @compileError("unreachable"); |
| 362 | 375 | switch (base.tag) { |
| 363 | // zig fmt: off | |
| 364 | .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 365 | .elf => return @fieldParentPtr(Elf, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 366 | .macho => return @fieldParentPtr(MachO, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 367 | .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 368 | 376 | .spirv => unreachable, |
| 369 | .c => unreachable, | |
| 370 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerUnnamedConst(tv, decl_index), | |
| 377 | .c => unreachable, | |
| 371 | 378 | .nvptx => unreachable, |
| 372 | // zig fmt: on | |
| 379 | inline else => |t| { | |
| 380 | return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(tv, decl_index); | |
| 381 | }, | |
| 373 | 382 | } |
| 374 | 383 | } |
| 375 | 384 | |
| ... | ... | @@ -382,16 +391,13 @@ pub const File = struct { |
| 382 | 391 | if (build_options.only_c) @compileError("unreachable"); |
| 383 | 392 | log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); |
| 384 | 393 | switch (base.tag) { |
| 385 | // zig fmt: off | |
| 386 | .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name, lib_name), | |
| 387 | .elf => return @fieldParentPtr(Elf, "base", base).getGlobalSymbol(name, lib_name), | |
| 388 | .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name, lib_name), | |
| 389 | 394 | .plan9 => unreachable, |
| 390 | 395 | .spirv => unreachable, |
| 391 | .c => unreachable, | |
| 392 | .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name, lib_name), | |
| 396 | .c => unreachable, | |
| 393 | 397 | .nvptx => unreachable, |
| 394 | // zig fmt: on | |
| 398 | inline else => |t| { | |
| 399 | return @fieldParentPtr(t.Type(), "base", base).getGlobalSymbol(name, lib_name); | |
| 400 | }, | |
| 395 | 401 | } |
| 396 | 402 | } |
| 397 | 403 | |
| ... | ... | @@ -399,59 +405,48 @@ pub const File = struct { |
| 399 | 405 | pub fn updateDecl(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 400 | 406 | const decl = module.declPtr(decl_index); |
| 401 | 407 | assert(decl.has_tv); |
| 402 | if (build_options.only_c) { | |
| 403 | assert(base.tag == .c); | |
| 404 | return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index); | |
| 405 | } | |
| 406 | 408 | switch (base.tag) { |
| 407 | // zig fmt: off | |
| 408 | .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl_index), | |
| 409 | .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl_index), | |
| 410 | .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl_index), | |
| 411 | .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index), | |
| 412 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl_index), | |
| 413 | .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl_index), | |
| 414 | .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl_index), | |
| 415 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDecl(module, decl_index), | |
| 416 | // zig fmt: on | |
| 409 | .c => { | |
| 410 | return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index); | |
| 411 | }, | |
| 412 | inline else => |tag| { | |
| 413 | if (build_options.only_c) unreachable; | |
| 414 | return @fieldParentPtr(tag.Type(), "base", base).updateDecl(module, decl_index); | |
| 415 | }, | |
| 417 | 416 | } |
| 418 | 417 | } |
| 419 | 418 | |
| 420 | 419 | /// May be called before or after updateExports for any given Decl. |
| 421 | pub fn updateFunc(base: *File, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) UpdateDeclError!void { | |
| 422 | if (build_options.only_c) { | |
| 423 | assert(base.tag == .c); | |
| 424 | return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness); | |
| 425 | } | |
| 420 | pub fn updateFunc( | |
| 421 | base: *File, | |
| 422 | module: *Module, | |
| 423 | func_index: InternPool.Index, | |
| 424 | air: Air, | |
| 425 | liveness: Liveness, | |
| 426 | ) UpdateDeclError!void { | |
| 426 | 427 | switch (base.tag) { |
| 427 | // zig fmt: off | |
| 428 | .coff => return @fieldParentPtr(Coff, "base", base).updateFunc(module, func_index, air, liveness), | |
| 429 | .elf => return @fieldParentPtr(Elf, "base", base).updateFunc(module, func_index, air, liveness), | |
| 430 | .macho => return @fieldParentPtr(MachO, "base", base).updateFunc(module, func_index, air, liveness), | |
| 431 | .c => return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness), | |
| 432 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateFunc(module, func_index, air, liveness), | |
| 433 | .spirv => return @fieldParentPtr(SpirV, "base", base).updateFunc(module, func_index, air, liveness), | |
| 434 | .plan9 => return @fieldParentPtr(Plan9, "base", base).updateFunc(module, func_index, air, liveness), | |
| 435 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateFunc(module, func_index, air, liveness), | |
| 436 | // zig fmt: on | |
| 428 | .c => { | |
| 429 | return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness); | |
| 430 | }, | |
| 431 | inline else => |tag| { | |
| 432 | if (build_options.only_c) unreachable; | |
| 433 | return @fieldParentPtr(tag.Type(), "base", base).updateFunc(module, func_index, air, liveness); | |
| 434 | }, | |
| 437 | 435 | } |
| 438 | 436 | } |
| 439 | 437 | |
| 440 | 438 | pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void { |
| 441 | 439 | const decl = module.declPtr(decl_index); |
| 442 | 440 | assert(decl.has_tv); |
| 443 | if (build_options.only_c) { | |
| 444 | assert(base.tag == .c); | |
| 445 | return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index); | |
| 446 | } | |
| 447 | 441 | switch (base.tag) { |
| 448 | .coff => return @fieldParentPtr(Coff, "base", base).updateDeclLineNumber(module, decl_index), | |
| 449 | .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl_index), | |
| 450 | .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl_index), | |
| 451 | .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index), | |
| 452 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclLineNumber(module, decl_index), | |
| 453 | .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclLineNumber(module, decl_index), | |
| 454 | 442 | .spirv, .nvptx => {}, |
| 443 | .c => { | |
| 444 | return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index); | |
| 445 | }, | |
| 446 | inline else => |tag| { | |
| 447 | if (build_options.only_c) unreachable; | |
| 448 | return @fieldParentPtr(tag.Type(), "base", base).updateDeclLineNumber(module, decl_index); | |
| 449 | }, | |
| 455 | 450 | } |
| 456 | 451 | } |
| 457 | 452 | |
| ... | ... | @@ -477,44 +472,11 @@ pub const File = struct { |
| 477 | 472 | base.misc_errors.deinit(gpa); |
| 478 | 473 | } |
| 479 | 474 | switch (base.tag) { |
| 480 | .coff => { | |
| 481 | if (build_options.only_c) unreachable; | |
| 482 | const parent = @fieldParentPtr(Coff, "base", base); | |
| 483 | parent.deinit(); | |
| 484 | }, | |
| 485 | .elf => { | |
| 486 | if (build_options.only_c) unreachable; | |
| 487 | const parent = @fieldParentPtr(Elf, "base", base); | |
| 488 | parent.deinit(); | |
| 489 | }, | |
| 490 | .macho => { | |
| 491 | if (build_options.only_c) unreachable; | |
| 492 | const parent = @fieldParentPtr(MachO, "base", base); | |
| 493 | parent.deinit(); | |
| 494 | }, | |
| 495 | .c => { | |
| 496 | const parent = @fieldParentPtr(C, "base", base); | |
| 497 | parent.deinit(); | |
| 498 | }, | |
| 499 | .wasm => { | |
| 500 | if (build_options.only_c) unreachable; | |
| 501 | const parent = @fieldParentPtr(Wasm, "base", base); | |
| 502 | parent.deinit(); | |
| 503 | }, | |
| 504 | .spirv => { | |
| 505 | if (build_options.only_c) unreachable; | |
| 506 | const parent = @fieldParentPtr(SpirV, "base", base); | |
| 507 | parent.deinit(); | |
| 508 | }, | |
| 509 | .plan9 => { | |
| 510 | if (build_options.only_c) unreachable; | |
| 511 | const parent = @fieldParentPtr(Plan9, "base", base); | |
| 512 | parent.deinit(); | |
| 513 | }, | |
| 514 | .nvptx => { | |
| 475 | .c => @fieldParentPtr(C, "base", base).deinit(), | |
| 476 | ||
| 477 | inline else => |tag| { | |
| 515 | 478 | if (build_options.only_c) unreachable; |
| 516 | const parent = @fieldParentPtr(NvPtx, "base", base); | |
| 517 | parent.deinit(); | |
| 479 | @fieldParentPtr(tag.Type(), "base", base).deinit(); | |
| 518 | 480 | }, |
| 519 | 481 | } |
| 520 | 482 | } |
| ... | ... | @@ -619,51 +581,36 @@ pub const File = struct { |
| 619 | 581 | return base.linkAsArchive(comp, prog_node); |
| 620 | 582 | } |
| 621 | 583 | switch (base.tag) { |
| 622 | .coff => return @fieldParentPtr(Coff, "base", base).flush(comp, prog_node), | |
| 623 | .elf => return @fieldParentPtr(Elf, "base", base).flush(comp, prog_node), | |
| 624 | .macho => return @fieldParentPtr(MachO, "base", base).flush(comp, prog_node), | |
| 625 | .c => return @fieldParentPtr(C, "base", base).flush(comp, prog_node), | |
| 626 | .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node), | |
| 627 | .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp, prog_node), | |
| 628 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp, prog_node), | |
| 629 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp, prog_node), | |
| 584 | inline else => |tag| { | |
| 585 | return @fieldParentPtr(tag.Type(), "base", base).flush(comp, prog_node); | |
| 586 | }, | |
| 630 | 587 | } |
| 631 | 588 | } |
| 632 | 589 | |
| 633 | 590 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` |
| 634 | 591 | /// rather than final output mode. |
| 635 | 592 | pub fn flushModule(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void { |
| 636 | if (build_options.only_c) { | |
| 637 | assert(base.tag == .c); | |
| 638 | return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node); | |
| 639 | } | |
| 640 | 593 | switch (base.tag) { |
| 641 | .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp, prog_node), | |
| 642 | .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp, prog_node), | |
| 643 | .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp, prog_node), | |
| 644 | .c => return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node), | |
| 645 | .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp, prog_node), | |
| 646 | .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp, prog_node), | |
| 647 | .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp, prog_node), | |
| 648 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp, prog_node), | |
| 594 | .c => { | |
| 595 | return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node); | |
| 596 | }, | |
| 597 | inline else => |tag| { | |
| 598 | if (build_options.only_c) unreachable; | |
| 599 | return @fieldParentPtr(tag.Type(), "base", base).flushModule(comp, prog_node); | |
| 600 | }, | |
| 649 | 601 | } |
| 650 | 602 | } |
| 651 | 603 | |
| 652 | 604 | /// Called when a Decl is deleted from the Module. |
| 653 | 605 | pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void { |
| 654 | if (build_options.only_c) { | |
| 655 | assert(base.tag == .c); | |
| 656 | return @fieldParentPtr(C, "base", base).freeDecl(decl_index); | |
| 657 | } | |
| 658 | 606 | switch (base.tag) { |
| 659 | .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl_index), | |
| 660 | .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl_index), | |
| 661 | .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl_index), | |
| 662 | .c => @fieldParentPtr(C, "base", base).freeDecl(decl_index), | |
| 663 | .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl_index), | |
| 664 | .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl_index), | |
| 665 | .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl_index), | |
| 666 | .nvptx => @fieldParentPtr(NvPtx, "base", base).freeDecl(decl_index), | |
| 607 | .c => { | |
| 608 | @fieldParentPtr(C, "base", base).freeDecl(decl_index); | |
| 609 | }, | |
| 610 | inline else => |tag| { | |
| 611 | if (build_options.only_c) unreachable; | |
| 612 | @fieldParentPtr(tag.Type(), "base", base).freeDecl(decl_index); | |
| 613 | }, | |
| 667 | 614 | } |
| 668 | 615 | } |
| 669 | 616 | |
| ... | ... | @@ -682,19 +629,14 @@ pub const File = struct { |
| 682 | 629 | exported: Module.Exported, |
| 683 | 630 | exports: []const *Module.Export, |
| 684 | 631 | ) UpdateExportsError!void { |
| 685 | if (build_options.only_c) { | |
| 686 | assert(base.tag == .c); | |
| 687 | return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports); | |
| 688 | } | |
| 689 | 632 | switch (base.tag) { |
| 690 | .coff => return @fieldParentPtr(Coff, "base", base).updateExports(module, exported, exports), | |
| 691 | .elf => return @fieldParentPtr(Elf, "base", base).updateExports(module, exported, exports), | |
| 692 | .macho => return @fieldParentPtr(MachO, "base", base).updateExports(module, exported, exports), | |
| 693 | .c => return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports), | |
| 694 | .wasm => return @fieldParentPtr(Wasm, "base", base).updateExports(module, exported, exports), | |
| 695 | .spirv => return @fieldParentPtr(SpirV, "base", base).updateExports(module, exported, exports), | |
| 696 | .plan9 => return @fieldParentPtr(Plan9, "base", base).updateExports(module, exported, exports), | |
| 697 | .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateExports(module, exported, exports), | |
| 633 | .c => { | |
| 634 | return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports); | |
| 635 | }, | |
| 636 | inline else => |tag| { | |
| 637 | if (build_options.only_c) unreachable; | |
| 638 | return @fieldParentPtr(tag.Type(), "base", base).updateExports(module, exported, exports); | |
| 639 | }, | |
| 698 | 640 | } |
| 699 | 641 | } |
| 700 | 642 | |
| ... | ... | @@ -711,60 +653,64 @@ pub const File = struct { |
| 711 | 653 | /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate |
| 712 | 654 | /// the block/atom. |
| 713 | 655 | pub fn getDeclVAddr(base: *File, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 { |
| 714 | if (build_options.only_c) unreachable; | |
| 656 | if (build_options.only_c) @compileError("unreachable"); | |
| 715 | 657 | switch (base.tag) { |
| 716 | .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 717 | .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 718 | .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 719 | .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 720 | 658 | .c => unreachable, |
| 721 | .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl_index, reloc_info), | |
| 722 | 659 | .spirv => unreachable, |
| 723 | 660 | .nvptx => unreachable, |
| 661 | inline else => |tag| { | |
| 662 | return @fieldParentPtr(tag.Type(), "base", base).getDeclVAddr(decl_index, reloc_info); | |
| 663 | }, | |
| 724 | 664 | } |
| 725 | 665 | } |
| 726 | 666 | |
| 727 | 667 | pub const LowerResult = @import("codegen.zig").Result; |
| 728 | 668 | |
| 729 | pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult { | |
| 730 | if (build_options.only_c) unreachable; | |
| 669 | pub fn lowerAnonDecl( | |
| 670 | base: *File, | |
| 671 | decl_val: InternPool.Index, | |
| 672 | decl_align: InternPool.Alignment, | |
| 673 | src_loc: Module.SrcLoc, | |
| 674 | ) !LowerResult { | |
| 675 | if (build_options.only_c) @compileError("unreachable"); | |
| 731 | 676 | switch (base.tag) { |
| 732 | .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 733 | .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 734 | .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 735 | .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc), | |
| 736 | 677 | .c => unreachable, |
| 737 | .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc), | |
| 738 | 678 | .spirv => unreachable, |
| 739 | 679 | .nvptx => unreachable, |
| 680 | inline else => |tag| { | |
| 681 | return @fieldParentPtr(tag.Type(), "base", base).lowerAnonDecl(decl_val, decl_align, src_loc); | |
| 682 | }, | |
| 740 | 683 | } |
| 741 | 684 | } |
| 742 | 685 | |
| 743 | 686 | pub fn getAnonDeclVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 { |
| 744 | if (build_options.only_c) unreachable; | |
| 687 | if (build_options.only_c) @compileError("unreachable"); | |
| 745 | 688 | switch (base.tag) { |
| 746 | .coff => return @fieldParentPtr(Coff, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 747 | .elf => return @fieldParentPtr(Elf, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 748 | .macho => return @fieldParentPtr(MachO, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 749 | .plan9 => return @fieldParentPtr(Plan9, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 750 | 689 | .c => unreachable, |
| 751 | .wasm => return @fieldParentPtr(Wasm, "base", base).getAnonDeclVAddr(decl_val, reloc_info), | |
| 752 | 690 | .spirv => unreachable, |
| 753 | 691 | .nvptx => unreachable, |
| 692 | inline else => |tag| { | |
| 693 | return @fieldParentPtr(tag.Type(), "base", base).getAnonDeclVAddr(decl_val, reloc_info); | |
| 694 | }, | |
| 754 | 695 | } |
| 755 | 696 | } |
| 756 | 697 | |
| 757 | pub fn deleteDeclExport(base: *File, decl_index: InternPool.DeclIndex, name: InternPool.NullTerminatedString) !void { | |
| 758 | if (build_options.only_c) unreachable; | |
| 698 | pub fn deleteDeclExport( | |
| 699 | base: *File, | |
| 700 | decl_index: InternPool.DeclIndex, | |
| 701 | name: InternPool.NullTerminatedString, | |
| 702 | ) !void { | |
| 703 | if (build_options.only_c) @compileError("unreachable"); | |
| 759 | 704 | switch (base.tag) { |
| 760 | .coff => return @fieldParentPtr(Coff, "base", base).deleteDeclExport(decl_index, name), | |
| 761 | .elf => return @fieldParentPtr(Elf, "base", base).deleteDeclExport(decl_index, name), | |
| 762 | .macho => return @fieldParentPtr(MachO, "base", base).deleteDeclExport(decl_index, name), | |
| 763 | .plan9 => {}, | |
| 764 | .c => {}, | |
| 765 | .wasm => return @fieldParentPtr(Wasm, "base", base).deleteDeclExport(decl_index), | |
| 766 | .spirv => {}, | |
| 767 | .nvptx => {}, | |
| 705 | .plan9, | |
| 706 | .c, | |
| 707 | .spirv, | |
| 708 | .nvptx, | |
| 709 | => {}, | |
| 710 | ||
| 711 | inline else => |tag| { | |
| 712 | return @fieldParentPtr(tag.Type(), "base", base).deleteDeclExport(decl_index, name); | |
| 713 | }, | |
| 768 | 714 | } |
| 769 | 715 | } |
| 770 | 716 | |
| ... | ... | @@ -1049,7 +995,7 @@ pub const File = struct { |
| 1049 | 995 | base: File, |
| 1050 | 996 | arena: Allocator, |
| 1051 | 997 | opt_loc: ?Compilation.EmitLoc, |
| 1052 | ) Allocator.Error!?[*:0]u8 { | |
| 998 | ) Allocator.Error!?[*:0]const u8 { | |
| 1053 | 999 | const loc = opt_loc orelse return null; |
| 1054 | 1000 | const slice = if (loc.directory) |directory| |
| 1055 | 1001 | try directory.joinZ(arena, &.{loc.basename}) |
| ... | ... | @@ -1071,7 +1017,7 @@ pub const File = struct { |
| 1071 | 1017 | sub_prog_node.context.refresh(); |
| 1072 | 1018 | defer sub_prog_node.end(); |
| 1073 | 1019 | |
| 1074 | try llvm_object.emit(comp, .{ | |
| 1020 | try llvm_object.emit(.{ | |
| 1075 | 1021 | .pre_ir_path = comp.verbose_llvm_ir, |
| 1076 | 1022 | .pre_bc_path = comp.verbose_llvm_bc, |
| 1077 | 1023 | .bin_path = try base.resolveEmitLoc(arena, .{ |
| ... | ... | @@ -1079,8 +1025,8 @@ pub const File = struct { |
| 1079 | 1025 | .basename = base.intermediary_basename.?, |
| 1080 | 1026 | }), |
| 1081 | 1027 | .asm_path = try base.resolveEmitLoc(arena, comp.emit_asm), |
| 1082 | .post_llvm_ir_path = try base.resolveEmitLoc(arena, comp.emit_llvm_ir), | |
| 1083 | .post_llvm_bc_path = try base.resolveEmitLoc(arena, comp.emit_llvm_bc), | |
| 1028 | .post_ir_path = try base.resolveEmitLoc(arena, comp.emit_llvm_ir), | |
| 1029 | .post_bc_path = try base.resolveEmitLoc(arena, comp.emit_llvm_bc), | |
| 1084 | 1030 | |
| 1085 | 1031 | .is_debug = comp.root_mod.optimize_mode == .Debug, |
| 1086 | 1032 | .is_small = comp.root_mod.optimize_mode == .ReleaseSmall, |
src/link/C.zig+1| ... | ... | @@ -135,6 +135,7 @@ pub fn createEmpty( |
| 135 | 135 | .comp = comp, |
| 136 | 136 | .emit = emit, |
| 137 | 137 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), |
| 138 | .print_gc_sections = options.print_gc_sections, | |
| 138 | 139 | .stack_size = options.stack_size orelse 16777216, |
| 139 | 140 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 140 | 141 | .file = file, |
src/link/Coff.zig+9-6| ... | ... | @@ -14,9 +14,10 @@ nxcompat: bool, |
| 14 | 14 | dynamicbase: bool, |
| 15 | 15 | /// TODO this and minor_subsystem_version should be combined into one property and left as |
| 16 | 16 | /// default or populated together. They should not be separate fields. |
| 17 | major_subsystem_version: u32, | |
| 18 | minor_subsystem_version: u32, | |
| 17 | major_subsystem_version: u16, | |
| 18 | minor_subsystem_version: u16, | |
| 19 | 19 | lib_dirs: []const []const u8, |
| 20 | entry_addr: ?u32, | |
| 20 | 21 | |
| 21 | 22 | ptr_width: PtrWidth, |
| 22 | 23 | page_size: u32, |
| ... | ... | @@ -238,7 +239,6 @@ pub fn open( |
| 238 | 239 | emit: Compilation.Emit, |
| 239 | 240 | options: link.File.OpenOptions, |
| 240 | 241 | ) !*Coff { |
| 241 | if (build_options.only_c) unreachable; | |
| 242 | 242 | const target = comp.root_mod.resolved_target.result; |
| 243 | 243 | assert(target.ofmt == .coff); |
| 244 | 244 | |
| ... | ... | @@ -390,6 +390,7 @@ pub fn createEmpty( |
| 390 | 390 | .emit = emit, |
| 391 | 391 | .stack_size = options.stack_size orelse 16777216, |
| 392 | 392 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), |
| 393 | .print_gc_sections = options.print_gc_sections, | |
| 393 | 394 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 394 | 395 | .file = null, |
| 395 | 396 | .disable_lld_caching = options.disable_lld_caching, |
| ... | ... | @@ -422,6 +423,8 @@ pub fn createEmpty( |
| 422 | 423 | .major_subsystem_version = options.major_subsystem_version orelse 6, |
| 423 | 424 | .minor_subsystem_version = options.minor_subsystem_version orelse 0, |
| 424 | 425 | .lib_dirs = options.lib_dirs, |
| 426 | .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse | |
| 427 | return error.EntryAddressTooBig, | |
| 425 | 428 | }; |
| 426 | 429 | |
| 427 | 430 | const use_llvm = comp.config.use_llvm; |
| ... | ... | @@ -2329,8 +2332,8 @@ fn writeHeader(self: *Coff) !void { |
| 2329 | 2332 | .minor_operating_system_version = 0, |
| 2330 | 2333 | .major_image_version = 0, |
| 2331 | 2334 | .minor_image_version = 0, |
| 2332 | .major_subsystem_version = self.major_subsystem_version, | |
| 2333 | .minor_subsystem_version = self.minor_subsystem_version, | |
| 2335 | .major_subsystem_version = @intCast(self.major_subsystem_version), | |
| 2336 | .minor_subsystem_version = @intCast(self.minor_subsystem_version), | |
| 2334 | 2337 | .win32_version_value = 0, |
| 2335 | 2338 | .size_of_image = size_of_image, |
| 2336 | 2339 | .size_of_headers = size_of_headers, |
| ... | ... | @@ -2342,7 +2345,7 @@ fn writeHeader(self: *Coff) !void { |
| 2342 | 2345 | .size_of_heap_reserve = default_size_of_heap_reserve, |
| 2343 | 2346 | .size_of_heap_commit = default_size_of_heap_commit, |
| 2344 | 2347 | .loader_flags = 0, |
| 2345 | .number_of_rva_and_sizes = @as(u32, @intCast(self.data_directories.len)), | |
| 2348 | .number_of_rva_and_sizes = @intCast(self.data_directories.len), | |
| 2346 | 2349 | }; |
| 2347 | 2350 | writer.writeAll(mem.asBytes(&opt_header)) catch unreachable; |
| 2348 | 2351 | }, |
src/link/Coff/lld.zig+23-22| ... | ... | @@ -21,7 +21,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 21 | 21 | const tracy = trace(@src()); |
| 22 | 22 | defer tracy.end(); |
| 23 | 23 | |
| 24 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | |
| 24 | const gpa = comp.gpa; | |
| 25 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); | |
| 25 | 26 | defer arena_allocator.deinit(); |
| 26 | 27 | const arena = arena_allocator.allocator(); |
| 27 | 28 | |
| ... | ... | @@ -30,7 +31,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 30 | 31 | |
| 31 | 32 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 32 | 33 | // will not be part of the linker line anyway. |
| 33 | const module_obj_path: ?[]const u8 = if (self.base.comp.module != null) blk: { | |
| 34 | const module_obj_path: ?[]const u8 = if (comp.module != null) blk: { | |
| 34 | 35 | try self.flushModule(comp, prog_node); |
| 35 | 36 | |
| 36 | 37 | if (fs.path.dirname(full_out_path)) |dirname| { |
| ... | ... | @@ -45,12 +46,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 45 | 46 | sub_prog_node.context.refresh(); |
| 46 | 47 | defer sub_prog_node.end(); |
| 47 | 48 | |
| 48 | const is_lib = self.base.comp.config.output_mode == .Lib; | |
| 49 | const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib; | |
| 50 | const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe; | |
| 49 | const is_lib = comp.config.output_mode == .Lib; | |
| 50 | const is_dyn_lib = comp.config.link_mode == .Dynamic and is_lib; | |
| 51 | const is_exe_or_dyn_lib = is_dyn_lib or comp.config.output_mode == .Exe; | |
| 51 | 52 | const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib; |
| 52 | const target = self.base.comp.root_mod.resolved_target.result; | |
| 53 | const optimize_mode = self.base.comp.root_mod.optimize_mode; | |
| 53 | const target = comp.root_mod.resolved_target.result; | |
| 54 | const optimize_mode = comp.root_mod.optimize_mode; | |
| 54 | 55 | |
| 55 | 56 | // See link/Elf.zig for comments on how this mechanism works. |
| 56 | 57 | const id_symlink_basename = "lld.id"; |
| ... | ... | @@ -85,8 +86,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 85 | 86 | man.hash.addListOfBytes(self.lib_dirs); |
| 86 | 87 | man.hash.add(comp.skip_linker_dependencies); |
| 87 | 88 | if (comp.config.link_libc) { |
| 88 | man.hash.add(self.base.comp.libc_installation != null); | |
| 89 | if (self.base.comp.libc_installation) |libc_installation| { | |
| 89 | man.hash.add(comp.libc_installation != null); | |
| 90 | if (comp.libc_installation) |libc_installation| { | |
| 90 | 91 | man.hash.addBytes(libc_installation.crt_dir.?); |
| 91 | 92 | if (target.abi == .msvc) { |
| 92 | 93 | man.hash.addBytes(libc_installation.msvc_lib_dir.?); |
| ... | ... | @@ -94,7 +95,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 94 | 95 | } |
| 95 | 96 | } |
| 96 | 97 | } |
| 97 | try link.hashAddSystemLibs(&man, self.base.comp.system_libs); | |
| 98 | try link.hashAddSystemLibs(&man, comp.system_libs); | |
| 98 | 99 | man.hash.addListOfBytes(self.base.force_undefined_symbols.keys()); |
| 99 | 100 | man.hash.addOptional(self.subsystem); |
| 100 | 101 | man.hash.add(comp.config.is_test); |
| ... | ... | @@ -136,7 +137,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 136 | 137 | }; |
| 137 | 138 | } |
| 138 | 139 | |
| 139 | if (self.base.comp.config.output_mode == .Obj) { | |
| 140 | if (comp.config.output_mode == .Obj) { | |
| 140 | 141 | // LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy |
| 141 | 142 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 142 | 143 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| ... | ... | @@ -161,7 +162,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 161 | 162 | } |
| 162 | 163 | } else { |
| 163 | 164 | // Create an LLD command line and invoke it. |
| 164 | var argv = std.ArrayList([]const u8).init(self.base.allocator); | |
| 165 | var argv = std.ArrayList([]const u8).init(gpa); | |
| 165 | 166 | defer argv.deinit(); |
| 166 | 167 | // We will invoke ourselves as a child process to gain access to LLD. |
| 167 | 168 | // This is necessary because LLD does not behave properly as a library - |
| ... | ... | @@ -192,7 +193,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 192 | 193 | .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"), |
| 193 | 194 | } |
| 194 | 195 | } |
| 195 | if (self.base.comp.config.output_mode == .Exe) { | |
| 196 | if (comp.config.output_mode == .Exe) { | |
| 196 | 197 | try argv.append(try allocPrint(arena, "-STACK:{d}", .{self.base.stack_size})); |
| 197 | 198 | } |
| 198 | 199 | try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{self.image_base})); |
| ... | ... | @@ -242,7 +243,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 242 | 243 | } |
| 243 | 244 | |
| 244 | 245 | if (comp.config.link_libc) { |
| 245 | if (self.base.comp.libc_installation) |libc_installation| { | |
| 246 | if (comp.libc_installation) |libc_installation| { | |
| 246 | 247 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?})); |
| 247 | 248 | |
| 248 | 249 | if (target.abi == .msvc) { |
| ... | ... | @@ -287,7 +288,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 287 | 288 | if (self.subsystem) |explicit| break :blk explicit; |
| 288 | 289 | switch (target.os.tag) { |
| 289 | 290 | .windows => { |
| 290 | if (self.base.comp.module) |module| { | |
| 291 | if (comp.module) |module| { | |
| 291 | 292 | if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib) |
| 292 | 293 | break :blk null; |
| 293 | 294 | if (module.stage1_flags.have_c_main or comp.config.is_test or |
| ... | ... | @@ -415,13 +416,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 415 | 416 | try argv.append(try comp.get_libc_crt_file(arena, "uuid.lib")); |
| 416 | 417 | |
| 417 | 418 | for (mingw.always_link_libs) |name| { |
| 418 | if (!self.base.comp.system_libs.contains(name)) { | |
| 419 | if (!comp.system_libs.contains(name)) { | |
| 419 | 420 | const lib_basename = try allocPrint(arena, "{s}.lib", .{name}); |
| 420 | 421 | try argv.append(try comp.get_libc_crt_file(arena, lib_basename)); |
| 421 | 422 | } |
| 422 | 423 | } |
| 423 | 424 | } else { |
| 424 | const lib_str = switch (self.base.comp.config.link_mode) { | |
| 425 | const lib_str = switch (comp.config.link_mode) { | |
| 425 | 426 | .Dynamic => "", |
| 426 | 427 | .Static => "lib", |
| 427 | 428 | }; |
| ... | ... | @@ -429,7 +430,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 429 | 430 | .Debug => "d", |
| 430 | 431 | else => "", |
| 431 | 432 | }; |
| 432 | switch (self.base.comp.config.link_mode) { | |
| 433 | switch (comp.config.link_mode) { | |
| 433 | 434 | .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})), |
| 434 | 435 | .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})), |
| 435 | 436 | } |
| ... | ... | @@ -448,7 +449,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 448 | 449 | } else { |
| 449 | 450 | try argv.append("-NODEFAULTLIB"); |
| 450 | 451 | if (!is_lib and comp.config.entry == null) { |
| 451 | if (self.base.comp.module) |module| { | |
| 452 | if (comp.module) |module| { | |
| 452 | 453 | if (module.stage1_flags.have_winmain_crt_startup) { |
| 453 | 454 | try argv.append("-ENTRY:WinMainCRTStartup"); |
| 454 | 455 | } else { |
| ... | ... | @@ -485,8 +486,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 485 | 486 | if (comp.compiler_rt_lib) |lib| try argv.append(lib.full_object_path); |
| 486 | 487 | } |
| 487 | 488 | |
| 488 | try argv.ensureUnusedCapacity(self.base.comp.system_libs.count()); | |
| 489 | for (self.base.comp.system_libs.keys()) |key| { | |
| 489 | try argv.ensureUnusedCapacity(comp.system_libs.count()); | |
| 490 | for (comp.system_libs.keys()) |key| { | |
| 490 | 491 | const lib_basename = try allocPrint(arena, "{s}.lib", .{key}); |
| 491 | 492 | if (comp.crt_files.get(lib_basename)) |crt_file| { |
| 492 | 493 | argv.appendAssumeCapacity(crt_file.full_object_path); |
| ... | ... | @@ -512,7 +513,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 512 | 513 | return error.DllImportLibraryNotFound; |
| 513 | 514 | } |
| 514 | 515 | |
| 515 | if (self.base.comp.verbose_link) { | |
| 516 | if (comp.verbose_link) { | |
| 516 | 517 | // Skip over our own name so that the LLD linker name is the first argv item. |
| 517 | 518 | Compilation.dump_argv(argv.items[1..]); |
| 518 | 519 | } |
src/link/Dwarf.zig+4-2| ... | ... | @@ -1745,6 +1745,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void { |
| 1745 | 1745 | } |
| 1746 | 1746 | |
| 1747 | 1747 | pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1748 | const gpa = self.allocator; | |
| 1748 | 1749 | // These are LEB encoded but since the values are all less than 127 |
| 1749 | 1750 | // we can simply append these bytes. |
| 1750 | 1751 | // zig fmt: off |
| ... | ... | @@ -1887,7 +1888,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void { |
| 1887 | 1888 | .wasm => { |
| 1888 | 1889 | const wasm_file = self.bin_file.cast(File.Wasm).?; |
| 1889 | 1890 | const debug_abbrev = &wasm_file.getAtomPtr(wasm_file.debug_abbrev_atom.?).code; |
| 1890 | try debug_abbrev.resize(wasm_file.base.allocator, needed_size); | |
| 1891 | try debug_abbrev.resize(gpa, needed_size); | |
| 1891 | 1892 | debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf; |
| 1892 | 1893 | }, |
| 1893 | 1894 | else => unreachable, |
| ... | ... | @@ -2236,6 +2237,7 @@ fn writeDbgInfoNopsToArrayList( |
| 2236 | 2237 | |
| 2237 | 2238 | pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { |
| 2238 | 2239 | const comp = self.bin_file.comp; |
| 2240 | const gpa = comp.gpa; | |
| 2239 | 2241 | const target = comp.root_mod.resolved_target.result; |
| 2240 | 2242 | const target_endian = target.cpu.arch.endian(); |
| 2241 | 2243 | const ptr_width_bytes = self.ptrWidthBytes(); |
| ... | ... | @@ -2301,7 +2303,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { |
| 2301 | 2303 | .wasm => { |
| 2302 | 2304 | const wasm_file = self.bin_file.cast(File.Wasm).?; |
| 2303 | 2305 | const debug_ranges = &wasm_file.getAtomPtr(wasm_file.debug_ranges_atom.?).code; |
| 2304 | try debug_ranges.resize(wasm_file.base.allocator, needed_size); | |
| 2306 | try debug_ranges.resize(gpa, needed_size); | |
| 2305 | 2307 | @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items); |
| 2306 | 2308 | }, |
| 2307 | 2309 | else => unreachable, |
src/link/Elf.zig+6-6| ... | ... | @@ -230,7 +230,6 @@ pub fn open( |
| 230 | 230 | emit: Compilation.Emit, |
| 231 | 231 | options: link.File.OpenOptions, |
| 232 | 232 | ) !*Elf { |
| 233 | if (build_options.only_c) unreachable; | |
| 234 | 233 | const target = comp.root_mod.resolved_target.result; |
| 235 | 234 | assert(target.ofmt == .elf); |
| 236 | 235 | |
| ... | ... | @@ -380,6 +379,7 @@ pub fn createEmpty( |
| 380 | 379 | .comp = comp, |
| 381 | 380 | .emit = emit, |
| 382 | 381 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), |
| 382 | .print_gc_sections = options.print_gc_sections, | |
| 383 | 383 | .stack_size = options.stack_size orelse 16777216, |
| 384 | 384 | .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os, |
| 385 | 385 | .file = null, |
| ... | ... | @@ -1175,7 +1175,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1175 | 1175 | const lib_name = flag["-l".len..]; |
| 1176 | 1176 | |
| 1177 | 1177 | success: { |
| 1178 | if (!self.isStatic()) { | |
| 1178 | if (!self.base.isStatic()) { | |
| 1179 | 1179 | if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Dynamic)) |
| 1180 | 1180 | break :success; |
| 1181 | 1181 | } |
| ... | ... | @@ -1664,7 +1664,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1664 | 1664 | try argv.append(p); |
| 1665 | 1665 | } |
| 1666 | 1666 | } else { |
| 1667 | if (!self.isStatic()) { | |
| 1667 | if (!self.base.isStatic()) { | |
| 1668 | 1668 | if (target.dynamic_linker.get()) |path| { |
| 1669 | 1669 | try argv.append("-dynamic-linker"); |
| 1670 | 1670 | try argv.append(path); |
| ... | ... | @@ -1742,7 +1742,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1742 | 1742 | try argv.append("now"); |
| 1743 | 1743 | } |
| 1744 | 1744 | |
| 1745 | if (self.isStatic()) { | |
| 1745 | if (self.base.isStatic()) { | |
| 1746 | 1746 | try argv.append("-static"); |
| 1747 | 1747 | } else if (self.base.isDynLib()) { |
| 1748 | 1748 | try argv.append("-shared"); |
| ... | ... | @@ -2023,7 +2023,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void { |
| 2023 | 2023 | // TODO I think technically we should re-use the mechanism used by the frontend here. |
| 2024 | 2024 | // Maybe we should hoist search-strategy all the way here? |
| 2025 | 2025 | for (self.lib_dirs) |lib_dir| { |
| 2026 | if (!self.isStatic()) { | |
| 2026 | if (!self.base.isStatic()) { | |
| 2027 | 2027 | if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Dynamic)) |
| 2028 | 2028 | break :success; |
| 2029 | 2029 | } |
| ... | ... | @@ -3598,7 +3598,7 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3598 | 3598 | // In this case, if we do generate .interp section and segment, we will get |
| 3599 | 3599 | // a segfault in the dynamic linker trying to load a binary that is static |
| 3600 | 3600 | // and doesn't contain .dynamic section. |
| 3601 | if (self.isStatic() and !comp.config.pie) break :blk false; | |
| 3601 | if (self.base.isStatic() and !comp.config.pie) break :blk false; | |
| 3602 | 3602 | break :blk target.dynamic_linker.get() != null; |
| 3603 | 3603 | }; |
| 3604 | 3604 | if (needs_interp) { |
src/link/Elf/Atom.zig+3-3| ... | ... | @@ -377,8 +377,8 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
| 377 | 377 | } |
| 378 | 378 | |
| 379 | 379 | pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype) !void { |
| 380 | const is_static = elf_file.isStatic(); | |
| 381 | const is_dyn_lib = elf_file.isDynLib(); | |
| 380 | const is_static = elf_file.base.isStatic(); | |
| 381 | const is_dyn_lib = elf_file.base.isDynLib(); | |
| 382 | 382 | const file_ptr = self.file(elf_file).?; |
| 383 | 383 | const rels = self.relocs(elf_file); |
| 384 | 384 | var i: usize = 0; |
| ... | ... | @@ -660,7 +660,7 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction { |
| 660 | 660 | |
| 661 | 661 | fn outputType(elf_file: *Elf) u2 { |
| 662 | 662 | const comp = elf_file.base.comp; |
| 663 | assert(!elf_file.isRelocatable()); | |
| 663 | assert(!elf_file.base.isRelocatable()); | |
| 664 | 664 | return switch (elf_file.base.comp.config.output_mode) { |
| 665 | 665 | .Obj => unreachable, |
| 666 | 666 | .Lib => 0, |
src/link/Elf/Object.zig+3-3| ... | ... | @@ -250,7 +250,7 @@ fn addAtom(self: *Object, shdr: ElfShdr, shndx: u16, elf_file: *Elf) error{OutOf |
| 250 | 250 | fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 { |
| 251 | 251 | const name = blk: { |
| 252 | 252 | const name = self.getString(shdr.sh_name); |
| 253 | if (elf_file.isRelocatable()) break :blk name; | |
| 253 | if (elf_file.base.isRelocatable()) break :blk name; | |
| 254 | 254 | if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name; |
| 255 | 255 | const sh_name_prefixes: []const [:0]const u8 = &.{ |
| 256 | 256 | ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", |
| ... | ... | @@ -278,7 +278,7 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem |
| 278 | 278 | }; |
| 279 | 279 | const flags = blk: { |
| 280 | 280 | var flags = shdr.sh_flags; |
| 281 | if (!elf_file.isRelocatable()) { | |
| 281 | if (!elf_file.base.isRelocatable()) { | |
| 282 | 282 | flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN); |
| 283 | 283 | } |
| 284 | 284 | break :blk switch (@"type") { |
| ... | ... | @@ -520,7 +520,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void { |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | const is_import = blk: { |
| 523 | if (!elf_file.isDynLib()) break :blk false; | |
| 523 | if (!elf_file.base.isDynLib()) break :blk false; | |
| 524 | 524 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); |
| 525 | 525 | if (vis == .HIDDEN) break :blk false; |
| 526 | 526 | break :blk true; |
src/link/Elf/ZigObject.zig+1-1| ... | ... | @@ -370,7 +370,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void { |
| 370 | 370 | } |
| 371 | 371 | |
| 372 | 372 | const is_import = blk: { |
| 373 | if (!elf_file.isDynLib()) break :blk false; | |
| 373 | if (!elf_file.base.isDynLib()) break :blk false; | |
| 374 | 374 | const vis = @as(elf.STV, @enumFromInt(esym.st_other)); |
| 375 | 375 | if (vis == .HIDDEN) break :blk false; |
| 376 | 376 | break :blk true; |
src/link/Elf/eh_frame.zig+1-1| ... | ... | @@ -271,7 +271,7 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize { |
| 271 | 271 | } |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | if (!elf_file.isRelocatable()) { | |
| 274 | if (!elf_file.base.isRelocatable()) { | |
| 275 | 275 | offset += 4; // NULL terminator |
| 276 | 276 | } |
| 277 | 277 |
src/link/MachO.zig+19-15| ... | ... | @@ -155,6 +155,7 @@ frameworks: []const Framework, |
| 155 | 155 | install_name: ?[]const u8, |
| 156 | 156 | /// Path to entitlements file. |
| 157 | 157 | entitlements: ?[]const u8, |
| 158 | compatibility_version: ?std.SemanticVersion, | |
| 158 | 159 | |
| 159 | 160 | /// When adding a new field, remember to update `hashAddFrameworks`. |
| 160 | 161 | pub const Framework = struct { |
| ... | ... | @@ -185,7 +186,6 @@ pub fn open( |
| 185 | 186 | emit: Compilation.Emit, |
| 186 | 187 | options: link.File.OpenOptions, |
| 187 | 188 | ) !*MachO { |
| 188 | if (build_options.only_c) unreachable; | |
| 189 | 189 | const target = comp.root_mod.resolved_target.result; |
| 190 | 190 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 191 | 191 | const use_llvm = comp.config.use_llvm; |
| ... | ... | @@ -295,6 +295,7 @@ pub fn createEmpty( |
| 295 | 295 | .comp = comp, |
| 296 | 296 | .emit = emit, |
| 297 | 297 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), |
| 298 | .print_gc_sections = options.print_gc_sections, | |
| 298 | 299 | .stack_size = options.stack_size orelse 16777216, |
| 299 | 300 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 300 | 301 | .file = null, |
| ... | ... | @@ -315,6 +316,7 @@ pub fn createEmpty( |
| 315 | 316 | .frameworks = options.frameworks, |
| 316 | 317 | .install_name = options.install_name, |
| 317 | 318 | .entitlements = options.entitlements, |
| 319 | .compatibility_version = options.compatibility_version, | |
| 318 | 320 | }; |
| 319 | 321 | |
| 320 | 322 | if (use_llvm and comp.module != null) { |
| ... | ... | @@ -632,7 +634,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 632 | 634 | }); |
| 633 | 635 | { |
| 634 | 636 | const platform = Platform.fromTarget(target); |
| 635 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); | |
| 637 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(self); | |
| 636 | 638 | if (platform.isBuildVersionCompatible()) { |
| 637 | 639 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| 638 | 640 | } else if (platform.isVersionMinCompatible()) { |
| ... | ... | @@ -2237,10 +2239,10 @@ fn allocateGlobal(self: *MachO) !u32 { |
| 2237 | 2239 | return index; |
| 2238 | 2240 | } |
| 2239 | 2241 | |
| 2240 | pub fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { | |
| 2241 | if (self.got_table.lookup.contains(target)) return; | |
| 2242 | pub fn addGotEntry(self: *MachO, reloc_target: SymbolWithLoc) !void { | |
| 2243 | if (self.got_table.lookup.contains(reloc_target)) return; | |
| 2242 | 2244 | const gpa = self.base.comp.gpa; |
| 2243 | const got_index = try self.got_table.allocateEntry(gpa, target); | |
| 2245 | const got_index = try self.got_table.allocateEntry(gpa, reloc_target); | |
| 2244 | 2246 | if (self.got_section_index == null) { |
| 2245 | 2247 | self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{ |
| 2246 | 2248 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| ... | ... | @@ -2249,20 +2251,22 @@ pub fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2249 | 2251 | if (self.mode == .incremental) { |
| 2250 | 2252 | try self.writeOffsetTableEntry(got_index); |
| 2251 | 2253 | self.got_table_count_dirty = true; |
| 2252 | self.markRelocsDirtyByTarget(target); | |
| 2254 | self.markRelocsDirtyByTarget(reloc_target); | |
| 2253 | 2255 | } |
| 2254 | 2256 | } |
| 2255 | 2257 | |
| 2256 | pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { | |
| 2257 | if (self.stub_table.lookup.contains(target)) return; | |
| 2258 | const gpa = self.base.comp.gpa; | |
| 2259 | const stub_index = try self.stub_table.allocateEntry(gpa, target); | |
| 2258 | pub fn addStubEntry(self: *MachO, reloc_target: SymbolWithLoc) !void { | |
| 2259 | if (self.stub_table.lookup.contains(reloc_target)) return; | |
| 2260 | const comp = self.base.comp; | |
| 2261 | const gpa = comp.gpa; | |
| 2262 | const cpu_arch = comp.root_mod.resolved_target.result.cpu.arch; | |
| 2263 | const stub_index = try self.stub_table.allocateEntry(gpa, reloc_target); | |
| 2260 | 2264 | if (self.stubs_section_index == null) { |
| 2261 | 2265 | self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{ |
| 2262 | 2266 | .flags = macho.S_SYMBOL_STUBS | |
| 2263 | 2267 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 2264 | 2268 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2265 | .reserved2 = stubs.stubSize(target.cpu.arch), | |
| 2269 | .reserved2 = stubs.stubSize(cpu_arch), | |
| 2266 | 2270 | }); |
| 2267 | 2271 | self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{ |
| 2268 | 2272 | .flags = macho.S_REGULAR | |
| ... | ... | @@ -2276,14 +2280,14 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2276 | 2280 | if (self.mode == .incremental) { |
| 2277 | 2281 | try self.writeStubTableEntry(stub_index); |
| 2278 | 2282 | self.stub_table_count_dirty = true; |
| 2279 | self.markRelocsDirtyByTarget(target); | |
| 2283 | self.markRelocsDirtyByTarget(reloc_target); | |
| 2280 | 2284 | } |
| 2281 | 2285 | } |
| 2282 | 2286 | |
| 2283 | pub fn addTlvPtrEntry(self: *MachO, target: SymbolWithLoc) !void { | |
| 2284 | if (self.tlv_ptr_table.lookup.contains(target)) return; | |
| 2287 | pub fn addTlvPtrEntry(self: *MachO, reloc_target: SymbolWithLoc) !void { | |
| 2288 | if (self.tlv_ptr_table.lookup.contains(reloc_target)) return; | |
| 2285 | 2289 | const gpa = self.base.comp.gpa; |
| 2286 | _ = try self.tlv_ptr_table.allocateEntry(gpa, target); | |
| 2290 | _ = try self.tlv_ptr_table.allocateEntry(gpa, reloc_target); | |
| 2287 | 2291 | if (self.tlv_ptr_section_index == null) { |
| 2288 | 2292 | self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{ |
| 2289 | 2293 | .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS, |
src/link/MachO/Object.zig+11-5| ... | ... | @@ -342,19 +342,22 @@ pub const SplitIntoAtomsError = error{ |
| 342 | 342 | }; |
| 343 | 343 | |
| 344 | 344 | pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIntoAtomsError!void { |
| 345 | const comp = macho_file.base.comp; | |
| 346 | const gpa = comp.gpa; | |
| 345 | 347 | log.debug("splitting object({d}, {s}) into atoms", .{ object_id, self.name }); |
| 346 | 348 | |
| 347 | 349 | try self.splitRegularSections(macho_file, object_id); |
| 348 | 350 | try self.parseEhFrameSection(macho_file, object_id); |
| 349 | 351 | try self.parseUnwindInfo(macho_file, object_id); |
| 350 | try self.parseDataInCode(macho_file.base.allocator); | |
| 352 | try self.parseDataInCode(gpa); | |
| 351 | 353 | } |
| 352 | 354 | |
| 353 | 355 | /// Splits input regular sections into Atoms. |
| 354 | 356 | /// If the Object was compiled with `MH_SUBSECTIONS_VIA_SYMBOLS`, splits section |
| 355 | 357 | /// into subsections where each subsection then represents an Atom. |
| 356 | 358 | pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 357 | const gpa = macho_file.base.allocator; | |
| 359 | const comp = macho_file.base.comp; | |
| 360 | const gpa = comp.gpa; | |
| 358 | 361 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 359 | 362 | |
| 360 | 363 | const sections = self.getSourceSections(); |
| ... | ... | @@ -555,7 +558,8 @@ fn createAtomFromSubsection( |
| 555 | 558 | alignment: Alignment, |
| 556 | 559 | out_sect_id: u8, |
| 557 | 560 | ) !Atom.Index { |
| 558 | const gpa = macho_file.base.allocator; | |
| 561 | const comp = macho_file.base.comp; | |
| 562 | const gpa = comp.gpa; | |
| 559 | 563 | const atom_index = try macho_file.createAtom(sym_index, .{ |
| 560 | 564 | .size = size, |
| 561 | 565 | .alignment = alignment, |
| ... | ... | @@ -671,7 +675,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 671 | 675 | |
| 672 | 676 | log.debug("parsing __TEXT,__eh_frame section", .{}); |
| 673 | 677 | |
| 674 | const gpa = macho_file.base.allocator; | |
| 678 | const comp = macho_file.base.comp; | |
| 679 | const gpa = comp.gpa; | |
| 675 | 680 | |
| 676 | 681 | if (macho_file.eh_frame_section_index == null) { |
| 677 | 682 | macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{}); |
| ... | ... | @@ -767,7 +772,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void |
| 767 | 772 | } |
| 768 | 773 | |
| 769 | 774 | fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void { |
| 770 | const gpa = macho_file.base.allocator; | |
| 775 | const comp = macho_file.base.comp; | |
| 776 | const gpa = comp.gpa; | |
| 771 | 777 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 772 | 778 | const cpu_arch = target.cpu.arch; |
| 773 | 779 | const sect_id = self.unwind_info_sect_id orelse { |
src/link/MachO/dead_strip.zig+2-1| ... | ... | @@ -1,7 +1,8 @@ |
| 1 | 1 | //! An algorithm for dead stripping of unreferenced Atoms. |
| 2 | 2 | |
| 3 | 3 | pub fn gcAtoms(macho_file: *MachO) !void { |
| 4 | const gpa = macho_file.base.allocator; | |
| 4 | const comp = macho_file.base.comp; | |
| 5 | const gpa = comp.gpa; | |
| 5 | 6 | |
| 6 | 7 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 7 | 8 | defer arena.deinit(); |
src/link/MachO/eh_frame.zig+6-3| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | pub fn scanRelocs(macho_file: *MachO) !void { |
| 2 | const gpa = macho_file.base.allocator; | |
| 2 | const comp = macho_file.base.comp; | |
| 3 | const gpa = comp.gpa; | |
| 3 | 4 | |
| 4 | 5 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| 5 | 6 | var cies = std.AutoHashMap(u32, void).init(gpa); |
| ... | ... | @@ -37,7 +38,8 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error |
| 37 | 38 | |
| 38 | 39 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 39 | 40 | const cpu_arch = target.cpu.arch; |
| 40 | const gpa = macho_file.base.allocator; | |
| 41 | const comp = macho_file.base.comp; | |
| 42 | const gpa = comp.gpa; | |
| 41 | 43 | var size: u32 = 0; |
| 42 | 44 | |
| 43 | 45 | for (macho_file.objects.items, 0..) |*object, object_id| { |
| ... | ... | @@ -89,7 +91,8 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void { |
| 89 | 91 | |
| 90 | 92 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 91 | 93 | const cpu_arch = target.cpu.arch; |
| 92 | const gpa = macho_file.base.allocator; | |
| 94 | const comp = macho_file.base.comp; | |
| 95 | const gpa = comp.gpa; | |
| 93 | 96 | |
| 94 | 97 | var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa); |
| 95 | 98 | defer { |
src/link/MachO/load_commands.zig+20-13| ... | ... | @@ -63,7 +63,7 @@ fn calcLCsSize(m: *MachO, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 { |
| 63 | 63 | } |
| 64 | 64 | // LC_RPATH |
| 65 | 65 | { |
| 66 | var it = RpathIterator.init(gpa, m.rpath_list); | |
| 66 | var it = RpathIterator.init(gpa, m.base.rpath_list); | |
| 67 | 67 | defer it.deinit(); |
| 68 | 68 | while (try it.next()) |rpath| { |
| 69 | 69 | sizeofcmds += calcInstallNameLen( |
| ... | ... | @@ -189,17 +189,20 @@ fn writeDylibLC(ctx: WriteDylibLCCtx, lc_writer: anytype) !void { |
| 189 | 189 | } |
| 190 | 190 | } |
| 191 | 191 | |
| 192 | pub fn writeDylibIdLC(gpa: Allocator, options: *const link.Options, lc_writer: anytype) !void { | |
| 193 | assert(options.output_mode == .Lib and options.link_mode == .Dynamic); | |
| 194 | const emit = options.emit.?; | |
| 195 | const install_name = options.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path}); | |
| 196 | defer if (options.install_name == null) gpa.free(install_name); | |
| 197 | const curr = options.version orelse std.SemanticVersion{ | |
| 192 | pub fn writeDylibIdLC(macho_file: *MachO, lc_writer: anytype) !void { | |
| 193 | const comp = macho_file.base.comp; | |
| 194 | const gpa = comp.gpa; | |
| 195 | assert(comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic); | |
| 196 | const emit = macho_file.base.emit; | |
| 197 | const install_name = macho_file.install_name orelse | |
| 198 | try emit.directory.join(gpa, &.{emit.sub_path}); | |
| 199 | defer if (macho_file.install_name == null) gpa.free(install_name); | |
| 200 | const curr = comp.version orelse std.SemanticVersion{ | |
| 198 | 201 | .major = 1, |
| 199 | 202 | .minor = 0, |
| 200 | 203 | .patch = 0, |
| 201 | 204 | }; |
| 202 | const compat = options.compatibility_version orelse std.SemanticVersion{ | |
| 205 | const compat = macho_file.compatibility_version orelse std.SemanticVersion{ | |
| 203 | 206 | .major = 1, |
| 204 | 207 | .minor = 0, |
| 205 | 208 | .patch = 0, |
| ... | ... | @@ -237,8 +240,11 @@ const RpathIterator = struct { |
| 237 | 240 | } |
| 238 | 241 | }; |
| 239 | 242 | |
| 240 | pub fn writeRpathLCs(gpa: Allocator, options: *const link.Options, lc_writer: anytype) !void { | |
| 241 | var it = RpathIterator.init(gpa, options.rpath_list); | |
| 243 | pub fn writeRpathLCs(macho_file: *MachO, lc_writer: anytype) !void { | |
| 244 | const comp = macho_file.base.comp; | |
| 245 | const gpa = comp.gpa; | |
| 246 | ||
| 247 | var it = RpathIterator.init(gpa, macho_file.base.rpath_list); | |
| 242 | 248 | defer it.deinit(); |
| 243 | 249 | |
| 244 | 250 | while (try it.next()) |rpath| { |
| ... | ... | @@ -467,13 +473,14 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion { |
| 467 | 473 | }; |
| 468 | 474 | } |
| 469 | 475 | |
| 470 | pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVersion { | |
| 476 | pub fn inferSdkVersion(macho_file: *MachO) ?std.SemanticVersion { | |
| 477 | const comp = macho_file.base.comp; | |
| 478 | const gpa = comp.gpa; | |
| 479 | ||
| 471 | 480 | var arena_allocator = std.heap.ArenaAllocator.init(gpa); |
| 472 | 481 | defer arena_allocator.deinit(); |
| 473 | 482 | const arena = arena_allocator.allocator(); |
| 474 | 483 | |
| 475 | const macho_file = comp.bin_file.cast(MachO).?; | |
| 476 | ||
| 477 | 484 | const sdk_layout = macho_file.sdk_layout orelse return null; |
| 478 | 485 | const sdk_dir = switch (sdk_layout) { |
| 479 | 486 | .sdk => comp.sysroot.?, |
src/link/MachO/thunks.zig+4-2| ... | ... | @@ -68,7 +68,8 @@ pub fn createThunks(macho_file: *MachO, sect_id: u8) !void { |
| 68 | 68 | const header = &macho_file.sections.items(.header)[sect_id]; |
| 69 | 69 | if (header.size == 0) return; |
| 70 | 70 | |
| 71 | const gpa = macho_file.base.allocator; | |
| 71 | const comp = macho_file.base.comp; | |
| 72 | const gpa = comp.gpa; | |
| 72 | 73 | const first_atom_index = macho_file.sections.items(.first_atom_index)[sect_id].?; |
| 73 | 74 | |
| 74 | 75 | header.size = 0; |
| ... | ... | @@ -245,7 +246,8 @@ fn scanRelocs( |
| 245 | 246 | macho_file.getSymbol(target).n_value, |
| 246 | 247 | }); |
| 247 | 248 | |
| 248 | const gpa = macho_file.base.allocator; | |
| 249 | const comp = macho_file.base.comp; | |
| 250 | const gpa = comp.gpa; | |
| 249 | 251 | const target_sym = macho_file.getSymbol(target); |
| 250 | 252 | const thunk = &macho_file.thunks.items[thunk_index]; |
| 251 | 253 |
src/link/MachO/zld.zig+25-17| ... | ... | @@ -15,7 +15,7 @@ pub fn linkWithZld( |
| 15 | 15 | const arena = arena_allocator.allocator(); |
| 16 | 16 | |
| 17 | 17 | const directory = emit.directory; // Just an alias to make it shorter to type. |
| 18 | const full_out_path = try directory.join(arena, &[_][]const u8{emit.?.sub_path}); | |
| 18 | const full_out_path = try directory.join(arena, &[_][]const u8{emit.sub_path}); | |
| 19 | 19 | const opt_zcu = macho_file.base.comp.module; |
| 20 | 20 | |
| 21 | 21 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| ... | ... | @@ -71,14 +71,14 @@ pub fn linkWithZld( |
| 71 | 71 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 72 | 72 | // installation sources because they are always a product of the compiler version + target information. |
| 73 | 73 | man.hash.add(stack_size); |
| 74 | man.hash.addOptional(macho_file.pagezero_vmsize); | |
| 75 | man.hash.addOptional(macho_file.headerpad_size); | |
| 74 | man.hash.add(macho_file.pagezero_vmsize); | |
| 75 | man.hash.add(macho_file.headerpad_size); | |
| 76 | 76 | man.hash.add(macho_file.headerpad_max_install_names); |
| 77 | 77 | man.hash.add(macho_file.base.gc_sections); |
| 78 | 78 | man.hash.add(macho_file.dead_strip_dylibs); |
| 79 | 79 | man.hash.add(macho_file.base.comp.root_mod.strip); |
| 80 | 80 | try MachO.hashAddFrameworks(&man, macho_file.frameworks); |
| 81 | man.hash.addListOfBytes(macho_file.rpath_list); | |
| 81 | man.hash.addListOfBytes(macho_file.base.rpath_list); | |
| 82 | 82 | if (is_dyn_lib) { |
| 83 | 83 | man.hash.addOptionalBytes(macho_file.install_name); |
| 84 | 84 | man.hash.addOptional(comp.version); |
| ... | ... | @@ -151,7 +151,7 @@ pub fn linkWithZld( |
| 151 | 151 | try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{}); |
| 152 | 152 | } |
| 153 | 153 | } else { |
| 154 | const sub_path = emit.?.sub_path; | |
| 154 | const sub_path = emit.sub_path; | |
| 155 | 155 | |
| 156 | 156 | const old_file = macho_file.base.file; // TODO is this needed at all? |
| 157 | 157 | defer macho_file.base.file = old_file; |
| ... | ... | @@ -241,7 +241,7 @@ pub fn linkWithZld( |
| 241 | 241 | try argv.append(@tagName(platform.os_tag)); |
| 242 | 242 | try argv.append(try std.fmt.allocPrint(arena, "{}", .{platform.version})); |
| 243 | 243 | |
| 244 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); | |
| 244 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(macho_file); | |
| 245 | 245 | if (sdk_version) |ver| { |
| 246 | 246 | try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor })); |
| 247 | 247 | } else { |
| ... | ... | @@ -254,13 +254,13 @@ pub fn linkWithZld( |
| 254 | 254 | try argv.append(syslibroot); |
| 255 | 255 | } |
| 256 | 256 | |
| 257 | for (macho_file.rpath_list) |rpath| { | |
| 257 | for (macho_file.base.rpath_list) |rpath| { | |
| 258 | 258 | try argv.append("-rpath"); |
| 259 | 259 | try argv.append(rpath); |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | try argv.appendSlice(&.{ |
| 263 | "-pagezero_size", try std.fmt.allocPrint(arena, "0x{x}", .{macho_file.pagezero_size}), | |
| 263 | "-pagezero_size", try std.fmt.allocPrint(arena, "0x{x}", .{macho_file.pagezero_vmsize}), | |
| 264 | 264 | "-headerpad_size", try std.fmt.allocPrint(arena, "0x{x}", .{macho_file.headerpad_size}), |
| 265 | 265 | }); |
| 266 | 266 | |
| ... | ... | @@ -558,7 +558,7 @@ pub fn linkWithZld( |
| 558 | 558 | }); |
| 559 | 559 | { |
| 560 | 560 | const platform = Platform.fromTarget(target); |
| 561 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp); | |
| 561 | const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(macho_file); | |
| 562 | 562 | if (platform.isBuildVersionCompatible()) { |
| 563 | 563 | try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer); |
| 564 | 564 | } else { |
| ... | ... | @@ -609,7 +609,8 @@ pub fn linkWithZld( |
| 609 | 609 | } |
| 610 | 610 | |
| 611 | 611 | fn createSegments(macho_file: *MachO) !void { |
| 612 | const gpa = macho_file.base.allocator; | |
| 612 | const comp = macho_file.base.comp; | |
| 613 | const gpa = comp.gpa; | |
| 613 | 614 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 614 | 615 | const page_size = MachO.getPageSize(target.cpu.arch); |
| 615 | 616 | const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size); |
| ... | ... | @@ -683,7 +684,8 @@ fn createSegments(macho_file: *MachO) !void { |
| 683 | 684 | } |
| 684 | 685 | |
| 685 | 686 | fn writeAtoms(macho_file: *MachO) !void { |
| 686 | const gpa = macho_file.base.allocator; | |
| 687 | const comp = macho_file.base.comp; | |
| 688 | const gpa = comp.gpa; | |
| 687 | 689 | const slice = macho_file.sections.slice(); |
| 688 | 690 | |
| 689 | 691 | for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| { |
| ... | ... | @@ -758,7 +760,8 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void { |
| 758 | 760 | fn writeThunks(macho_file: *MachO) !void { |
| 759 | 761 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 760 | 762 | assert(target.cpu.arch == .aarch64); |
| 761 | const gpa = macho_file.base.allocator; | |
| 763 | const comp = macho_file.base.comp; | |
| 764 | const gpa = comp.gpa; | |
| 762 | 765 | |
| 763 | 766 | const sect_id = macho_file.text_section_index orelse return; |
| 764 | 767 | const header = macho_file.sections.items(.header)[sect_id]; |
| ... | ... | @@ -778,7 +781,8 @@ fn writeThunks(macho_file: *MachO) !void { |
| 778 | 781 | } |
| 779 | 782 | |
| 780 | 783 | fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void { |
| 781 | const gpa = macho_file.base.allocator; | |
| 784 | const comp = macho_file.base.comp; | |
| 785 | const gpa = comp.gpa; | |
| 782 | 786 | const header = macho_file.sections.items(.header)[sect_id]; |
| 783 | 787 | const capacity = math.cast(usize, header.size) orelse return error.Overflow; |
| 784 | 788 | var buffer = try std.ArrayList(u8).initCapacity(gpa, capacity); |
| ... | ... | @@ -792,7 +796,8 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void { |
| 792 | 796 | } |
| 793 | 797 | |
| 794 | 798 | fn writeStubs(macho_file: *MachO) !void { |
| 795 | const gpa = macho_file.base.allocator; | |
| 799 | const comp = macho_file.base.comp; | |
| 800 | const gpa = comp.gpa; | |
| 796 | 801 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 797 | 802 | const cpu_arch = target.cpu.arch; |
| 798 | 803 | const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?]; |
| ... | ... | @@ -815,7 +820,8 @@ fn writeStubs(macho_file: *MachO) !void { |
| 815 | 820 | } |
| 816 | 821 | |
| 817 | 822 | fn writeStubHelpers(macho_file: *MachO) !void { |
| 818 | const gpa = macho_file.base.allocator; | |
| 823 | const comp = macho_file.base.comp; | |
| 824 | const gpa = comp.gpa; | |
| 819 | 825 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 820 | 826 | const cpu_arch = target.cpu.arch; |
| 821 | 827 | const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?]; |
| ... | ... | @@ -859,7 +865,8 @@ fn writeStubHelpers(macho_file: *MachO) !void { |
| 859 | 865 | } |
| 860 | 866 | |
| 861 | 867 | fn writeLaSymbolPtrs(macho_file: *MachO) !void { |
| 862 | const gpa = macho_file.base.allocator; | |
| 868 | const comp = macho_file.base.comp; | |
| 869 | const gpa = comp.gpa; | |
| 863 | 870 | const target = macho_file.base.comp.root_mod.resolved_target.result; |
| 864 | 871 | const cpu_arch = target.cpu.arch; |
| 865 | 872 | const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?]; |
| ... | ... | @@ -892,7 +899,8 @@ fn pruneAndSortSections(macho_file: *MachO) !void { |
| 892 | 899 | } |
| 893 | 900 | }; |
| 894 | 901 | |
| 895 | const gpa = macho_file.base.allocator; | |
| 902 | const comp = macho_file.base.comp; | |
| 903 | const gpa = comp.gpa; | |
| 896 | 904 | |
| 897 | 905 | var entries = try std.ArrayList(Entry).initCapacity(gpa, macho_file.sections.slice().len); |
| 898 | 906 | defer entries.deinit(); |
src/link/NvPtx.zig+1-2| ... | ... | @@ -31,8 +31,6 @@ pub fn createEmpty( |
| 31 | 31 | emit: Compilation.Emit, |
| 32 | 32 | options: link.File.OpenOptions, |
| 33 | 33 | ) !*NvPtx { |
| 34 | if (build_options.only_c) unreachable; | |
| 35 | ||
| 36 | 34 | const target = comp.root_mod.resolved_target.result; |
| 37 | 35 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 38 | 36 | const use_llvm = comp.config.use_llvm; |
| ... | ... | @@ -55,6 +53,7 @@ pub fn createEmpty( |
| 55 | 53 | .comp = comp, |
| 56 | 54 | .emit = emit, |
| 57 | 55 | .gc_sections = options.gc_sections orelse false, |
| 56 | .print_gc_sections = options.print_gc_sections, | |
| 58 | 57 | .stack_size = options.stack_size orelse 0, |
| 59 | 58 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 60 | 59 | .file = null, |
src/link/Plan9.zig+8-3| ... | ... | @@ -318,6 +318,7 @@ pub fn createEmpty( |
| 318 | 318 | .comp = comp, |
| 319 | 319 | .emit = emit, |
| 320 | 320 | .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj), |
| 321 | .print_gc_sections = options.print_gc_sections, | |
| 321 | 322 | .stack_size = options.stack_size orelse 16777216, |
| 322 | 323 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 323 | 324 | .file = null, |
| ... | ... | @@ -1314,8 +1315,6 @@ pub fn open( |
| 1314 | 1315 | emit: Compilation.Emit, |
| 1315 | 1316 | options: link.File.OpenOptions, |
| 1316 | 1317 | ) !*Plan9 { |
| 1317 | if (build_options.only_c) unreachable; | |
| 1318 | ||
| 1319 | 1318 | const target = comp.root_mod.resolved_target.result; |
| 1320 | 1319 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 1321 | 1320 | const use_llvm = comp.config.use_llvm; |
| ... | ... | @@ -1525,7 +1524,13 @@ pub fn getDeclVAddr( |
| 1525 | 1524 | return undefined; |
| 1526 | 1525 | } |
| 1527 | 1526 | |
| 1528 | pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result { | |
| 1527 | pub fn lowerAnonDecl( | |
| 1528 | self: *Plan9, | |
| 1529 | decl_val: InternPool.Index, | |
| 1530 | explicit_alignment: InternPool.Alignment, | |
| 1531 | src_loc: Module.SrcLoc, | |
| 1532 | ) !codegen.Result { | |
| 1533 | _ = explicit_alignment; | |
| 1529 | 1534 | // This is basically the same as lowerUnnamedConst. |
| 1530 | 1535 | // example: |
| 1531 | 1536 | // const ty = mod.intern_pool.typeOf(decl_val).toType(); |
src/link/SpirV.zig+11-8| ... | ... | @@ -24,7 +24,6 @@ const SpirV = @This(); |
| 24 | 24 | |
| 25 | 25 | const std = @import("std"); |
| 26 | 26 | const Allocator = std.mem.Allocator; |
| 27 | const ArenaAllocator = std.heap.ArenaAllocator; | |
| 28 | 27 | const assert = std.debug.assert; |
| 29 | 28 | const log = std.log.scoped(.link); |
| 30 | 29 | |
| ... | ... | @@ -65,6 +64,7 @@ pub fn createEmpty( |
| 65 | 64 | .comp = comp, |
| 66 | 65 | .emit = emit, |
| 67 | 66 | .gc_sections = options.gc_sections orelse false, |
| 67 | .print_gc_sections = options.print_gc_sections, | |
| 68 | 68 | .stack_size = options.stack_size orelse 0, |
| 69 | 69 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 70 | 70 | .file = null, |
| ... | ... | @@ -98,8 +98,6 @@ pub fn open( |
| 98 | 98 | emit: Compilation.Emit, |
| 99 | 99 | options: link.File.OpenOptions, |
| 100 | 100 | ) !*SpirV { |
| 101 | if (build_options.only_c) unreachable; | |
| 102 | ||
| 103 | 101 | const target = comp.root_mod.resolved_target.result; |
| 104 | 102 | const use_lld = build_options.have_llvm and comp.config.use_lld; |
| 105 | 103 | const use_llvm = comp.config.use_llvm; |
| ... | ... | @@ -194,7 +192,9 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 194 | 192 | |
| 195 | 193 | const spv = &self.object.spv; |
| 196 | 194 | |
| 195 | const gpa = comp.gpa; | |
| 197 | 196 | const target = comp.getTarget(); |
| 197 | ||
| 198 | 198 | try writeCapabilities(spv, target); |
| 199 | 199 | try writeMemoryModel(spv, target); |
| 200 | 200 | |
| ... | ... | @@ -214,11 +214,11 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 214 | 214 | // name if it contains no strange characters is nice for debugging. URI encoding fits the bill. |
| 215 | 215 | // We're using : as separator, which is a reserved character. |
| 216 | 216 | |
| 217 | const escaped_name = try std.Uri.escapeString(self.base.allocator, name); | |
| 218 | defer self.base.allocator.free(escaped_name); | |
| 217 | const escaped_name = try std.Uri.escapeString(gpa, name); | |
| 218 | defer gpa.free(escaped_name); | |
| 219 | 219 | try error_info.writer().print(":{s}", .{escaped_name}); |
| 220 | 220 | } |
| 221 | try spv.sections.debug_strings.emit(spv.gpa, .OpSourceExtension, .{ | |
| 221 | try spv.sections.debug_strings.emit(gpa, .OpSourceExtension, .{ | |
| 222 | 222 | .extension = error_info.items, |
| 223 | 223 | }); |
| 224 | 224 | |
| ... | ... | @@ -226,6 +226,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { |
| 229 | const gpa = spv.gpa; | |
| 229 | 230 | // TODO: Integrate with a hypothetical feature system |
| 230 | 231 | const caps: []const spec.Capability = switch (target.os.tag) { |
| 231 | 232 | .opencl => &.{ .Kernel, .Addresses, .Int8, .Int16, .Int64, .Float64, .Float16, .GenericPointer }, |
| ... | ... | @@ -235,13 +236,15 @@ fn writeCapabilities(spv: *SpvModule, target: std.Target) !void { |
| 235 | 236 | }; |
| 236 | 237 | |
| 237 | 238 | for (caps) |cap| { |
| 238 | try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{ | |
| 239 | try spv.sections.capabilities.emit(gpa, .OpCapability, .{ | |
| 239 | 240 | .capability = cap, |
| 240 | 241 | }); |
| 241 | 242 | } |
| 242 | 243 | } |
| 243 | 244 | |
| 244 | 245 | fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { |
| 246 | const gpa = spv.gpa; | |
| 247 | ||
| 245 | 248 | const addressing_model = switch (target.os.tag) { |
| 246 | 249 | .opencl => switch (target.cpu.arch) { |
| 247 | 250 | .spirv32 => spec.AddressingModel.Physical32, |
| ... | ... | @@ -260,7 +263,7 @@ fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void { |
| 260 | 263 | }; |
| 261 | 264 | |
| 262 | 265 | // TODO: Put this in a proper section. |
| 263 | try spv.sections.extensions.emit(spv.gpa, .OpMemoryModel, .{ | |
| 266 | try spv.sections.extensions.emit(gpa, .OpMemoryModel, .{ | |
| 264 | 267 | .addressing_model = addressing_model, |
| 265 | 268 | .memory_model = memory_model, |
| 266 | 269 | }); |
src/link/Wasm.zig+7-2| ... | ... | @@ -378,7 +378,6 @@ pub fn open( |
| 378 | 378 | emit: Compilation.Emit, |
| 379 | 379 | options: link.File.OpenOptions, |
| 380 | 380 | ) !*Wasm { |
| 381 | if (build_options.only_c) unreachable; | |
| 382 | 381 | const gpa = comp.gpa; |
| 383 | 382 | const target = comp.root_mod.resolved_target.result; |
| 384 | 383 | assert(target.ofmt == .wasm); |
| ... | ... | @@ -549,6 +548,7 @@ pub fn createEmpty( |
| 549 | 548 | .comp = comp, |
| 550 | 549 | .emit = emit, |
| 551 | 550 | .gc_sections = options.gc_sections orelse (output_mode != .Obj), |
| 551 | .print_gc_sections = options.print_gc_sections, | |
| 552 | 552 | .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB |
| 553 | 553 | .allow_shlib_undefined = options.allow_shlib_undefined orelse false, |
| 554 | 554 | .file = null, |
| ... | ... | @@ -1893,7 +1893,12 @@ pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: lin |
| 1893 | 1893 | return target_symbol_index; |
| 1894 | 1894 | } |
| 1895 | 1895 | |
| 1896 | pub fn deleteDeclExport(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { | |
| 1896 | pub fn deleteDeclExport( | |
| 1897 | wasm: *Wasm, | |
| 1898 | decl_index: InternPool.DeclIndex, | |
| 1899 | name: InternPool.NullTerminatedString, | |
| 1900 | ) void { | |
| 1901 | _ = name; | |
| 1897 | 1902 | if (wasm.llvm_object) |_| return; |
| 1898 | 1903 | const atom_index = wasm.decls.get(decl_index) orelse return; |
| 1899 | 1904 | const sym_index = wasm.getAtom(atom_index).sym_index; |
src/link/Wasm/Object.zig+6-4| ... | ... | @@ -883,6 +883,8 @@ fn assertEnd(reader: anytype) !void { |
| 883 | 883 | |
| 884 | 884 | /// Parses an object file into atoms, for code and data sections |
| 885 | 885 | pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32, wasm: *Wasm) !Atom.Index { |
| 886 | const comp = wasm.base.comp; | |
| 887 | const gpa = comp.gpa; | |
| 886 | 888 | const symbol = &object.symtable[symbol_index]; |
| 887 | 889 | const relocatable_data: RelocatableData = switch (symbol.tag) { |
| 888 | 890 | .function => object.relocatable_data.get(.code).?[symbol.index - object.importedCountByKind(.function)], |
| ... | ... | @@ -900,7 +902,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 900 | 902 | }; |
| 901 | 903 | const final_index = try wasm.getMatchingSegment(object_index, symbol_index); |
| 902 | 904 | const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len)); |
| 903 | const atom = try wasm.managed_atoms.addOne(wasm.base.allocator); | |
| 905 | const atom = try wasm.managed_atoms.addOne(gpa); | |
| 904 | 906 | atom.* = Atom.empty; |
| 905 | 907 | try wasm.appendAtomAtIndex(final_index, atom_index); |
| 906 | 908 | |
| ... | ... | @@ -910,7 +912,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 910 | 912 | atom.alignment = relocatable_data.getAlignment(object); |
| 911 | 913 | atom.code = std.ArrayListUnmanaged(u8).fromOwnedSlice(relocatable_data.data[0..relocatable_data.size]); |
| 912 | 914 | atom.original_offset = relocatable_data.offset; |
| 913 | try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom_index); | |
| 915 | try wasm.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom_index); | |
| 914 | 916 | const segment: *Wasm.Segment = &wasm.segments.items[final_index]; |
| 915 | 917 | if (relocatable_data.type == .data) { //code section and custom sections are 1-byte aligned |
| 916 | 918 | segment.alignment = segment.alignment.max(atom.alignment); |
| ... | ... | @@ -927,7 +929,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 927 | 929 | .R_WASM_TABLE_INDEX_SLEB, |
| 928 | 930 | .R_WASM_TABLE_INDEX_SLEB64, |
| 929 | 931 | => { |
| 930 | try wasm.function_table.put(wasm.base.allocator, .{ | |
| 932 | try wasm.function_table.put(gpa, .{ | |
| 931 | 933 | .file = object_index, |
| 932 | 934 | .index = reloc.index, |
| 933 | 935 | }, 0); |
| ... | ... | @@ -938,7 +940,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32 |
| 938 | 940 | const sym = object.symtable[reloc.index]; |
| 939 | 941 | if (sym.tag != .global) { |
| 940 | 942 | try wasm.got_symbols.append( |
| 941 | wasm.base.allocator, | |
| 943 | gpa, | |
| 942 | 944 | .{ .file = object_index, .index = reloc.index }, |
| 943 | 945 | ); |
| 944 | 946 | } |
src/main.zig+10-14| ... | ... | @@ -874,8 +874,8 @@ fn buildOutputType( |
| 874 | 874 | var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); |
| 875 | 875 | var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no; |
| 876 | 876 | var subsystem: ?std.Target.SubSystem = null; |
| 877 | var major_subsystem_version: ?u32 = null; | |
| 878 | var minor_subsystem_version: ?u32 = null; | |
| 877 | var major_subsystem_version: ?u16 = null; | |
| 878 | var minor_subsystem_version: ?u16 = null; | |
| 879 | 879 | var enable_link_snapshots: bool = false; |
| 880 | 880 | var debug_incremental: bool = false; |
| 881 | 881 | var install_name: ?[]const u8 = null; |
| ... | ... | @@ -2321,21 +2321,17 @@ fn buildOutputType( |
| 2321 | 2321 | _ = linker_args_it.nextOrFatal(); |
| 2322 | 2322 | } else if (mem.eql(u8, arg, "--major-subsystem-version")) { |
| 2323 | 2323 | const major = linker_args_it.nextOrFatal(); |
| 2324 | major_subsystem_version = std.fmt.parseUnsigned( | |
| 2325 | u32, | |
| 2326 | major, | |
| 2327 | 10, | |
| 2328 | ) catch |err| { | |
| 2329 | fatal("unable to parse major subsystem version '{s}': {s}", .{ major, @errorName(err) }); | |
| 2324 | major_subsystem_version = std.fmt.parseUnsigned(u16, major, 10) catch |err| { | |
| 2325 | fatal("unable to parse major subsystem version '{s}': {s}", .{ | |
| 2326 | major, @errorName(err), | |
| 2327 | }); | |
| 2330 | 2328 | }; |
| 2331 | 2329 | } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { |
| 2332 | 2330 | const minor = linker_args_it.nextOrFatal(); |
| 2333 | minor_subsystem_version = std.fmt.parseUnsigned( | |
| 2334 | u32, | |
| 2335 | minor, | |
| 2336 | 10, | |
| 2337 | ) catch |err| { | |
| 2338 | fatal("unable to parse minor subsystem version '{s}': {s}", .{ minor, @errorName(err) }); | |
| 2331 | minor_subsystem_version = std.fmt.parseUnsigned(u16, minor, 10) catch |err| { | |
| 2332 | fatal("unable to parse minor subsystem version '{s}': {s}", .{ | |
| 2333 | minor, @errorName(err), | |
| 2334 | }); | |
| 2339 | 2335 | }; |
| 2340 | 2336 | } else if (mem.eql(u8, arg, "-framework")) { |
| 2341 | 2337 | try frameworks.put(arena, linker_args_it.nextOrFatal(), .{}); |