authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-02 20:59:17+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-02 20:59:17+01:00
log7694361832090198ed6d4e4fa930990a72813642
treea824ef65e7fc6110e6142acb4e43d3a277888686
parent3eb8d01f522cf23d484411794ac10777b3de1cfa
parent8f3be0e04f47b250eb84029ff524130b8411daf8
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10769 from ziglang/link-lib-fixes

stage2: handle name-qualified imports in sema, add a zerofill sections workaround to incremental macho

4 files changed, 44 insertions(+), 33 deletions(-)

src/Sema.zig+11-5
...@@ -5567,11 +5567,6 @@ fn funcCommon(...@@ -5567,11 +5567,6 @@ fn funcCommon(
5567 if (opt_lib_name) |lib_name| blk: {5567 if (opt_lib_name) |lib_name| blk: {
5568 const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset };5568 const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset };
5569 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});5569 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
5570 mod.comp.stage1AddLinkLib(lib_name) catch |err| {
5571 return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
5572 lib_name, @errorName(err),
5573 });
5574 };
5575 if (target_util.is_libc_lib_name(target, lib_name)) {5570 if (target_util.is_libc_lib_name(target, lib_name)) {
5576 if (!mod.comp.bin_file.options.link_libc) {5571 if (!mod.comp.bin_file.options.link_libc) {
5577 return sema.fail(5572 return sema.fail(
...@@ -5581,6 +5576,7 @@ fn funcCommon(...@@ -5581,6 +5576,7 @@ fn funcCommon(
5581 .{},5576 .{},
5582 );5577 );
5583 }5578 }
5579 mod.comp.bin_file.options.link_libc = true;
5584 break :blk;5580 break :blk;
5585 }5581 }
5586 if (target_util.is_libcpp_lib_name(target, lib_name)) {5582 if (target_util.is_libcpp_lib_name(target, lib_name)) {
...@@ -5592,6 +5588,11 @@ fn funcCommon(...@@ -5592,6 +5588,11 @@ fn funcCommon(
5592 .{},5588 .{},
5593 );5589 );
5594 }5590 }
5591 mod.comp.bin_file.options.link_libcpp = true;
5592 break :blk;
5593 }
5594 if (mem.eql(u8, lib_name, "unwind")) {
5595 mod.comp.bin_file.options.link_libunwind = true;
5595 break :blk;5596 break :blk;
5596 }5597 }
5597 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {5598 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
...@@ -5602,6 +5603,11 @@ fn funcCommon(...@@ -5602,6 +5603,11 @@ fn funcCommon(
5602 .{ lib_name, lib_name },5603 .{ lib_name, lib_name },
5603 );5604 );
5604 }5605 }
5606 mod.comp.stage1AddLinkLib(lib_name) catch |err| {
5607 return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
5608 lib_name, @errorName(err),
5609 });
5610 };
5605 }5611 }
56065612
5607 if (is_extern) {5613 if (is_extern) {
src/link/MachO.zig+14-9
...@@ -144,9 +144,6 @@ objc_data_section_index: ?u16 = null,...@@ -144,9 +144,6 @@ objc_data_section_index: ?u16 = null,
144rustc_section_index: ?u16 = null,144rustc_section_index: ?u16 = null,
145rustc_section_size: u64 = 0,145rustc_section_size: u64 = 0,
146146
147bss_file_offset: u32 = 0,
148tlv_bss_file_offset: u32 = 0,
149
150locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},147locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
151globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},148globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
152undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},149undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
...@@ -383,7 +380,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {...@@ -383,7 +380,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
383 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator380 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator
384 // ABI such as aarch64-ios-simulator, etc.381 // ABI such as aarch64-ios-simulator, etc.
385 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);382 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);
386 const needs_prealloc = !(build_options.is_stage1 and options.use_stage1);383 const use_stage1 = build_options.is_stage1 and options.use_stage1;
384 const needs_prealloc = !(use_stage1 or options.cache_mode == .whole);
387385
388 const self = try gpa.create(MachO);386 const self = try gpa.create(MachO);
389 errdefer gpa.destroy(self);387 errdefer gpa.destroy(self);
...@@ -401,7 +399,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {...@@ -401,7 +399,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
401 };399 };
402400
403 const use_llvm = build_options.have_llvm and options.use_llvm;401 const use_llvm = build_options.have_llvm and options.use_llvm;
404 const use_stage1 = build_options.is_stage1 and options.use_stage1;
405 if (use_llvm and !use_stage1) {402 if (use_llvm and !use_stage1) {
406 self.llvm_object = try LlvmObject.create(gpa, options);403 self.llvm_object = try LlvmObject.create(gpa, options);
407 }404 }
...@@ -2158,7 +2155,8 @@ fn writeAtoms(self: *MachO) !void {...@@ -2158,7 +2155,8 @@ fn writeAtoms(self: *MachO) !void {
2158 const sect = seg.sections.items[match.sect];2155 const sect = seg.sections.items[match.sect];
2159 var atom: *Atom = entry.value_ptr.*;2156 var atom: *Atom = entry.value_ptr.*;
21602157
2161 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;2158 // TODO handle zerofill in stage2
2159 // if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
21622160
2163 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });2161 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
21642162
...@@ -4756,9 +4754,12 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4756,9 +4754,12 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4756 var start: u64 = offset;4754 var start: u64 = offset;
4757 for (seg.sections.items) |*sect, sect_id| {4755 for (seg.sections.items) |*sect, sect_id| {
4758 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;4756 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4757 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
4759 const alignment = try math.powi(u32, 2, sect.@"align");4758 const alignment = try math.powi(u32, 2, sect.@"align");
4760 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);4759 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
4761 sect.offset = if (is_zerofill) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);4760
4761 // TODO handle zerofill sections in stage2
4762 sect.offset = if (is_zerofill and use_stage1) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
4762 sect.addr = seg.inner.vmaddr + start_aligned;4763 sect.addr = seg.inner.vmaddr + start_aligned;
47634764
4764 // Recalculate section size given the allocated start address4765 // Recalculate section size given the allocated start address
...@@ -4786,7 +4787,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4786,7 +4787,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
47864787
4787 start = start_aligned + sect.size;4788 start = start_aligned + sect.size;
47884789
4789 if (!is_zerofill) {4790 if (!(is_zerofill and use_stage1)) {
4790 seg.inner.filesize = start;4791 seg.inner.filesize = start;
4791 }4792 }
4792 seg.inner.vmsize = start;4793 seg.inner.vmsize = start;
...@@ -4834,7 +4835,11 @@ fn initSection(...@@ -4834,7 +4835,11 @@ fn initSection(
48344835
4835 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;4836 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
48364837
4837 if (opts.flags != macho.S_ZEROFILL and opts.flags != macho.S_THREAD_LOCAL_ZEROFILL) {4838 const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4839 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
4840
4841 // TODO handle zerofill in stage2
4842 if (!(is_zerofill and use_stage1)) {
4838 sect.offset = @intCast(u32, off);4843 sect.offset = @intCast(u32, off);
4839 }4844 }
4840 }4845 }
test/stage2/aarch64.zig+6-6
...@@ -121,8 +121,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -121,8 +121,8 @@ pub fn addCases(ctx: *TestContext) !void {
121121
122 // Regular old hello world122 // Regular old hello world
123 case.addCompareOutput(123 case.addCompareOutput(
124 \\extern fn write(usize, usize, usize) usize;124 \\extern "c" fn write(usize, usize, usize) usize;
125 \\extern fn exit(usize) noreturn;125 \\extern "c" fn exit(usize) noreturn;
126 \\126 \\
127 \\pub export fn main() noreturn {127 \\pub export fn main() noreturn {
128 \\ print();128 \\ print();
...@@ -141,7 +141,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -141,7 +141,7 @@ pub fn addCases(ctx: *TestContext) !void {
141141
142 // Now using start.zig without an explicit extern exit fn142 // Now using start.zig without an explicit extern exit fn
143 case.addCompareOutput(143 case.addCompareOutput(
144 \\extern fn write(usize, usize, usize) usize;144 \\extern "c" fn write(usize, usize, usize) usize;
145 \\145 \\
146 \\pub fn main() void {146 \\pub fn main() void {
147 \\ print();147 \\ print();
...@@ -158,7 +158,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -158,7 +158,7 @@ pub fn addCases(ctx: *TestContext) !void {
158158
159 // Print it 4 times and force growth and realloc.159 // Print it 4 times and force growth and realloc.
160 case.addCompareOutput(160 case.addCompareOutput(
161 \\extern fn write(usize, usize, usize) usize;161 \\extern "c" fn write(usize, usize, usize) usize;
162 \\162 \\
163 \\pub fn main() void {163 \\pub fn main() void {
164 \\ print();164 \\ print();
...@@ -182,7 +182,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -182,7 +182,7 @@ pub fn addCases(ctx: *TestContext) !void {
182182
183 // Print it once, and change the message.183 // Print it once, and change the message.
184 case.addCompareOutput(184 case.addCompareOutput(
185 \\extern fn write(usize, usize, usize) usize;185 \\extern "c" fn write(usize, usize, usize) usize;
186 \\186 \\
187 \\pub fn main() void {187 \\pub fn main() void {
188 \\ print();188 \\ print();
...@@ -199,7 +199,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -199,7 +199,7 @@ pub fn addCases(ctx: *TestContext) !void {
199199
200 // Now we print it twice.200 // Now we print it twice.
201 case.addCompareOutput(201 case.addCompareOutput(
202 \\extern fn write(usize, usize, usize) usize;202 \\extern "c" fn write(usize, usize, usize) usize;
203 \\203 \\
204 \\pub fn main() void {204 \\pub fn main() void {
205 \\ print();205 \\ print();
test/stage2/x86_64.zig+13-13
...@@ -328,7 +328,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -328,7 +328,7 @@ pub fn addCases(ctx: *TestContext) !void {
328 .macos => {328 .macos => {
329 // While loops329 // While loops
330 case.addCompareOutput(330 case.addCompareOutput(
331 \\extern fn write(usize, usize, usize) usize;331 \\extern "c" fn write(usize, usize, usize) usize;
332 \\332 \\
333 \\pub fn main() void {333 \\pub fn main() void {
334 \\ var i: u32 = 0;334 \\ var i: u32 = 0;
...@@ -349,7 +349,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -349,7 +349,7 @@ pub fn addCases(ctx: *TestContext) !void {
349349
350 // inline while requires the condition to be comptime known.350 // inline while requires the condition to be comptime known.
351 case.addError(351 case.addError(
352 \\extern fn write(usize, usize, usize) usize;352 \\extern "c" fn write(usize, usize, usize) usize;
353 \\353 \\
354 \\pub fn main() void {354 \\pub fn main() void {
355 \\ var i: u32 = 0;355 \\ var i: u32 = 0;
...@@ -652,7 +652,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -652,7 +652,7 @@ pub fn addCases(ctx: *TestContext) !void {
652 .macos => {652 .macos => {
653 // Basic for loop653 // Basic for loop
654 case.addCompareOutput(654 case.addCompareOutput(
655 \\extern fn write(usize, usize, usize) usize;655 \\extern "c" fn write(usize, usize, usize) usize;
656 \\656 \\
657 \\pub fn main() void {657 \\pub fn main() void {
658 \\ for ("hello") |_| print();658 \\ for ("hello") |_| print();
...@@ -736,7 +736,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -736,7 +736,7 @@ pub fn addCases(ctx: *TestContext) !void {
736 }),736 }),
737 .macos => try case.files.append(.{737 .macos => try case.files.append(.{
738 .src = 738 .src =
739 \\extern fn write(usize, usize, usize) usize;739 \\extern "c" fn write(usize, usize, usize) usize;
740 \\740 \\
741 \\pub fn print() void {741 \\pub fn print() void {
742 \\ _ = write(1, @ptrToInt("Hello, World!\n"), 14);742 \\ _ = write(1, @ptrToInt("Hello, World!\n"), 14);
...@@ -814,7 +814,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -814,7 +814,7 @@ pub fn addCases(ctx: *TestContext) !void {
814 }),814 }),
815 .macos => try case.files.append(.{815 .macos => try case.files.append(.{
816 .src = 816 .src =
817 \\extern fn write(usize, usize, usize) usize;817 \\extern "c" fn write(usize, usize, usize) usize;
818 \\fn print() void {818 \\fn print() void {
819 \\ _ = write(1, @ptrToInt("Hello, World!\n"), 14);819 \\ _ = write(1, @ptrToInt("Hello, World!\n"), 14);
820 \\}820 \\}
...@@ -1478,7 +1478,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1478,7 +1478,7 @@ pub fn addCases(ctx: *TestContext) !void {
1478 \\}1478 \\}
1479 , "HelloHello, World!\n"),1479 , "HelloHello, World!\n"),
1480 .macos => case.addCompareOutput(1480 .macos => case.addCompareOutput(
1481 \\extern fn write(usize, usize, usize) usize;1481 \\extern "c" fn write(usize, usize, usize) usize;
1482 \\1482 \\
1483 \\pub fn main() void {1483 \\pub fn main() void {
1484 \\ comptime var len: u32 = 5;1484 \\ comptime var len: u32 = 5;
...@@ -1550,7 +1550,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1550,7 +1550,7 @@ pub fn addCases(ctx: *TestContext) !void {
1550 \\}1550 \\}
1551 , "HeHelHellHello"),1551 , "HeHelHellHello"),
1552 .macos => case.addCompareOutput(1552 .macos => case.addCompareOutput(
1553 \\extern fn write(usize, usize, usize) usize;1553 \\extern "c" fn write(usize, usize, usize) usize;
1554 \\1554 \\
1555 \\pub fn main() void {1555 \\pub fn main() void {
1556 \\ comptime var i: u64 = 2;1556 \\ comptime var i: u64 = 2;
...@@ -2117,8 +2117,8 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -2117,8 +2117,8 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
21172117
2118 // Regular old hello world2118 // Regular old hello world
2119 case.addCompareOutput(2119 case.addCompareOutput(
2120 \\extern fn write(usize, usize, usize) usize;2120 \\extern "c" fn write(usize, usize, usize) usize;
2121 \\extern fn exit(usize) noreturn;2121 \\extern "c" fn exit(usize) noreturn;
2122 \\2122 \\
2123 \\pub export fn main() noreturn {2123 \\pub export fn main() noreturn {
2124 \\ print();2124 \\ print();
...@@ -2137,7 +2137,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -2137,7 +2137,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
21372137
2138 // Now using start.zig without an explicit extern exit fn2138 // Now using start.zig without an explicit extern exit fn
2139 case.addCompareOutput(2139 case.addCompareOutput(
2140 \\extern fn write(usize, usize, usize) usize;2140 \\extern "c" fn write(usize, usize, usize) usize;
2141 \\2141 \\
2142 \\pub fn main() void {2142 \\pub fn main() void {
2143 \\ print();2143 \\ print();
...@@ -2154,7 +2154,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -2154,7 +2154,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
21542154
2155 // Print it 4 times and force growth and realloc.2155 // Print it 4 times and force growth and realloc.
2156 case.addCompareOutput(2156 case.addCompareOutput(
2157 \\extern fn write(usize, usize, usize) usize;2157 \\extern "c" fn write(usize, usize, usize) usize;
2158 \\2158 \\
2159 \\pub fn main() void {2159 \\pub fn main() void {
2160 \\ print();2160 \\ print();
...@@ -2178,7 +2178,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -2178,7 +2178,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
21782178
2179 // Print it once, and change the message.2179 // Print it once, and change the message.
2180 case.addCompareOutput(2180 case.addCompareOutput(
2181 \\extern fn write(usize, usize, usize) usize;2181 \\extern "c" fn write(usize, usize, usize) usize;
2182 \\2182 \\
2183 \\pub fn main() void {2183 \\pub fn main() void {
2184 \\ print();2184 \\ print();
...@@ -2195,7 +2195,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -2195,7 +2195,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
21952195
2196 // Now we print it twice.2196 // Now we print it twice.
2197 case.addCompareOutput(2197 case.addCompareOutput(
2198 \\extern fn write(usize, usize, usize) usize;2198 \\extern "c" fn write(usize, usize, usize) usize;
2199 \\2199 \\
2200 \\pub fn main() void {2200 \\pub fn main() void {
2201 \\ print();2201 \\ print();