Commit 9bbd71c9ab

Andrew Kelley <andrew@ziglang.org>
2019-05-09 02:49:07
add --bundle-compiler-rt function to link options
and use it when building libuserland.a The self-hosted part of stage1 relies on zig's compiler-rt, and so we include it in libuserland.a. This should potentially be the default, but for now it's behind a linker option. self-hosted translate-c: small progress on translating functions.
1 parent 3bd5c16
src/all_types.hpp
@@ -1861,6 +1861,7 @@ struct CodeGen {
     bool each_lib_rpath;
     bool is_dummy_so;
     bool disable_gen_h;
+    bool bundle_compiler_rt;
 
     Buf *mmacosx_version_min;
     Buf *mios_version_min;
src/codegen.cpp
@@ -9346,6 +9346,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_bool(ch, g->linker_rdynamic);
     cache_bool(ch, g->each_lib_rpath);
     cache_bool(ch, g->disable_gen_h);
+    cache_bool(ch, g->bundle_compiler_rt);
     cache_bool(ch, want_valgrind_support(g));
     cache_bool(ch, g->have_pic);
     cache_bool(ch, g->have_dynamic_link);
src/link.cpp
@@ -772,17 +772,15 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
     }
 }
 
-static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {
+static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {
     // The Mach-O LLD code is not well maintained, and trips an assertion
     // when we link compiler_rt and builtin as libraries rather than objects.
     // Here we workaround this by having compiler_rt and builtin be objects.
     // TODO write our own linker. https://github.com/ziglang/zig/issues/1535
-    OutType child_out_type = OutTypeLib;
     if (parent_gen->zig_target->os == OsMacOSX) {
         child_out_type = OutTypeObj;
     }
 
-
     CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type,
             parent_gen->libc);
     codegen_set_out_name(child_gen, buf_create_from_str(aname));
@@ -804,14 +802,14 @@ static Buf *build_a(CodeGen *parent_gen, const char *aname) {
     Buf *full_path = buf_alloc();
     os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
 
-    return build_a_raw(parent_gen, aname, full_path);
+    return build_a_raw(parent_gen, aname, full_path, OutTypeLib);
 }
 
-static Buf *build_compiler_rt(CodeGen *parent_gen) {
+static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
     Buf *full_path = buf_alloc();
     os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);
 
-    return build_a_raw(parent_gen, "compiler_rt", full_path);
+    return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type);
 }
 
 static const char *get_darwin_arch_string(const ZigTarget *t) {
@@ -1006,7 +1004,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
             lj->args.append(buf_ptr(builtin_a_path));
         }
 
-        Buf *compiler_rt_o_path = build_compiler_rt(g);
+        Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
         lj->args.append(buf_ptr(compiler_rt_o_path));
     }
 
@@ -1117,7 +1115,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
             lj->args.append(buf_ptr(builtin_a_path));
         }
 
-        Buf *compiler_rt_o_path = build_compiler_rt(g);
+        Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
         lj->args.append(buf_ptr(compiler_rt_o_path));
     }
 }
@@ -1361,7 +1359,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
         }
 
         // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
-        Buf *compiler_rt_o_path = build_compiler_rt(g);
+        Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
         lj->args.append(buf_ptr(compiler_rt_o_path));
     }
 
@@ -1604,7 +1602,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
 
     // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
     if (g->out_type == OutTypeExe || is_dyn_lib) {
-        Buf *compiler_rt_o_path = build_compiler_rt(g);
+        Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
         lj->args.append(buf_ptr(compiler_rt_o_path));
     }
 
@@ -1681,14 +1679,18 @@ void codegen_link(CodeGen *g) {
     if (g->out_type == OutTypeLib && !g->is_dynamic) {
         ZigList<const char *> file_names = {};
         for (size_t i = 0; i < g->link_objects.length; i += 1) {
-            file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
+            file_names.append(buf_ptr(g->link_objects.at(i)));
+        }
+        if (g->bundle_compiler_rt) {
+            Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
+            file_names.append(buf_ptr(compiler_rt_o_path));
         }
         ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
         codegen_add_time_event(g, "LLVM Link");
         if (g->verbose_link) {
             fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
-            for (size_t i = 0; i < g->link_objects.length; i += 1) {
-                fprintf(stderr, " %s", (const char *)buf_ptr(g->link_objects.at(i)));
+            for (size_t i = 0; i < file_names.length; i += 1) {
+                fprintf(stderr, " %s", file_names.at(i));
             }
             fprintf(stderr, "\n");
         }
src/main.cpp
@@ -86,6 +86,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
         "  --override-std-dir [arg]     use an alternate Zig standard library\n"
         "\n"
         "Link Options:\n"
+        "  --bundle-compiler-rt [path]  for static libraries, include compiler-rt symbols\n"
         "  --dynamic-linker [path]      set the path to ld.so\n"
         "  --each-lib-rpath             add rpath for each used dynamic library\n"
         "  --library [lib]              link against lib\n"
@@ -442,6 +443,7 @@ int main(int argc, char **argv) {
     TargetSubsystem subsystem = TargetSubsystemAuto;
     bool want_single_threaded = false;
     bool disable_gen_h = false;
+    bool bundle_compiler_rt = false;
     Buf *override_std_dir = nullptr;
     Buf *override_lib_dir = nullptr;
     Buf *main_pkg_path = nullptr;
@@ -652,6 +654,8 @@ int main(int argc, char **argv) {
                 want_single_threaded = true;
             } else if (strcmp(arg, "--disable-gen-h") == 0) {
                 disable_gen_h = true;
+            } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
+                bundle_compiler_rt = true;
             } else if (strcmp(arg, "--test-cmd-bin") == 0) {
                 test_exec_args.append(nullptr);
             } else if (arg[1] == 'L' && arg[2] != 0) {
@@ -1070,6 +1074,7 @@ int main(int argc, char **argv) {
             g->verbose_cc = verbose_cc;
             g->output_dir = output_dir;
             g->disable_gen_h = disable_gen_h;
+            g->bundle_compiler_rt = bundle_compiler_rt;
             codegen_set_errmsg_color(g, color);
             g->system_linker_hack = system_linker_hack;
 
src-self-hosted/translate_c.zig
@@ -13,14 +13,21 @@ pub const Mode = enum {
 
 pub const ClangErrMsg = Stage2ErrorMsg;
 
-pub const Error = error {
-    OutOfMemory,
-};
+pub const Error = error{OutOfMemory};
 
 const Context = struct {
     tree: *ast.Tree,
     source_buffer: *std.Buffer,
     err: Error,
+
+    fn a(c: *Context) *std.mem.Allocator {
+        return &c.tree.arena_allocator.allocator;
+    }
+
+    /// Convert a null-terminated C string to a slice allocated in the arena
+    fn str(c: *Context, s: [*]const u8) ![]u8 {
+        return std.mem.dupe(c.a(), u8, std.mem.toSliceConst(u8, s));
+    }
 };
 
 pub fn translate(
@@ -60,12 +67,13 @@ pub fn translate(
     tree.* = ast.Tree{
         .source = undefined, // need to use Buffer.toOwnedSlice later
         .root_node = root_node,
-        .arena_allocator = tree_arena,
+        .arena_allocator = undefined,
         .tokens = ast.Tree.TokenList.init(arena),
         .errors = ast.Tree.ErrorList.init(arena),
     };
+    tree.arena_allocator = tree_arena;
 
-    var source_buffer = try std.Buffer.initSize(arena, 0);
+    var source_buffer = try std.Buffer.initSize(&tree.arena_allocator.allocator, 0);
 
     var context = Context{
         .tree = tree,
@@ -94,7 +102,7 @@ extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
 fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
     switch (ZigClangDecl_getKind(decl)) {
         .Function => {
-            try appendToken(c, .LineComment, "// TODO translate function decl");
+            return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));
         },
         .Typedef => {
             try appendToken(c, .LineComment, "// TODO translate typedef");
@@ -115,11 +123,25 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
     }
 }
 
-fn appendToken(c: *Context, token_id: Token.Id, src_text: []const u8) !void {
+fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
+    const fn_name = c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
+    try appendToken(c, .LineComment, "// TODO translate function '{}'", fn_name);
+}
+
+fn appendToken(c: *Context, token_id: Token.Id, comptime format: []const u8, args: ...) !void {
+    const S = struct {
+        fn callback(context: *Context, bytes: []const u8) Error!void {
+            return context.source_buffer.append(bytes);
+        }
+    };
     const start_index = c.source_buffer.len();
-    try c.source_buffer.append(src_text);
+    errdefer c.source_buffer.shrink(start_index);
+
+    try std.fmt.format(c, Error, S.callback, format, args);
     const end_index = c.source_buffer.len();
     const new_token = try c.tree.tokens.addOne();
+    errdefer c.tree.tokens.shrink(c.tree.tokens.len - 1);
+
     new_token.* = Token{
         .id = token_id,
         .start = start_index,
std/special/compiler_rt.zig
@@ -1,15 +1,13 @@
 const builtin = @import("builtin");
 const is_test = builtin.is_test;
 
-const stack_probe = @import("compiler_rt/stack_probe.zig");
-
 comptime {
     const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
     const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
 
     switch (builtin.arch) {
         .i386, .x86_64 => @export("__zig_probe_stack", @import("compiler_rt/stack_probe.zig").zig_probe_stack, linkage),
-        else => { }
+        else => {},
     }
 
     @export("__lesf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);
@@ -499,7 +497,6 @@ nakedcc fn __aeabi_memcmp() noreturn {
     unreachable;
 }
 
-
 extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 {
     @setRuntimeSafety(is_test);
 
@@ -1272,17 +1269,17 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
 
 test "test_divsi3" {
     const cases = [][3]i32{
-        []i32{ 0,  1,  0},
-        []i32{ 0, -1,  0},
-        []i32{ 2,  1,  2},
-        []i32{ 2, -1, -2},
-        []i32{-2,  1, -2},
-        []i32{-2, -1,  2},
-
-        []i32{@bitCast(i32, u32(0x80000000)),  1, @bitCast(i32, u32(0x80000000))},
-        []i32{@bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000))},
-        []i32{@bitCast(i32, u32(0x80000000)), -2, 0x40000000},
-        []i32{@bitCast(i32, u32(0x80000000)),  2, @bitCast(i32, u32(0xC0000000))},
+        []i32{ 0, 1, 0 },
+        []i32{ 0, -1, 0 },
+        []i32{ 2, 1, 2 },
+        []i32{ 2, -1, -2 },
+        []i32{ -2, 1, -2 },
+        []i32{ -2, -1, 2 },
+
+        []i32{ @bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000)) },
+        []i32{ @bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000)) },
+        []i32{ @bitCast(i32, u32(0x80000000)), -2, 0x40000000 },
+        []i32{ @bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000)) },
     };
 
     for (cases) |case| {
@@ -1297,19 +1294,19 @@ fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void {
 
 test "test_divmodsi4" {
     const cases = [][4]i32{
-        []i32{ 0,  1,  0,  0},
-        []i32{ 0, -1,  0,  0},
-        []i32{ 2,  1,  2,  0},
-        []i32{ 2, -1, -2,  0},
-        []i32{-2,  1, -2,  0},
-        []i32{-2, -1,  2,  0},
-        []i32{ 7,  5,  1,  2},
-        []i32{-7,  5, -1, -2},
-        []i32{19,  5,  3,  4},
-        []i32{19, -5, -3,  4},
-
-        []i32{@bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0},
-        []i32{@bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1},
+        []i32{ 0, 1, 0, 0 },
+        []i32{ 0, -1, 0, 0 },
+        []i32{ 2, 1, 2, 0 },
+        []i32{ 2, -1, -2, 0 },
+        []i32{ -2, 1, -2, 0 },
+        []i32{ -2, -1, 2, 0 },
+        []i32{ 7, 5, 1, 2 },
+        []i32{ -7, 5, -1, -2 },
+        []i32{ 19, 5, 3, 4 },
+        []i32{ 19, -5, -3, 4 },
+
+        []i32{ @bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0 },
+        []i32{ @bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1 },
     };
 
     for (cases) |case| {
@@ -1325,17 +1322,17 @@ fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) void {
 
 test "test_divdi3" {
     const cases = [][3]i64{
-        []i64{ 0,  1,  0},
-        []i64{ 0, -1,  0},
-        []i64{ 2,  1,  2},
-        []i64{ 2, -1, -2},
-        []i64{-2,  1, -2},
-        []i64{-2, -1,  2},
-
-        []i64{@bitCast(i64, u64(0x8000000000000000)),  1, @bitCast(i64, u64(0x8000000000000000))},
-        []i64{@bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000))},
-        []i64{@bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000},
-        []i64{@bitCast(i64, u64(0x8000000000000000)),  2, @bitCast(i64, u64(0xC000000000000000))},
+        []i64{ 0, 1, 0 },
+        []i64{ 0, -1, 0 },
+        []i64{ 2, 1, 2 },
+        []i64{ 2, -1, -2 },
+        []i64{ -2, 1, -2 },
+        []i64{ -2, -1, 2 },
+
+        []i64{ @bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)) },
+        []i64{ @bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)) },
+        []i64{ @bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000 },
+        []i64{ @bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000)) },
     };
 
     for (cases) |case| {
@@ -1350,19 +1347,19 @@ fn test_one_divdi3(a: i64, b: i64, expected_q: i64) void {
 
 test "test_moddi3" {
     const cases = [][3]i64{
-        []i64{0, 1, 0},
-        []i64{0, -1, 0},
-        []i64{5, 3, 2},
-        []i64{5, -3, 2},
-        []i64{-5, 3, -2},
-        []i64{-5, -3, -2},
-
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)),  1,  0},
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -1,  0},
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)),  2,  0},
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -2,  0},
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)),  3, -2},
-        []i64{@bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2},
+        []i64{ 0, 1, 0 },
+        []i64{ 0, -1, 0 },
+        []i64{ 5, 3, 2 },
+        []i64{ 5, -3, 2 },
+        []i64{ -5, 3, -2 },
+        []i64{ -5, -3, -2 },
+
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0 },
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0 },
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0 },
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0 },
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2 },
+        []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2 },
     };
 
     for (cases) |case| {
@@ -1377,17 +1374,17 @@ fn test_one_moddi3(a: i64, b: i64, expected_r: i64) void {
 
 test "test_modsi3" {
     const cases = [][3]i32{
-        []i32{0, 1, 0},
-        []i32{0, -1, 0},
-        []i32{5, 3, 2},
-        []i32{5, -3, 2},
-        []i32{-5, 3, -2},
-        []i32{-5, -3, -2},
-        []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0},
-        []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0},
-        []i32{@bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0},
-        []i32{@bitCast(i32, @intCast(u32, 0x80000000)), 3, -2},
-        []i32{@bitCast(i32, @intCast(u32, 0x80000000)), -3, -2},
+        []i32{ 0, 1, 0 },
+        []i32{ 0, -1, 0 },
+        []i32{ 5, 3, 2 },
+        []i32{ 5, -3, 2 },
+        []i32{ -5, 3, -2 },
+        []i32{ -5, -3, -2 },
+        []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 },
+        []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 },
+        []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 },
+        []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 },
+        []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 },
     };
 
     for (cases) |case| {
@@ -1402,138 +1399,138 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) void {
 
 test "test_umodsi3" {
     const cases = [][3]u32{
-        []u32{0x00000000, 0x00000001, 0x00000000},
-        []u32{0x00000000, 0x00000002, 0x00000000},
-        []u32{0x00000000, 0x00000003, 0x00000000},
-        []u32{0x00000000, 0x00000010, 0x00000000},
-        []u32{0x00000000, 0x078644FA, 0x00000000},
-        []u32{0x00000000, 0x0747AE14, 0x00000000},
-        []u32{0x00000000, 0x7FFFFFFF, 0x00000000},
-        []u32{0x00000000, 0x80000000, 0x00000000},
-        []u32{0x00000000, 0xFFFFFFFD, 0x00000000},
-        []u32{0x00000000, 0xFFFFFFFE, 0x00000000},
-        []u32{0x00000000, 0xFFFFFFFF, 0x00000000},
-        []u32{0x00000001, 0x00000001, 0x00000000},
-        []u32{0x00000001, 0x00000002, 0x00000001},
-        []u32{0x00000001, 0x00000003, 0x00000001},
-        []u32{0x00000001, 0x00000010, 0x00000001},
-        []u32{0x00000001, 0x078644FA, 0x00000001},
-        []u32{0x00000001, 0x0747AE14, 0x00000001},
-        []u32{0x00000001, 0x7FFFFFFF, 0x00000001},
-        []u32{0x00000001, 0x80000000, 0x00000001},
-        []u32{0x00000001, 0xFFFFFFFD, 0x00000001},
-        []u32{0x00000001, 0xFFFFFFFE, 0x00000001},
-        []u32{0x00000001, 0xFFFFFFFF, 0x00000001},
-        []u32{0x00000002, 0x00000001, 0x00000000},
-        []u32{0x00000002, 0x00000002, 0x00000000},
-        []u32{0x00000002, 0x00000003, 0x00000002},
-        []u32{0x00000002, 0x00000010, 0x00000002},
-        []u32{0x00000002, 0x078644FA, 0x00000002},
-        []u32{0x00000002, 0x0747AE14, 0x00000002},
-        []u32{0x00000002, 0x7FFFFFFF, 0x00000002},
-        []u32{0x00000002, 0x80000000, 0x00000002},
-        []u32{0x00000002, 0xFFFFFFFD, 0x00000002},
-        []u32{0x00000002, 0xFFFFFFFE, 0x00000002},
-        []u32{0x00000002, 0xFFFFFFFF, 0x00000002},
-        []u32{0x00000003, 0x00000001, 0x00000000},
-        []u32{0x00000003, 0x00000002, 0x00000001},
-        []u32{0x00000003, 0x00000003, 0x00000000},
-        []u32{0x00000003, 0x00000010, 0x00000003},
-        []u32{0x00000003, 0x078644FA, 0x00000003},
-        []u32{0x00000003, 0x0747AE14, 0x00000003},
-        []u32{0x00000003, 0x7FFFFFFF, 0x00000003},
-        []u32{0x00000003, 0x80000000, 0x00000003},
-        []u32{0x00000003, 0xFFFFFFFD, 0x00000003},
-        []u32{0x00000003, 0xFFFFFFFE, 0x00000003},
-        []u32{0x00000003, 0xFFFFFFFF, 0x00000003},
-        []u32{0x00000010, 0x00000001, 0x00000000},
-        []u32{0x00000010, 0x00000002, 0x00000000},
-        []u32{0x00000010, 0x00000003, 0x00000001},
-        []u32{0x00000010, 0x00000010, 0x00000000},
-        []u32{0x00000010, 0x078644FA, 0x00000010},
-        []u32{0x00000010, 0x0747AE14, 0x00000010},
-        []u32{0x00000010, 0x7FFFFFFF, 0x00000010},
-        []u32{0x00000010, 0x80000000, 0x00000010},
-        []u32{0x00000010, 0xFFFFFFFD, 0x00000010},
-        []u32{0x00000010, 0xFFFFFFFE, 0x00000010},
-        []u32{0x00000010, 0xFFFFFFFF, 0x00000010},
-        []u32{0x078644FA, 0x00000001, 0x00000000},
-        []u32{0x078644FA, 0x00000002, 0x00000000},
-        []u32{0x078644FA, 0x00000003, 0x00000000},
-        []u32{0x078644FA, 0x00000010, 0x0000000A},
-        []u32{0x078644FA, 0x078644FA, 0x00000000},
-        []u32{0x078644FA, 0x0747AE14, 0x003E96E6},
-        []u32{0x078644FA, 0x7FFFFFFF, 0x078644FA},
-        []u32{0x078644FA, 0x80000000, 0x078644FA},
-        []u32{0x078644FA, 0xFFFFFFFD, 0x078644FA},
-        []u32{0x078644FA, 0xFFFFFFFE, 0x078644FA},
-        []u32{0x078644FA, 0xFFFFFFFF, 0x078644FA},
-        []u32{0x0747AE14, 0x00000001, 0x00000000},
-        []u32{0x0747AE14, 0x00000002, 0x00000000},
-        []u32{0x0747AE14, 0x00000003, 0x00000002},
-        []u32{0x0747AE14, 0x00000010, 0x00000004},
-        []u32{0x0747AE14, 0x078644FA, 0x0747AE14},
-        []u32{0x0747AE14, 0x0747AE14, 0x00000000},
-        []u32{0x0747AE14, 0x7FFFFFFF, 0x0747AE14},
-        []u32{0x0747AE14, 0x80000000, 0x0747AE14},
-        []u32{0x0747AE14, 0xFFFFFFFD, 0x0747AE14},
-        []u32{0x0747AE14, 0xFFFFFFFE, 0x0747AE14},
-        []u32{0x0747AE14, 0xFFFFFFFF, 0x0747AE14},
-        []u32{0x7FFFFFFF, 0x00000001, 0x00000000},
-        []u32{0x7FFFFFFF, 0x00000002, 0x00000001},
-        []u32{0x7FFFFFFF, 0x00000003, 0x00000001},
-        []u32{0x7FFFFFFF, 0x00000010, 0x0000000F},
-        []u32{0x7FFFFFFF, 0x078644FA, 0x00156B65},
-        []u32{0x7FFFFFFF, 0x0747AE14, 0x043D70AB},
-        []u32{0x7FFFFFFF, 0x7FFFFFFF, 0x00000000},
-        []u32{0x7FFFFFFF, 0x80000000, 0x7FFFFFFF},
-        []u32{0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF},
-        []u32{0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF},
-        []u32{0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF},
-        []u32{0x80000000, 0x00000001, 0x00000000},
-        []u32{0x80000000, 0x00000002, 0x00000000},
-        []u32{0x80000000, 0x00000003, 0x00000002},
-        []u32{0x80000000, 0x00000010, 0x00000000},
-        []u32{0x80000000, 0x078644FA, 0x00156B66},
-        []u32{0x80000000, 0x0747AE14, 0x043D70AC},
-        []u32{0x80000000, 0x7FFFFFFF, 0x00000001},
-        []u32{0x80000000, 0x80000000, 0x00000000},
-        []u32{0x80000000, 0xFFFFFFFD, 0x80000000},
-        []u32{0x80000000, 0xFFFFFFFE, 0x80000000},
-        []u32{0x80000000, 0xFFFFFFFF, 0x80000000},
-        []u32{0xFFFFFFFD, 0x00000001, 0x00000000},
-        []u32{0xFFFFFFFD, 0x00000002, 0x00000001},
-        []u32{0xFFFFFFFD, 0x00000003, 0x00000001},
-        []u32{0xFFFFFFFD, 0x00000010, 0x0000000D},
-        []u32{0xFFFFFFFD, 0x078644FA, 0x002AD6C9},
-        []u32{0xFFFFFFFD, 0x0747AE14, 0x01333341},
-        []u32{0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE},
-        []u32{0xFFFFFFFD, 0x80000000, 0x7FFFFFFD},
-        []u32{0xFFFFFFFD, 0xFFFFFFFD, 0x00000000},
-        []u32{0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD},
-        []u32{0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD},
-        []u32{0xFFFFFFFE, 0x00000001, 0x00000000},
-        []u32{0xFFFFFFFE, 0x00000002, 0x00000000},
-        []u32{0xFFFFFFFE, 0x00000003, 0x00000002},
-        []u32{0xFFFFFFFE, 0x00000010, 0x0000000E},
-        []u32{0xFFFFFFFE, 0x078644FA, 0x002AD6CA},
-        []u32{0xFFFFFFFE, 0x0747AE14, 0x01333342},
-        []u32{0xFFFFFFFE, 0x7FFFFFFF, 0x00000000},
-        []u32{0xFFFFFFFE, 0x80000000, 0x7FFFFFFE},
-        []u32{0xFFFFFFFE, 0xFFFFFFFD, 0x00000001},
-        []u32{0xFFFFFFFE, 0xFFFFFFFE, 0x00000000},
-        []u32{0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE},
-        []u32{0xFFFFFFFF, 0x00000001, 0x00000000},
-        []u32{0xFFFFFFFF, 0x00000002, 0x00000001},
-        []u32{0xFFFFFFFF, 0x00000003, 0x00000000},
-        []u32{0xFFFFFFFF, 0x00000010, 0x0000000F},
-        []u32{0xFFFFFFFF, 0x078644FA, 0x002AD6CB},
-        []u32{0xFFFFFFFF, 0x0747AE14, 0x01333343},
-        []u32{0xFFFFFFFF, 0x7FFFFFFF, 0x00000001},
-        []u32{0xFFFFFFFF, 0x80000000, 0x7FFFFFFF},
-        []u32{0xFFFFFFFF, 0xFFFFFFFD, 0x00000002},
-        []u32{0xFFFFFFFF, 0xFFFFFFFE, 0x00000001},
-        []u32{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}
+        []u32{ 0x00000000, 0x00000001, 0x00000000 },
+        []u32{ 0x00000000, 0x00000002, 0x00000000 },
+        []u32{ 0x00000000, 0x00000003, 0x00000000 },
+        []u32{ 0x00000000, 0x00000010, 0x00000000 },
+        []u32{ 0x00000000, 0x078644FA, 0x00000000 },
+        []u32{ 0x00000000, 0x0747AE14, 0x00000000 },
+        []u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 },
+        []u32{ 0x00000000, 0x80000000, 0x00000000 },
+        []u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 },
+        []u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 },
+        []u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 },
+        []u32{ 0x00000001, 0x00000001, 0x00000000 },
+        []u32{ 0x00000001, 0x00000002, 0x00000001 },
+        []u32{ 0x00000001, 0x00000003, 0x00000001 },
+        []u32{ 0x00000001, 0x00000010, 0x00000001 },
+        []u32{ 0x00000001, 0x078644FA, 0x00000001 },
+        []u32{ 0x00000001, 0x0747AE14, 0x00000001 },
+        []u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 },
+        []u32{ 0x00000001, 0x80000000, 0x00000001 },
+        []u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 },
+        []u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 },
+        []u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 },
+        []u32{ 0x00000002, 0x00000001, 0x00000000 },
+        []u32{ 0x00000002, 0x00000002, 0x00000000 },
+        []u32{ 0x00000002, 0x00000003, 0x00000002 },
+        []u32{ 0x00000002, 0x00000010, 0x00000002 },
+        []u32{ 0x00000002, 0x078644FA, 0x00000002 },
+        []u32{ 0x00000002, 0x0747AE14, 0x00000002 },
+        []u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 },
+        []u32{ 0x00000002, 0x80000000, 0x00000002 },
+        []u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 },
+        []u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 },
+        []u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 },
+        []u32{ 0x00000003, 0x00000001, 0x00000000 },
+        []u32{ 0x00000003, 0x00000002, 0x00000001 },
+        []u32{ 0x00000003, 0x00000003, 0x00000000 },
+        []u32{ 0x00000003, 0x00000010, 0x00000003 },
+        []u32{ 0x00000003, 0x078644FA, 0x00000003 },
+        []u32{ 0x00000003, 0x0747AE14, 0x00000003 },
+        []u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 },
+        []u32{ 0x00000003, 0x80000000, 0x00000003 },
+        []u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 },
+        []u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 },
+        []u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 },
+        []u32{ 0x00000010, 0x00000001, 0x00000000 },
+        []u32{ 0x00000010, 0x00000002, 0x00000000 },
+        []u32{ 0x00000010, 0x00000003, 0x00000001 },
+        []u32{ 0x00000010, 0x00000010, 0x00000000 },
+        []u32{ 0x00000010, 0x078644FA, 0x00000010 },
+        []u32{ 0x00000010, 0x0747AE14, 0x00000010 },
+        []u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 },
+        []u32{ 0x00000010, 0x80000000, 0x00000010 },
+        []u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 },
+        []u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 },
+        []u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 },
+        []u32{ 0x078644FA, 0x00000001, 0x00000000 },
+        []u32{ 0x078644FA, 0x00000002, 0x00000000 },
+        []u32{ 0x078644FA, 0x00000003, 0x00000000 },
+        []u32{ 0x078644FA, 0x00000010, 0x0000000A },
+        []u32{ 0x078644FA, 0x078644FA, 0x00000000 },
+        []u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 },
+        []u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA },
+        []u32{ 0x078644FA, 0x80000000, 0x078644FA },
+        []u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA },
+        []u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA },
+        []u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA },
+        []u32{ 0x0747AE14, 0x00000001, 0x00000000 },
+        []u32{ 0x0747AE14, 0x00000002, 0x00000000 },
+        []u32{ 0x0747AE14, 0x00000003, 0x00000002 },
+        []u32{ 0x0747AE14, 0x00000010, 0x00000004 },
+        []u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 },
+        []u32{ 0x0747AE14, 0x0747AE14, 0x00000000 },
+        []u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 },
+        []u32{ 0x0747AE14, 0x80000000, 0x0747AE14 },
+        []u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 },
+        []u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 },
+        []u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 },
+        []u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 },
+        []u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 },
+        []u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 },
+        []u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F },
+        []u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 },
+        []u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB },
+        []u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 },
+        []u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF },
+        []u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF },
+        []u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF },
+        []u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF },
+        []u32{ 0x80000000, 0x00000001, 0x00000000 },
+        []u32{ 0x80000000, 0x00000002, 0x00000000 },
+        []u32{ 0x80000000, 0x00000003, 0x00000002 },
+        []u32{ 0x80000000, 0x00000010, 0x00000000 },
+        []u32{ 0x80000000, 0x078644FA, 0x00156B66 },
+        []u32{ 0x80000000, 0x0747AE14, 0x043D70AC },
+        []u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 },
+        []u32{ 0x80000000, 0x80000000, 0x00000000 },
+        []u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 },
+        []u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 },
+        []u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 },
+        []u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 },
+        []u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 },
+        []u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 },
+        []u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D },
+        []u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 },
+        []u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 },
+        []u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE },
+        []u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD },
+        []u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 },
+        []u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD },
+        []u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD },
+        []u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 },
+        []u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 },
+        []u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 },
+        []u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E },
+        []u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA },
+        []u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 },
+        []u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 },
+        []u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE },
+        []u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 },
+        []u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 },
+        []u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE },
+        []u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 },
+        []u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 },
+        []u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 },
+        []u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F },
+        []u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB },
+        []u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 },
+        []u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 },
+        []u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF },
+        []u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 },
+        []u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 },
+        []u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 },
     };
 
     for (cases) |case| {
std/build.zig
@@ -941,6 +941,7 @@ pub const LibExeObjStep = struct {
     verbose_link: bool,
     verbose_cc: bool,
     disable_gen_h: bool,
+    bundle_compiler_rt: bool,
     c_std: Builder.CStd,
     override_std_dir: ?[]const u8,
     override_lib_dir: ?[]const u8,
@@ -1050,6 +1051,7 @@ pub const LibExeObjStep = struct {
             .name_prefix = "",
             .filter = null,
             .disable_gen_h = false,
+            .bundle_compiler_rt = false,
             .output_dir = null,
             .need_system_paths = false,
             .single_threaded = false,
@@ -1452,6 +1454,9 @@ pub const LibExeObjStep = struct {
         if (self.disable_gen_h) {
             try zig_args.append("--disable-gen-h");
         }
+        if (self.bundle_compiler_rt) {
+            try zig_args.append("--bundle-compiler-rt");
+        }
 
         switch (self.target) {
             Target.Native => {},
build.zig
@@ -389,6 +389,7 @@ fn addLibUserlandStep(b: *Builder) void {
     else
         b.addStaticLibrary("userland", "src-self-hosted/stage1.zig");
     artifact.disable_gen_h = true;
+    artifact.bundle_compiler_rt = true;
     artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
     artifact.linkSystemLibrary("c");
     const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");