Skip to content

compiler: Improve handling of -fno-builtin and compiler-rt options #21920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions lib/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ const native_os = builtin.os.tag;
const native_arch = builtin.cpu.arch;
const native_abi = builtin.abi;

const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .internal else .strong;

const is_wasm = switch (native_arch) {
.wasm32, .wasm64 => true,
else => false,
};
const is_msvc = switch (native_abi) {
.msvc => true,
else => false,
};
const is_freestanding = switch (native_os) {
.freestanding => true,
.freestanding, .other => true,
else => false,
};

Expand All @@ -30,14 +28,14 @@ comptime {
}

if (builtin.link_libc) {
@export(&strcmp, .{ .name = "strcmp", .linkage = .strong });
@export(&strncmp, .{ .name = "strncmp", .linkage = .strong });
@export(&strerror, .{ .name = "strerror", .linkage = .strong });
@export(&strlen, .{ .name = "strlen", .linkage = .strong });
@export(&strcpy, .{ .name = "strcpy", .linkage = .strong });
@export(&strncpy, .{ .name = "strncpy", .linkage = .strong });
@export(&strcat, .{ .name = "strcat", .linkage = .strong });
@export(&strncat, .{ .name = "strncat", .linkage = .strong });
@export(&strcmp, .{ .name = "strcmp", .linkage = linkage });
@export(&strncmp, .{ .name = "strncmp", .linkage = linkage });
@export(&strerror, .{ .name = "strerror", .linkage = linkage });
@export(&strlen, .{ .name = "strlen", .linkage = linkage });
@export(&strcpy, .{ .name = "strcpy", .linkage = linkage });
@export(&strncpy, .{ .name = "strncpy", .linkage = linkage });
@export(&strcat, .{ .name = "strcat", .linkage = linkage });
@export(&strncat, .{ .name = "strncat", .linkage = linkage });
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ pub fn toElfMachine(target: Target) std.elf.EM {
pub fn toCoffMachine(target: Target) std.coff.MachineType {
return switch (target.cpu.arch) {
.arm => .ARM,
.thumb => .THUMB,
.thumb => .ARMNT,
.aarch64 => .ARM64,
.loongarch32 => .LOONGARCH32,
.loongarch64 => .LOONGARCH64,
Expand Down
40 changes: 26 additions & 14 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ windows_libs: std.StringArrayHashMapUnmanaged(void),
version: ?std.SemanticVersion,
libc_installation: ?*const LibCInstallation,
skip_linker_dependencies: bool,
no_builtin: bool,
function_sections: bool,
data_sections: bool,
link_eh_frame_hdr: bool,
Expand Down Expand Up @@ -852,6 +851,7 @@ pub const cache_helpers = struct {
hh.add(mod.fuzz);
hh.add(mod.unwind_tables);
hh.add(mod.structured_cfg);
hh.add(mod.no_builtin);
hh.addListOfBytes(mod.cc_argv);
}

Expand Down Expand Up @@ -1057,7 +1057,6 @@ pub const CreateOptions = struct {
want_lto: ?bool = null,
function_sections: bool = false,
data_sections: bool = false,
no_builtin: bool = false,
time_report: bool = false,
stack_report: bool = false,
link_eh_frame_hdr: bool = false,
Expand Down Expand Up @@ -1299,7 +1298,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
},
.fully_qualified_name = "compiler_rt",
.cc_argv = &.{},
.inherited = .{},
.inherited = .{
.stack_check = false,
.stack_protector = 0,
.no_builtin = true,
},
.global = options.config,
.parent = options.root_mod,
.builtin_mod = options.root_mod.getBuiltinDependency(),
Expand Down Expand Up @@ -1353,7 +1356,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
cache.hash.add(options.config.link_mode);
cache.hash.add(options.function_sections);
cache.hash.add(options.data_sections);
cache.hash.add(options.no_builtin);
cache.hash.add(link_libc);
cache.hash.add(options.config.link_libcpp);
cache.hash.add(options.config.link_libunwind);
Expand Down Expand Up @@ -1490,7 +1492,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
.framework_dirs = options.framework_dirs,
.llvm_opt_bisect_limit = options.llvm_opt_bisect_limit,
.skip_linker_dependencies = options.skip_linker_dependencies,
.no_builtin = options.no_builtin,
.job_queued_update_builtin_zig = have_zcu,
.function_sections = options.function_sections,
.data_sections = options.data_sections,
Expand Down Expand Up @@ -5261,7 +5262,7 @@ pub fn addCCArgs(
try argv.append("-fdata-sections");
}

if (comp.no_builtin) {
if (mod.no_builtin) {
try argv.append("-fno-builtin");
}

Expand Down Expand Up @@ -6154,7 +6155,6 @@ fn buildOutputFromZig(

assert(output_mode != .Exe);

const unwind_tables = comp.link_eh_frame_hdr;
const strip = comp.compilerRtStrip();
const optimize_mode = comp.compilerRtOptMode();

Expand All @@ -6168,7 +6168,6 @@ fn buildOutputFromZig(
.root_optimize_mode = optimize_mode,
.root_strip = strip,
.link_libc = comp.config.link_libc,
.any_unwind_tables = unwind_tables,
});

const root_mod = try Package.Module.create(arena, .{
Expand All @@ -6185,10 +6184,11 @@ fn buildOutputFromZig(
.stack_protector = 0,
.red_zone = comp.root_mod.red_zone,
.omit_frame_pointer = comp.root_mod.omit_frame_pointer,
.unwind_tables = unwind_tables,
.unwind_tables = comp.root_mod.unwind_tables,
.pic = comp.root_mod.pic,
.optimize_mode = optimize_mode,
.structured_cfg = comp.root_mod.structured_cfg,
.no_builtin = true,
.code_model = comp.root_mod.code_model,
},
.global = config,
Expand Down Expand Up @@ -6237,7 +6237,6 @@ fn buildOutputFromZig(
},
.function_sections = true,
.data_sections = true,
.no_builtin = true,
.emit_h = null,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
Expand All @@ -6262,16 +6261,24 @@ fn buildOutputFromZig(
comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
}

pub const CrtFileOptions = struct {
function_sections: ?bool = null,
data_sections: ?bool = null,
omit_frame_pointer: ?bool = null,
pic: ?bool = null,
no_builtin: ?bool = null,
};

pub fn build_crt_file(
comp: *Compilation,
root_name: []const u8,
output_mode: std.builtin.OutputMode,
pic: ?bool,
misc_task_tag: MiscTask,
prog_node: std.Progress.Node,
/// These elements have to get mutated to add the owner module after it is
/// created within this function.
c_source_files: []CSourceFile,
options: CrtFileOptions,
) !void {
const tracy_trace = trace(@src());
defer tracy_trace.end();
Expand Down Expand Up @@ -6316,13 +6323,16 @@ pub fn build_crt_file(
.sanitize_c = false,
.sanitize_thread = false,
.red_zone = comp.root_mod.red_zone,
.omit_frame_pointer = comp.root_mod.omit_frame_pointer,
// Some libcs (e.g. musl) are opinionated about -fomit-frame-pointer.
.omit_frame_pointer = options.omit_frame_pointer orelse comp.root_mod.omit_frame_pointer,
.valgrind = false,
.unwind_tables = false,
// Some CRT objects (rcrt1.o, Scrt1.o) are opinionated about PIC.
.pic = pic orelse comp.root_mod.pic,
// Some CRT objects (e.g. musl's rcrt1.o and Scrt1.o) are opinionated about PIC.
.pic = options.pic orelse comp.root_mod.pic,
.optimize_mode = comp.compilerRtOptMode(),
.structured_cfg = comp.root_mod.structured_cfg,
// Some libcs (e.g. musl) are opinionated about -fno-builtin.
.no_builtin = options.no_builtin orelse comp.root_mod.no_builtin,
},
.global = config,
.cc_argv = &.{},
Expand Down Expand Up @@ -6350,6 +6360,8 @@ pub fn build_crt_file(
.directory = null, // Put it in the cache directory.
.basename = basename,
},
.function_sections = options.function_sections orelse false,
.data_sections = options.data_sections orelse false,
.emit_h = null,
.c_source_files = c_source_files,
.verbose_cc = comp.verbose_cc,
Expand Down
12 changes: 12 additions & 0 deletions src/Package/Module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ unwind_tables: bool,
cc_argv: []const []const u8,
/// (SPIR-V) whether to generate a structured control flow graph or not
structured_cfg: bool,
no_builtin: bool,

/// If the module is an `@import("builtin")` module, this is the `File` that
/// is preallocated for it. Otherwise this field is null.
Expand Down Expand Up @@ -95,6 +96,7 @@ pub const CreateOptions = struct {
sanitize_thread: ?bool = null,
fuzz: ?bool = null,
structured_cfg: ?bool = null,
no_builtin: ?bool = null,
};
};

Expand Down Expand Up @@ -298,6 +300,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
};
};

const no_builtin = b: {
if (options.inherited.no_builtin) |x| break :b x;
if (options.parent) |p| break :b p.no_builtin;

break :b target.cpu.arch.isBpf();
};

const llvm_cpu_features: ?[*:0]const u8 = b: {
if (resolved_target.llvm_cpu_features) |x| break :b x;
if (!options.global.use_llvm) break :b null;
Expand Down Expand Up @@ -350,6 +359,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.unwind_tables = unwind_tables,
.cc_argv = options.cc_argv,
.structured_cfg = structured_cfg,
.no_builtin = no_builtin,
.builtin_file = null,
};

Expand Down Expand Up @@ -442,6 +452,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.unwind_tables = unwind_tables,
.cc_argv = &.{},
.structured_cfg = structured_cfg,
.no_builtin = no_builtin,
.builtin_file = new_file,
};
new_file.* = .{
Expand Down Expand Up @@ -502,6 +513,7 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P
.unwind_tables = undefined,
.cc_argv = undefined,
.structured_cfg = undefined,
.no_builtin = undefined,
.builtin_file = null,
};
return mod;
Expand Down
12 changes: 8 additions & 4 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3222,8 +3222,6 @@ pub const Object = struct {
owner_mod: *Package.Module,
omit_frame_pointer: bool,
) Allocator.Error!void {
const comp = o.pt.zcu.comp;

if (!owner_mod.red_zone) {
try attributes.addFnAttr(.noredzone, &o.builder);
}
Expand All @@ -3242,8 +3240,7 @@ pub const Object = struct {
if (owner_mod.unwind_tables) {
try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
}
const target = owner_mod.resolved_target.result;
if (comp.skip_linker_dependencies or comp.no_builtin or target.cpu.arch.isBpf()) {
if (owner_mod.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
Expand All @@ -3258,6 +3255,7 @@ pub const Object = struct {
try attributes.addFnAttr(.minsize, &o.builder);
try attributes.addFnAttr(.optsize, &o.builder);
}
const target = owner_mod.resolved_target.result;
if (target.cpu.model.llvm_name) |s| {
try attributes.addFnAttr(.{ .string = .{
.kind = try o.builder.string("target-cpu"),
Expand Down Expand Up @@ -5578,6 +5576,10 @@ pub const FuncGen = struct {
var attributes: Builder.FunctionAttributes.Wip = .{};
defer attributes.deinit(&o.builder);

if (self.ng.ownerModule().no_builtin) {
try attributes.addFnAttr(.nobuiltin, &o.builder);
}

switch (modifier) {
.auto, .never_tail, .always_tail => {},
.never_inline => try attributes.addFnAttr(.@"noinline", &o.builder),
Expand Down Expand Up @@ -12728,6 +12730,8 @@ fn backendSupportsF16(target: std.Target) bool {
.mips64,
.mips64el,
.s390x,
.sparc,
.sparc64,
=> false,
.arm,
.armeb,
Expand Down
9 changes: 4 additions & 5 deletions src/glibc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
.owner = comp.root_mod,
},
};
return comp.build_crt_file("crti", .Obj, null, .@"glibc crti.o", prog_node, &files);
return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &files, .{});
},
.crtn_o => {
var args = std.ArrayList([]const u8).init(arena);
Expand All @@ -242,7 +242,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
.owner = undefined,
},
};
return comp.build_crt_file("crtn", .Obj, null, .@"glibc crtn.o", prog_node, &files);
return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &files, .{});
},
.scrt1_o => {
const start_o: Compilation.CSourceFile = blk: {
Expand Down Expand Up @@ -295,7 +295,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
};
var files = [_]Compilation.CSourceFile{ start_o, abi_note_o, init_o };
const basename = if (comp.config.output_mode == .Exe and !comp.config.pie) "crt1" else "Scrt1";
return comp.build_crt_file(basename, .Obj, null, .@"glibc Scrt1.o", prog_node, &files);
return comp.build_crt_file(basename, .Obj, .@"glibc Scrt1.o", prog_node, &files, .{});
},
.libc_nonshared_a => {
const s = path.sep_str;
Expand Down Expand Up @@ -373,7 +373,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
"-fmerge-all-constants",
"-frounding-math",
"-Wno-unsupported-floating-point-opt", // For targets that don't support -frounding-math.
"-fno-stack-protector",
"-fno-common",
"-fmath-errno",
"-ftls-model=initial-exec",
Expand Down Expand Up @@ -413,7 +412,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
files_index += 1;
}
const files = files_buf[0..files_index];
return comp.build_crt_file("c_nonshared", .Lib, null, .@"glibc libc_nonshared.a", prog_node, files);
return comp.build_crt_file("c_nonshared", .Lib, .@"glibc libc_nonshared.a", prog_node, files, .{});
},
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/libcxx.zig
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
.valgrind = false,
.optimize_mode = optimize_mode,
.structured_cfg = comp.root_mod.structured_cfg,
.pic = comp.root_mod.pic,
.pic = if (target_util.supports_fpic(target)) true else null,
},
.global = config,
.cc_argv = &.{},
Expand Down Expand Up @@ -278,9 +278,6 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
try cflags.append("-faligned-allocation");
}

if (target_util.supports_fpic(target)) {
try cflags.append("-fPIC");
}
try cflags.append("-nostdinc++");
try cflags.append("-std=c++23");
try cflags.append("-Wno-user-defined-literals");
Expand Down
Loading
Loading