authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-16 00:39:36-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:20-07:00
log2047a6b82d2e6cdbddde3e7f1c93df9e72216052
treec9717626d48bc85a0e5dbe12bb2d815241ac9c94
parent46297087871dec88c2b632d057f1e55b662126df

fix remaining compile errors except one


28 files changed, 340 insertions(+), 341 deletions(-)

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