From 2ee864ca5eb46468e8e0f4237a5532b76b60d715 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 5 Jul 2022 15:21:20 -0700 Subject: [PATCH] CLI: add support for -fno-builtin --- src/Compilation.zig | 8 ++++++++ src/clang_options_data.zig | 18 ++++++++++++++++-- src/codegen/llvm.zig | 4 +++- src/link.zig | 1 + src/main.zig | 17 ++++++++++++++++- tools/update_clang_options.zig | 8 ++++++++ 6 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index feb9fedceb..85db5aa76a 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -825,6 +825,7 @@ pub const InitOptions = struct { rdynamic: bool = false, strip: bool = false, function_sections: bool = false, + no_builtin: bool = false, is_native_os: bool, is_native_abi: bool, time_report: bool = false, @@ -1351,6 +1352,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { cache.hash.add(omit_frame_pointer); cache.hash.add(link_mode); cache.hash.add(options.function_sections); + cache.hash.add(options.no_builtin); cache.hash.add(strip); cache.hash.add(link_libc); cache.hash.add(link_libcpp); @@ -1682,6 +1684,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .is_native_os = options.is_native_os, .is_native_abi = options.is_native_abi, .function_sections = options.function_sections, + .no_builtin = options.no_builtin, .allow_shlib_undefined = options.linker_allow_shlib_undefined, .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false, .import_memory = options.linker_import_memory orelse false, @@ -3925,6 +3928,10 @@ pub fn addCCArgs( try argv.append("-ffunction-sections"); } + if (comp.bin_file.options.no_builtin) { + try argv.append("-fno-builtin"); + } + if (comp.bin_file.options.link_libcpp) { const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "libcxx", "include", @@ -4997,6 +5004,7 @@ fn buildOutputFromZig( .optimize_mode = comp.compilerRtOptMode(), .link_mode = .Static, .function_sections = true, + .no_builtin = true, .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig index 0757875add..cd9d603157 100644 --- a/src/clang_options_data.zig +++ b/src/clang_options_data.zig @@ -2529,7 +2529,14 @@ flagpd1("fborland-extensions"), flagpd1("fbounds-check"), sepd1("fbracket-depth"), flagpd1("fbranch-count-reg"), -flagpd1("fbuiltin"), +.{ + .name = "fbuiltin", + .syntax = .flag, + .zig_equivalent = .builtin, + .pd1 = true, + .pd2 = false, + .psl = false, +}, flagpd1("fbuiltin-module-map"), flagpd1("fcall-saved-x10"), flagpd1("fcall-saved-x11"), @@ -2925,7 +2932,14 @@ flagpd1("fno-blocks"), flagpd1("fno-borland-extensions"), flagpd1("fno-bounds-check"), flagpd1("fno-branch-count-reg"), -flagpd1("fno-builtin"), +.{ + .name = "fno-builtin", + .syntax = .flag, + .zig_equivalent = .no_builtin, + .pd1 = true, + .pd2 = false, + .psl = false, +}, flagpd1("fno-caller-saves"), .{ .name = "fno-caret-diagnostics", diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 590cee3d73..1b7e33a3a4 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2347,7 +2347,9 @@ pub const DeclGen = struct { if (comp.unwind_tables) { dg.addFnAttr(llvm_fn, "uwtable"); } - if (comp.bin_file.options.skip_linker_dependencies) { + if (comp.bin_file.options.skip_linker_dependencies or + comp.bin_file.options.no_builtin) + { // The intent here is for compiler-rt and libc functions to not generate // infinite recursion. For example, if we are compiling the memcpy function, // and llvm detects that the body is equivalent to memcpy, it may replace the diff --git a/src/link.zig b/src/link.zig index 97eb9f8876..871ceded6c 100644 --- a/src/link.zig +++ b/src/link.zig @@ -108,6 +108,7 @@ pub const Options = struct { link_libcpp: bool, link_libunwind: bool, function_sections: bool, + no_builtin: bool, eh_frame_hdr: bool, emit_relocs: bool, rdynamic: bool, diff --git a/src/main.zig b/src/main.zig index 00696693f2..4fe048bb93 100644 --- a/src/main.zig +++ b/src/main.zig @@ -381,6 +381,10 @@ const usage_build_generic = \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend \\ -fsingle-threaded Code assumes there is only one thread \\ -fno-single-threaded Code may not assume there is only one thread + \\ -fbuiltin Enable implicit builtin knowledge of functions + \\ -fno-builtin Disable implicit builtin knowledge of functions + \\ -ffunction-sections Places each function in a separate section + \\ -fno-function-sections All functions go into same section \\ --strip Omit debug symbols \\ -ofmt=[mode] Override target object format \\ elf Executable and Linking Format @@ -398,7 +402,6 @@ const usage_build_generic = \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted) \\ --libc [file] Provide a file which specifies libc paths \\ -cflags [flags] -- Set extra flags for the next positional C source files - \\ -ffunction-sections Places each function in a separate section \\ \\Link Options: \\ -l[lib], --library [lib] Link against system library (only if actually used) @@ -604,6 +607,7 @@ fn buildOutputType( var compatibility_version: ?std.builtin.Version = null; var strip = false; var function_sections = false; + var no_builtin = false; var watch = false; var debug_compile_errors = false; var verbose_link = std.process.hasEnvVarConstant("ZIG_VERBOSE_LINK"); @@ -1241,6 +1245,12 @@ fn buildOutputType( single_threaded = false; } else if (mem.eql(u8, arg, "-ffunction-sections")) { function_sections = true; + } else if (mem.eql(u8, arg, "-fno-function-sections")) { + function_sections = false; + } else if (mem.eql(u8, arg, "-fbuiltin")) { + no_builtin = false; + } else if (mem.eql(u8, arg, "-fno-builtin")) { + no_builtin = true; } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; } else if (mem.eql(u8, arg, "--emit-relocs")) { @@ -1464,6 +1474,8 @@ fn buildOutputType( .no_omit_frame_pointer => omit_frame_pointer = false, .function_sections => function_sections = true, .no_function_sections => function_sections = false, + .builtin => no_builtin = false, + .no_builtin => no_builtin = true, .color_diagnostics => color = .on, .no_color_diagnostics => color = .off, .stack_check => want_stack_check = true, @@ -2847,6 +2859,7 @@ fn buildOutputType( .strip = strip, .single_threaded = single_threaded, .function_sections = function_sections, + .no_builtin = no_builtin, .self_exe_path = self_exe_path, .thread_pool = &thread_pool, .clang_passthrough_mode = clang_passthrough_mode, @@ -4572,6 +4585,8 @@ pub const ClangArgIterator = struct { no_omit_frame_pointer, function_sections, no_function_sections, + builtin, + no_builtin, color_diagnostics, no_color_diagnostics, stack_check, diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 6bf4c47ebc..fc460d8744 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -320,6 +320,14 @@ const known_options = [_]KnownOpt{ .name = "fno-function-sections", .ident = "no_function_sections", }, + .{ + .name = "fbuiltin", + .ident = "builtin", + }, + .{ + .name = "fno-builtin", + .ident = "no_builtin", + }, .{ .name = "fcolor-diagnostics", .ident = "color_diagnostics",