Commit d107ef8697

Jakub Konka <kubkon@jakubkonka.com>
2022-02-02 20:59:17
Merge pull request #10769 from ziglang/link-lib-fixes
stage2: handle name-qualified imports in sema, add a zerofill sections workaround to incremental macho
1 parent cee0f08
Changed files (4)
src/link/MachO.zig
@@ -143,9 +143,6 @@ objc_data_section_index: ?u16 = null,
 rustc_section_index: ?u16 = null,
 rustc_section_size: u64 = 0,
 
-bss_file_offset: u32 = 0,
-tlv_bss_file_offset: u32 = 0,
-
 locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
 globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
 undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
@@ -384,7 +381,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
     // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator
     // ABI such as aarch64-ios-simulator, etc.
     const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);
-    const needs_prealloc = !(build_options.is_stage1 and options.use_stage1);
+    const use_stage1 = build_options.is_stage1 and options.use_stage1;
+    const needs_prealloc = !(use_stage1 or options.cache_mode == .whole);
 
     self.* = .{
         .base = .{
@@ -2129,7 +2127,8 @@ fn writeAtoms(self: *MachO) !void {
         const sect = seg.sections.items[match.sect];
         var atom: *Atom = entry.value_ptr.*;
 
-        if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
+        // TODO handle zerofill in stage2
+        // if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
 
         log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
 
@@ -4566,9 +4565,12 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
     var start: u64 = offset;
     for (seg.sections.items) |*sect, sect_id| {
         const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
+        const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
         const alignment = try math.powi(u32, 2, sect.@"align");
         const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
-        sect.offset = if (is_zerofill) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
+
+        // TODO handle zerofill sections in stage2
+        sect.offset = if (is_zerofill and use_stage1) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
         sect.addr = seg.inner.vmaddr + start_aligned;
 
         // Recalculate section size given the allocated start address
@@ -4596,7 +4598,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
 
         start = start_aligned + sect.size;
 
-        if (!is_zerofill) {
+        if (!(is_zerofill and use_stage1)) {
             seg.inner.filesize = start;
         }
         seg.inner.vmsize = start;
@@ -4644,7 +4646,11 @@ fn initSection(
 
         sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
 
-        if (opts.flags != macho.S_ZEROFILL and opts.flags != macho.S_THREAD_LOCAL_ZEROFILL) {
+        const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL;
+        const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
+
+        // TODO handle zerofill in stage2
+        if (!(is_zerofill and use_stage1)) {
             sect.offset = @intCast(u32, off);
         }
     }
src/Sema.zig
@@ -5145,11 +5145,6 @@ fn funcCommon(
     if (opt_lib_name) |lib_name| blk: {
         const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset };
         log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
-        mod.comp.stage1AddLinkLib(lib_name) catch |err| {
-            return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
-                lib_name, @errorName(err),
-            });
-        };
         const target = mod.getTarget();
         if (target_util.is_libc_lib_name(target, lib_name)) {
             if (!mod.comp.bin_file.options.link_libc) {
@@ -5160,6 +5155,7 @@ fn funcCommon(
                     .{},
                 );
             }
+            mod.comp.bin_file.options.link_libc = true;
             break :blk;
         }
         if (target_util.is_libcpp_lib_name(target, lib_name)) {
@@ -5171,6 +5167,11 @@ fn funcCommon(
                     .{},
                 );
             }
+            mod.comp.bin_file.options.link_libcpp = true;
+            break :blk;
+        }
+        if (mem.eql(u8, lib_name, "unwind")) {
+            mod.comp.bin_file.options.link_libunwind = true;
             break :blk;
         }
         if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
@@ -5181,6 +5182,11 @@ fn funcCommon(
                 .{ lib_name, lib_name },
             );
         }
+        mod.comp.stage1AddLinkLib(lib_name) catch |err| {
+            return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
+                lib_name, @errorName(err),
+            });
+        };
     }
 
     if (is_extern) {
test/stage2/aarch64.zig
@@ -121,8 +121,8 @@ pub fn addCases(ctx: *TestContext) !void {
 
         // Regular old hello world
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
-            \\extern fn exit(usize) noreturn;
+            \\extern "c" fn write(usize, usize, usize) usize;
+            \\extern "c" fn exit(usize) noreturn;
             \\
             \\pub export fn main() noreturn {
             \\    print();
@@ -141,7 +141,7 @@ pub fn addCases(ctx: *TestContext) !void {
 
         // Now using start.zig without an explicit extern exit fn
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -158,7 +158,7 @@ pub fn addCases(ctx: *TestContext) !void {
 
         // Print it 4 times and force growth and realloc.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -182,7 +182,7 @@ pub fn addCases(ctx: *TestContext) !void {
 
         // Print it once, and change the message.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -199,7 +199,7 @@ pub fn addCases(ctx: *TestContext) !void {
 
         // Now we print it twice.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
test/stage2/x86_64.zig
@@ -328,7 +328,7 @@ pub fn addCases(ctx: *TestContext) !void {
                 .macos => {
                     // While loops
                     case.addCompareOutput(
-                        \\extern fn write(usize, usize, usize) usize;
+                        \\extern "c" fn write(usize, usize, usize) usize;
                         \\
                         \\pub fn main() void {
                         \\    var i: u32 = 0;
@@ -349,7 +349,7 @@ pub fn addCases(ctx: *TestContext) !void {
 
                     // inline while requires the condition to be comptime known.
                     case.addError(
-                        \\extern fn write(usize, usize, usize) usize;
+                        \\extern "c" fn write(usize, usize, usize) usize;
                         \\
                         \\pub fn main() void {
                         \\    var i: u32 = 0;
@@ -652,7 +652,7 @@ pub fn addCases(ctx: *TestContext) !void {
                 .macos => {
                     // Basic for loop
                     case.addCompareOutput(
-                        \\extern fn write(usize, usize, usize) usize;
+                        \\extern "c" fn write(usize, usize, usize) usize;
                         \\
                         \\pub fn main() void {
                         \\    for ("hello") |_| print();
@@ -736,7 +736,7 @@ pub fn addCases(ctx: *TestContext) !void {
                 }),
                 .macos => try case.files.append(.{
                     .src = 
-                    \\extern fn write(usize, usize, usize) usize;
+                    \\extern "c" fn write(usize, usize, usize) usize;
                     \\
                     \\pub fn print() void {
                     \\    _ = write(1, @ptrToInt("Hello, World!\n"), 14);
@@ -814,7 +814,7 @@ pub fn addCases(ctx: *TestContext) !void {
                 }),
                 .macos => try case.files.append(.{
                     .src = 
-                    \\extern fn write(usize, usize, usize) usize;
+                    \\extern "c" fn write(usize, usize, usize) usize;
                     \\fn print() void {
                     \\    _ = write(1, @ptrToInt("Hello, World!\n"), 14);
                     \\}
@@ -1478,7 +1478,7 @@ pub fn addCases(ctx: *TestContext) !void {
                     \\}
                 , "HelloHello, World!\n"),
                 .macos => case.addCompareOutput(
-                    \\extern fn write(usize, usize, usize) usize;
+                    \\extern "c" fn write(usize, usize, usize) usize;
                     \\
                     \\pub fn main() void {
                     \\    comptime var len: u32 = 5;
@@ -1550,7 +1550,7 @@ pub fn addCases(ctx: *TestContext) !void {
                     \\}
                 , "HeHelHellHello"),
                 .macos => case.addCompareOutput(
-                    \\extern fn write(usize, usize, usize) usize;
+                    \\extern "c" fn write(usize, usize, usize) usize;
                     \\
                     \\pub fn main() void {
                     \\    comptime var i: u64 = 2;
@@ -1877,8 +1877,8 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
 
         // Regular old hello world
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
-            \\extern fn exit(usize) noreturn;
+            \\extern "c" fn write(usize, usize, usize) usize;
+            \\extern "c" fn exit(usize) noreturn;
             \\
             \\pub export fn main() noreturn {
             \\    print();
@@ -1897,7 +1897,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
 
         // Now using start.zig without an explicit extern exit fn
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -1914,7 +1914,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
 
         // Print it 4 times and force growth and realloc.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -1938,7 +1938,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
 
         // Print it once, and change the message.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();
@@ -1955,7 +1955,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
 
         // Now we print it twice.
         case.addCompareOutput(
-            \\extern fn write(usize, usize, usize) usize;
+            \\extern "c" fn write(usize, usize, usize) usize;
             \\
             \\pub fn main() void {
             \\    print();