Skip to content

Commit 22c8161

Browse files
committed
coff: add hack to build a compiler-rt dynamic library
This is not meant to be a long-term solution, but it's the easiest thing to get working quickly at the moment. The main intention of this hack is to allow more tests to be enabled. By the time the coff linker is far enough along to be enabled by default, this will no longer be required.
1 parent 8c1512d commit 22c8161

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

lib/compiler_rt/common.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ else
1616
/// Determines the symbol's visibility to other objects.
1717
/// For WebAssembly this allows the symbol to be resolved to other modules, but will not
1818
/// export it to the host runtime.
19-
pub const visibility: std.builtin.SymbolVisibility = if (linkage != .internal)
20-
.hidden
19+
pub const visibility: std.builtin.SymbolVisibility = if (linkage == .internal or builtin.link_mode == .dynamic)
20+
.default
2121
else
22-
.default;
22+
.hidden;
2323

2424
pub const PreferredLoadStoreElement = element: {
2525
if (std.simd.suggestVectorLength(u8)) |vec_size| {

src/Compilation.zig

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ compiler_rt_lib: ?CrtFile = null,
224224
/// Populated when we build the compiler_rt_obj object. A Job to build this is indicated
225225
/// by setting `queued_jobs.compiler_rt_obj` and resolved before calling linker.flush().
226226
compiler_rt_obj: ?CrtFile = null,
227+
/// hack for stage2_x86_64 + coff
228+
compiler_rt_dyn_lib: ?CrtFile = null,
227229
/// Populated when we build the libfuzzer static library. A Job to build this
228230
/// is indicated by setting `queued_jobs.fuzzer_lib` and resolved before
229231
/// calling linker.flush().
@@ -291,6 +293,8 @@ emit_llvm_bc: ?[]const u8,
291293
emit_docs: ?[]const u8,
292294

293295
const QueuedJobs = struct {
296+
/// hack for stage2_x86_64 + coff
297+
compiler_rt_dyn_lib: bool = false,
294298
compiler_rt_lib: bool = false,
295299
compiler_rt_obj: bool = false,
296300
ubsan_rt_lib: bool = false,
@@ -1753,7 +1757,7 @@ fn addModuleTableToCacheHash(
17531757
}
17541758
}
17551759

1756-
const RtStrat = enum { none, lib, obj, zcu };
1760+
const RtStrat = enum { none, lib, obj, zcu, dyn_lib };
17571761

17581762
pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compilation {
17591763
const output_mode = options.config.output_mode;
@@ -1816,7 +1820,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
18161820
if (options.skip_linker_dependencies) break :s .none;
18171821
const want = options.want_compiler_rt orelse is_exe_or_dyn_lib;
18181822
if (!want) break :s .none;
1819-
if (have_zcu and output_mode == .Obj) break :s .zcu;
1823+
if (have_zcu) {
1824+
if (output_mode == .Obj) break :s .zcu;
1825+
if (target.ofmt == .coff and target_util.zigBackend(target, use_llvm) == .stage2_x86_64)
1826+
break :s if (is_exe_or_dyn_lib) .dyn_lib else .zcu;
1827+
}
18201828
if (is_exe_or_dyn_lib) break :s .lib;
18211829
break :s .obj;
18221830
};
@@ -2436,6 +2444,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24362444
// for a compiler-rt object to put in it.
24372445
comp.queued_jobs.compiler_rt_obj = true;
24382446
comp.link_task_queue.pending_prelink_tasks += 1;
2447+
} else if (comp.compiler_rt_strat == .dyn_lib) {
2448+
// hack for stage2_x86_64 + coff
2449+
log.debug("queuing a job to build compiler_rt_dyn_lib", .{});
2450+
comp.queued_jobs.compiler_rt_dyn_lib = true;
2451+
comp.link_task_queue.pending_prelink_tasks += 1;
24392452
}
24402453

24412454
if (comp.ubsan_rt_strat == .lib) {
@@ -4233,6 +4246,7 @@ fn performAllTheWork(
42334246
"compiler_rt.zig",
42344247
"compiler_rt",
42354248
.Lib,
4249+
.static,
42364250
.compiler_rt,
42374251
main_progress_node,
42384252
RtOptions{
@@ -4249,6 +4263,7 @@ fn performAllTheWork(
42494263
"compiler_rt.zig",
42504264
"compiler_rt",
42514265
.Obj,
4266+
.static,
42524267
.compiler_rt,
42534268
main_progress_node,
42544269
RtOptions{
@@ -4259,12 +4274,31 @@ fn performAllTheWork(
42594274
});
42604275
}
42614276

4277+
// hack for stage2_x86_64 + coff
4278+
if (comp.queued_jobs.compiler_rt_dyn_lib and comp.compiler_rt_dyn_lib == null) {
4279+
comp.link_task_wait_group.spawnManager(buildRt, .{
4280+
comp,
4281+
"compiler_rt.zig",
4282+
"compiler_rt",
4283+
.Lib,
4284+
.dynamic,
4285+
.compiler_rt,
4286+
main_progress_node,
4287+
RtOptions{
4288+
.checks_valgrind = true,
4289+
.allow_lto = false,
4290+
},
4291+
&comp.compiler_rt_dyn_lib,
4292+
});
4293+
}
4294+
42624295
if (comp.queued_jobs.fuzzer_lib and comp.fuzzer_lib == null) {
42634296
comp.link_task_wait_group.spawnManager(buildRt, .{
42644297
comp,
42654298
"fuzzer.zig",
42664299
"fuzzer",
42674300
.Lib,
4301+
.static,
42684302
.libfuzzer,
42694303
main_progress_node,
42704304
RtOptions{},
@@ -4278,6 +4312,7 @@ fn performAllTheWork(
42784312
"ubsan_rt.zig",
42794313
"ubsan_rt",
42804314
.Lib,
4315+
.static,
42814316
.libubsan,
42824317
main_progress_node,
42834318
RtOptions{
@@ -4293,6 +4328,7 @@ fn performAllTheWork(
42934328
"ubsan_rt.zig",
42944329
"ubsan_rt",
42954330
.Obj,
4331+
.static,
42964332
.libubsan,
42974333
main_progress_node,
42984334
RtOptions{
@@ -5369,6 +5405,7 @@ fn buildRt(
53695405
root_source_name: []const u8,
53705406
root_name: []const u8,
53715407
output_mode: std.builtin.OutputMode,
5408+
link_mode: std.builtin.LinkMode,
53725409
misc_task: MiscTask,
53735410
prog_node: std.Progress.Node,
53745411
options: RtOptions,
@@ -5378,6 +5415,7 @@ fn buildRt(
53785415
root_source_name,
53795416
root_name,
53805417
output_mode,
5418+
link_mode,
53815419
misc_task,
53825420
prog_node,
53835421
options,
@@ -5533,6 +5571,7 @@ fn buildLibZigC(comp: *Compilation, prog_node: std.Progress.Node) void {
55335571
"c.zig",
55345572
"zigc",
55355573
.Lib,
5574+
.static,
55365575
.libzigc,
55375576
prog_node,
55385577
.{},
@@ -7210,6 +7249,7 @@ fn buildOutputFromZig(
72107249
src_basename: []const u8,
72117250
root_name: []const u8,
72127251
output_mode: std.builtin.OutputMode,
7252+
link_mode: std.builtin.LinkMode,
72137253
misc_task_tag: MiscTask,
72147254
prog_node: std.Progress.Node,
72157255
options: RtOptions,
@@ -7230,7 +7270,7 @@ fn buildOutputFromZig(
72307270

72317271
const config = try Config.resolve(.{
72327272
.output_mode = output_mode,
7233-
.link_mode = .static,
7273+
.link_mode = link_mode,
72347274
.resolved_target = comp.root_mod.resolved_target,
72357275
.is_test = false,
72367276
.have_zcu = true,

src/link/Coff.zig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,21 @@ fn flushInner(coff: *Coff, arena: Allocator, tid: Zcu.PerThread.Id) !void {
17151715
}
17161716

17171717
assert(!coff.imports_count_dirty);
1718+
1719+
// hack for stage2_x86_64 + coff
1720+
if (comp.compiler_rt_dyn_lib) |crt_file| {
1721+
const compiler_rt_sub_path = try std.fs.path.join(gpa, &.{
1722+
std.fs.path.dirname(coff.base.emit.sub_path) orelse "",
1723+
std.fs.path.basename(crt_file.full_object_path.sub_path),
1724+
});
1725+
defer gpa.free(compiler_rt_sub_path);
1726+
try crt_file.full_object_path.root_dir.handle.copyFile(
1727+
crt_file.full_object_path.sub_path,
1728+
coff.base.emit.root_dir.handle,
1729+
compiler_rt_sub_path,
1730+
.{},
1731+
);
1732+
}
17181733
}
17191734

17201735
pub fn getNavVAddr(

0 commit comments

Comments
 (0)