Skip to content

Commit ed37a1a

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 e92b129 commit ed37a1a

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
};
@@ -2441,6 +2449,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
24412449
// for a compiler-rt object to put in it.
24422450
comp.queued_jobs.compiler_rt_obj = true;
24432451
comp.link_task_queue.pending_prelink_tasks += 1;
2452+
} else if (comp.compiler_rt_strat == .dyn_lib) {
2453+
// hack for stage2_x86_64 + coff
2454+
log.debug("queuing a job to build compiler_rt_dyn_lib", .{});
2455+
comp.queued_jobs.compiler_rt_dyn_lib = true;
2456+
comp.link_task_queue.pending_prelink_tasks += 1;
24442457
}
24452458

24462459
if (comp.ubsan_rt_strat == .lib) {
@@ -4254,6 +4267,7 @@ fn performAllTheWork(
42544267
"compiler_rt.zig",
42554268
"compiler_rt",
42564269
.Lib,
4270+
.static,
42574271
.compiler_rt,
42584272
main_progress_node,
42594273
RtOptions{
@@ -4270,6 +4284,7 @@ fn performAllTheWork(
42704284
"compiler_rt.zig",
42714285
"compiler_rt",
42724286
.Obj,
4287+
.static,
42734288
.compiler_rt,
42744289
main_progress_node,
42754290
RtOptions{
@@ -4280,12 +4295,31 @@ fn performAllTheWork(
42804295
});
42814296
}
42824297

4298+
// hack for stage2_x86_64 + coff
4299+
if (comp.queued_jobs.compiler_rt_dyn_lib and comp.compiler_rt_dyn_lib == null) {
4300+
comp.link_task_wait_group.spawnManager(buildRt, .{
4301+
comp,
4302+
"compiler_rt.zig",
4303+
"compiler_rt",
4304+
.Lib,
4305+
.dynamic,
4306+
.compiler_rt,
4307+
main_progress_node,
4308+
RtOptions{
4309+
.checks_valgrind = true,
4310+
.allow_lto = false,
4311+
},
4312+
&comp.compiler_rt_dyn_lib,
4313+
});
4314+
}
4315+
42834316
if (comp.queued_jobs.fuzzer_lib and comp.fuzzer_lib == null) {
42844317
comp.link_task_wait_group.spawnManager(buildRt, .{
42854318
comp,
42864319
"fuzzer.zig",
42874320
"fuzzer",
42884321
.Lib,
4322+
.static,
42894323
.libfuzzer,
42904324
main_progress_node,
42914325
RtOptions{},
@@ -4299,6 +4333,7 @@ fn performAllTheWork(
42994333
"ubsan_rt.zig",
43004334
"ubsan_rt",
43014335
.Lib,
4336+
.static,
43024337
.libubsan,
43034338
main_progress_node,
43044339
RtOptions{
@@ -4314,6 +4349,7 @@ fn performAllTheWork(
43144349
"ubsan_rt.zig",
43154350
"ubsan_rt",
43164351
.Obj,
4352+
.static,
43174353
.libubsan,
43184354
main_progress_node,
43194355
RtOptions{
@@ -5390,6 +5426,7 @@ fn buildRt(
53905426
root_source_name: []const u8,
53915427
root_name: []const u8,
53925428
output_mode: std.builtin.OutputMode,
5429+
link_mode: std.builtin.LinkMode,
53935430
misc_task: MiscTask,
53945431
prog_node: std.Progress.Node,
53955432
options: RtOptions,
@@ -5399,6 +5436,7 @@ fn buildRt(
53995436
root_source_name,
54005437
root_name,
54015438
output_mode,
5439+
link_mode,
54025440
misc_task,
54035441
prog_node,
54045442
options,
@@ -5554,6 +5592,7 @@ fn buildLibZigC(comp: *Compilation, prog_node: std.Progress.Node) void {
55545592
"c.zig",
55555593
"zigc",
55565594
.Lib,
5595+
.static,
55575596
.libzigc,
55585597
prog_node,
55595598
.{},
@@ -7231,6 +7270,7 @@ fn buildOutputFromZig(
72317270
src_basename: []const u8,
72327271
root_name: []const u8,
72337272
output_mode: std.builtin.OutputMode,
7273+
link_mode: std.builtin.LinkMode,
72347274
misc_task_tag: MiscTask,
72357275
prog_node: std.Progress.Node,
72367276
options: RtOptions,
@@ -7251,7 +7291,7 @@ fn buildOutputFromZig(
72517291

72527292
const config = try Config.resolve(.{
72537293
.output_mode = output_mode,
7254-
.link_mode = .static,
7294+
.link_mode = link_mode,
72557295
.resolved_target = comp.root_mod.resolved_target,
72567296
.is_test = false,
72577297
.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)