authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-05 14:29:44+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-05 14:43:02+01:00
logb57819118ddf287a135b4c2fb7182615b402fbc2
tree6b55bd9b957750e542bec14373e3ba27aef94b5a
parent56b416662aa89196d5b974632dcd927d26b5d12c
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Compilation: Move no_builtin to Package.Module.

This option, by its very nature, needs to be attached to a module. If it isn't, the code in a module could break at random when compiled into an application that doesn't have this option set. After this change, skip_linker_dependencies no longer implies no_builtin in the LLVM backend.

8 files changed, 65 insertions(+), 40 deletions(-)

src/Compilation.zig+13-9
......@@ -89,7 +89,6 @@ windows_libs: std.StringArrayHashMapUnmanaged(void),
8989version: ?std.SemanticVersion,
9090libc_installation: ?*const LibCInstallation,
9191skip_linker_dependencies: bool,
92no_builtin: bool,
9392function_sections: bool,
9493data_sections: bool,
9594link_eh_frame_hdr: bool,
......@@ -852,6 +851,7 @@ pub const cache_helpers = struct {
852851 hh.add(mod.fuzz);
853852 hh.add(mod.unwind_tables);
854853 hh.add(mod.structured_cfg);
854 hh.add(mod.no_builtin);
855855 hh.addListOfBytes(mod.cc_argv);
856856 }
857857
......@@ -1057,7 +1057,6 @@ pub const CreateOptions = struct {
10571057 want_lto: ?bool = null,
10581058 function_sections: bool = false,
10591059 data_sections: bool = false,
1060 no_builtin: bool = false,
10611060 time_report: bool = false,
10621061 stack_report: bool = false,
10631062 link_eh_frame_hdr: bool = false,
......@@ -1353,7 +1352,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
13531352 cache.hash.add(options.config.link_mode);
13541353 cache.hash.add(options.function_sections);
13551354 cache.hash.add(options.data_sections);
1356 cache.hash.add(options.no_builtin);
13571355 cache.hash.add(link_libc);
13581356 cache.hash.add(options.config.link_libcpp);
13591357 cache.hash.add(options.config.link_libunwind);
......@@ -1490,7 +1488,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
14901488 .framework_dirs = options.framework_dirs,
14911489 .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit,
14921490 .skip_linker_dependencies = options.skip_linker_dependencies,
1493 .no_builtin = options.no_builtin,
14941491 .job_queued_update_builtin_zig = have_zcu,
14951492 .function_sections = options.function_sections,
14961493 .data_sections = options.data_sections,
......@@ -5261,7 +5258,7 @@ pub fn addCCArgs(
52615258 try argv.append("-fdata-sections");
52625259 }
52635260
5264 if (comp.no_builtin) {
5261 if (mod.no_builtin) {
52655262 try argv.append("-fno-builtin");
52665263 }
52675264
......@@ -6189,6 +6186,7 @@ fn buildOutputFromZig(
61896186 .pic = comp.root_mod.pic,
61906187 .optimize_mode = optimize_mode,
61916188 .structured_cfg = comp.root_mod.structured_cfg,
6189 .no_builtin = true,
61926190 .code_model = comp.root_mod.code_model,
61936191 },
61946192 .global = config,
......@@ -6237,7 +6235,6 @@ fn buildOutputFromZig(
62376235 },
62386236 .function_sections = true,
62396237 .data_sections = true,
6240 .no_builtin = true,
62416238 .emit_h = null,
62426239 .verbose_cc = comp.verbose_cc,
62436240 .verbose_link = comp.verbose_link,
......@@ -6262,16 +6259,21 @@ fn buildOutputFromZig(
62626259 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
62636260}
62646261
6262pub const CrtFileOptions = struct {
6263 pic: ?bool = null,
6264 no_builtin: ?bool = null,
6265};
6266
62656267pub fn build_crt_file(
62666268 comp: *Compilation,
62676269 root_name: []const u8,
62686270 output_mode: std.builtin.OutputMode,
6269 pic: ?bool,
62706271 misc_task_tag: MiscTask,
62716272 prog_node: std.Progress.Node,
62726273 /// These elements have to get mutated to add the owner module after it is
62736274 /// created within this function.
62746275 c_source_files: []CSourceFile,
6276 options: CrtFileOptions,
62756277) !void {
62766278 const tracy_trace = trace(@src());
62776279 defer tracy_trace.end();
......@@ -6319,10 +6321,12 @@ pub fn build_crt_file(
63196321 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
63206322 .valgrind = false,
63216323 .unwind_tables = false,
6322 // Some CRT objects (rcrt1.o, Scrt1.o) are opinionated about PIC.
6323 .pic = pic orelse comp.root_mod.pic,
6324 // Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC.
6325 .pic = options.pic orelse comp.root_mod.pic,
63246326 .optimize_mode = comp.compilerRtOptMode(),
63256327 .structured_cfg = comp.root_mod.structured_cfg,
6328 // Some libcs (e.g. musl) are opinionated about -fno-builtin.
6329 .no_builtin = options.no_builtin orelse comp.root_mod.no_builtin,
63266330 },
63276331 .global = config,
63286332 .cc_argv = &.{},
src/Package/Module.zig+12
......@@ -31,6 +31,7 @@ unwind_tables: bool,
3131cc_argv: []const []const u8,
3232/// (SPIR-V) whether to generate a structured control flow graph or not
3333structured_cfg: bool,
34no_builtin: bool,
3435
3536/// If the module is an `@import("builtin")` module, this is the `File` that
3637/// is preallocated for it. Otherwise this field is null.
......@@ -95,6 +96,7 @@ pub const CreateOptions = struct {
9596 sanitize_thread: ?bool = null,
9697 fuzz: ?bool = null,
9798 structured_cfg: ?bool = null,
99 no_builtin: ?bool = null,
98100 };
99101};
100102
......@@ -298,6 +300,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
298300 };
299301 };
300302
303 const no_builtin = b: {
304 if (options.inherited.no_builtin) |x| break :b x;
305 if (options.parent) |p| break :b p.no_builtin;
306
307 break :b target.cpu.arch.isBpf();
308 };
309
301310 const llvm_cpu_features: ?[*:0]const u8 = b: {
302311 if (resolved_target.llvm_cpu_features) |x| break :b x;
303312 if (!options.global.use_llvm) break :b null;
......@@ -350,6 +359,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
350359 .unwind_tables = unwind_tables,
351360 .cc_argv = options.cc_argv,
352361 .structured_cfg = structured_cfg,
362 .no_builtin = no_builtin,
353363 .builtin_file = null,
354364 };
355365
......@@ -442,6 +452,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
442452 .unwind_tables = unwind_tables,
443453 .cc_argv = &.{},
444454 .structured_cfg = structured_cfg,
455 .no_builtin = no_builtin,
445456 .builtin_file = new_file,
446457 };
447458 new_file.* = .{
......@@ -502,6 +513,7 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P
502513 .unwind_tables = undefined,
503514 .cc_argv = undefined,
504515 .structured_cfg = undefined,
516 .no_builtin = undefined,
505517 .builtin_file = null,
506518 };
507519 return mod;
src/codegen/llvm.zig+2-4
......@@ -3222,8 +3222,6 @@ pub const Object = struct {
32223222 owner_mod: *Package.Module,
32233223 omit_frame_pointer: bool,
32243224 ) Allocator.Error!void {
3225 const comp = o.pt.zcu.comp;
3226
32273225 if (!owner_mod.red_zone) {
32283226 try attributes.addFnAttr(.noredzone, &o.builder);
32293227 }
......@@ -3242,8 +3240,7 @@ pub const Object = struct {
32423240 if (owner_mod.unwind_tables) {
32433241 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
32443242 }
3245 const target = owner_mod.resolved_target.result;
3246 if (comp.skip_linker_dependencies or comp.no_builtin or target.cpu.arch.isBpf()) {
3243 if (owner_mod.no_builtin) {
32473244 // The intent here is for compiler-rt and libc functions to not generate
32483245 // infinite recursion. For example, if we are compiling the memcpy function,
32493246 // and llvm detects that the body is equivalent to memcpy, it may replace the
......@@ -3258,6 +3255,7 @@ pub const Object = struct {
32583255 try attributes.addFnAttr(.minsize, &o.builder);
32593256 try attributes.addFnAttr(.optsize, &o.builder);
32603257 }
3258 const target = owner_mod.resolved_target.result;
32613259 if (target.cpu.model.llvm_name) |s| {
32623260 try attributes.addFnAttr(.{ .string = .{
32633261 .kind = try o.builder.string("target-cpu"),
src/glibc.zig+4-4
......@@ -221,7 +221,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
221221 .owner = comp.root_mod,
222222 },
223223 };
224 return comp.build_crt_file("crti", .Obj, null, .@"glibc crti.o", prog_node, &files);
224 return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &files, .{});
225225 },
226226 .crtn_o => {
227227 var args = std.ArrayList([]const u8).init(arena);
......@@ -242,7 +242,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
242242 .owner = undefined,
243243 },
244244 };
245 return comp.build_crt_file("crtn", .Obj, null, .@"glibc crtn.o", prog_node, &files);
245 return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &files, .{});
246246 },
247247 .scrt1_o => {
248248 const start_o: Compilation.CSourceFile = blk: {
......@@ -295,7 +295,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
295295 };
296296 var files = [_]Compilation.CSourceFile{ start_o, abi_note_o, init_o };
297297 const basename = if (comp.config.output_mode == .Exe and !comp.config.pie) "crt1" else "Scrt1";
298 return comp.build_crt_file(basename, .Obj, null, .@"glibc Scrt1.o", prog_node, &files);
298 return comp.build_crt_file(basename, .Obj, .@"glibc Scrt1.o", prog_node, &files, .{});
299299 },
300300 .libc_nonshared_a => {
301301 const s = path.sep_str;
......@@ -413,7 +413,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
413413 files_index += 1;
414414 }
415415 const files = files_buf[0..files_index];
416 return comp.build_crt_file("c_nonshared", .Lib, null, .@"glibc libc_nonshared.a", prog_node, files);
416 return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files, .{});
417417 },
418418 }
419419}
src/main.zig+4-6
......@@ -810,7 +810,6 @@ fn buildOutputType(
810810 var compatibility_version: ?std.SemanticVersion = null;
811811 var function_sections = false;
812812 var data_sections = false;
813 var no_builtin = false;
814813 var listen: Listen = .none;
815814 var debug_compile_errors = false;
816815 var verbose_link = (native_os != .wasi or builtin.link_libc) and
......@@ -1550,9 +1549,9 @@ fn buildOutputType(
15501549 } else if (mem.eql(u8, arg, "-fno-data-sections")) {
15511550 data_sections = false;
15521551 } else if (mem.eql(u8, arg, "-fbuiltin")) {
1553 no_builtin = false;
1552 mod_opts.no_builtin = false;
15541553 } else if (mem.eql(u8, arg, "-fno-builtin")) {
1555 no_builtin = true;
1554 mod_opts.no_builtin = true;
15561555 } else if (mem.startsWith(u8, arg, "-fopt-bisect-limit=")) {
15571556 const next_arg = arg["-fopt-bisect-limit=".len..];
15581557 llvm_opt_bisect_limit = std.fmt.parseInt(c_int, next_arg, 0) catch |err|
......@@ -1963,8 +1962,8 @@ fn buildOutputType(
19631962 .no_function_sections => function_sections = false,
19641963 .data_sections => data_sections = true,
19651964 .no_data_sections => data_sections = false,
1966 .builtin => no_builtin = false,
1967 .no_builtin => no_builtin = true,
1965 .builtin => mod_opts.no_builtin = false,
1966 .no_builtin => mod_opts.no_builtin = true,
19681967 .color_diagnostics => color = .on,
19691968 .no_color_diagnostics => color = .off,
19701969 .stack_check => mod_opts.stack_check = true,
......@@ -3468,7 +3467,6 @@ fn buildOutputType(
34683467 .image_base = image_base,
34693468 .function_sections = function_sections,
34703469 .data_sections = data_sections,
3471 .no_builtin = no_builtin,
34723470 .clang_passthrough_mode = clang_passthrough_mode,
34733471 .clang_preprocessor_mode = clang_preprocessor_mode,
34743472 .version = optional_version,
src/mingw.zig+3-3
......@@ -41,7 +41,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
4141 .owner = undefined,
4242 },
4343 };
44 return comp.build_crt_file("crt2", .Obj, null, .@"mingw-w64 crt2.o", prog_node, &files);
44 return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files, .{});
4545 },
4646
4747 .dllcrt2_o => {
......@@ -56,7 +56,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
5656 .owner = undefined,
5757 },
5858 };
59 return comp.build_crt_file("dllcrt2", .Obj, null, .@"mingw-w64 dllcrt2.o", prog_node, &files);
59 return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files, .{});
6060 },
6161
6262 .mingw32_lib => {
......@@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
118118 } else {
119119 @panic("unsupported arch");
120120 }
121 return comp.build_crt_file("mingw32", .Lib, null, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items);
121 return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, c_source_files.items, .{});
122122 },
123123 }
124124}
src/musl.zig+20-7
......@@ -38,7 +38,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
3838 .owner = undefined,
3939 },
4040 };
41 return comp.build_crt_file("crti", .Obj, null, .@"musl crti.o", prog_node, &files);
41 return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &files, .{
42 .no_builtin = true,
43 });
4244 },
4345 .crtn_o => {
4446 var args = std.ArrayList([]const u8).init(arena);
......@@ -50,7 +52,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
5052 .owner = undefined,
5153 },
5254 };
53 return comp.build_crt_file("crtn", .Obj, null, .@"musl crtn.o", prog_node, &files);
55 return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &files, .{
56 .no_builtin = true,
57 });
5458 },
5559 .crt1_o => {
5660 var args = std.ArrayList([]const u8).init(arena);
......@@ -68,7 +72,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
6872 .owner = undefined,
6973 },
7074 };
71 return comp.build_crt_file("crt1", .Obj, null, .@"musl crt1.o", prog_node, &files);
75 return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &files, .{
76 .no_builtin = true,
77 });
7278 },
7379 .rcrt1_o => {
7480 var args = std.ArrayList([]const u8).init(arena);
......@@ -86,7 +92,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
8692 .owner = undefined,
8793 },
8894 };
89 return comp.build_crt_file("rcrt1", .Obj, true, .@"musl rcrt1.o", prog_node, &files);
95 return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &files, .{
96 .pic = true,
97 .no_builtin = true,
98 });
9099 },
91100 .scrt1_o => {
92101 var args = std.ArrayList([]const u8).init(arena);
......@@ -104,7 +113,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
104113 .owner = undefined,
105114 },
106115 };
107 return comp.build_crt_file("Scrt1", .Obj, true, .@"musl Scrt1.o", prog_node, &files);
116 return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &files, .{
117 .pic = true,
118 .no_builtin = true,
119 });
108120 },
109121 .libc_a => {
110122 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
......@@ -197,7 +209,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
197209 .owner = undefined,
198210 };
199211 }
200 return comp.build_crt_file("c", .Lib, null, .@"musl libc.a", prog_node, c_source_files.items);
212 return comp.build_crt_file("c", .Lib, .@"musl libc.a", prog_node, c_source_files.items, .{
213 .no_builtin = true,
214 });
201215 },
202216 .libc_so => {
203217 const optimize_mode = comp.compilerRtOptMode();
......@@ -410,7 +424,6 @@ fn addCcArgs(
410424 try args.appendSlice(&[_][]const u8{
411425 "-std=c99",
412426 "-ffreestanding",
413 "-fno-builtin",
414427 "-fexcess-precision=standard",
415428 "-frounding-math",
416429 "-ffp-contract=off",
src/wasi_libc.zig+7-7
......@@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
8181 .owner = undefined,
8282 },
8383 };
84 return comp.build_crt_file("crt1-reactor", .Obj, null, .@"wasi crt1-reactor.o", prog_node, &files);
84 return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files, .{});
8585 },
8686 .crt1_command_o => {
8787 var args = std.ArrayList([]const u8).init(arena);
......@@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
9696 .owner = undefined,
9797 },
9898 };
99 return comp.build_crt_file("crt1-command", .Obj, null, .@"wasi crt1-command.o", prog_node, &files);
99 return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files, .{});
100100 },
101101 .libc_a => {
102102 var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
......@@ -150,7 +150,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
150150 }
151151 }
152152
153 try comp.build_crt_file("c", .Lib, null, .@"wasi libc.a", prog_node, libc_sources.items);
153 try comp.build_crt_file("c", .Lib, .@"wasi libc.a", prog_node, libc_sources.items, .{});
154154 },
155155 .libwasi_emulated_process_clocks_a => {
156156 var args = std.ArrayList([]const u8).init(arena);
......@@ -167,7 +167,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
167167 .owner = undefined,
168168 });
169169 }
170 try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, null, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items);
170 try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items, .{});
171171 },
172172 .libwasi_emulated_getpid_a => {
173173 var args = std.ArrayList([]const u8).init(arena);
......@@ -184,7 +184,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
184184 .owner = undefined,
185185 });
186186 }
187 try comp.build_crt_file("wasi-emulated-getpid", .Lib, null, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items);
187 try comp.build_crt_file("wasi-emulated-getpid", .Lib, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items, .{});
188188 },
189189 .libwasi_emulated_mman_a => {
190190 var args = std.ArrayList([]const u8).init(arena);
......@@ -201,7 +201,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
201201 .owner = undefined,
202202 });
203203 }
204 try comp.build_crt_file("wasi-emulated-mman", .Lib, null, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items);
204 try comp.build_crt_file("wasi-emulated-mman", .Lib, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items, .{});
205205 },
206206 .libwasi_emulated_signal_a => {
207207 var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
......@@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
238238 }
239239 }
240240
241 try comp.build_crt_file("wasi-emulated-signal", .Lib, null, .@"libwasi-emulated-signal.a", prog_node, emu_signal_sources.items);
241 try comp.build_crt_file("wasi-emulated-signal", .Lib, .@"libwasi-emulated-signal.a", prog_node, emu_signal_sources.items, .{});
242242 },
243243 }
244244}