authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-02 20:59:17+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-02 22:10:59-07:00
logd107ef86973692123892bcd5e47ce1b17982283a
tree23959c8a254ef0eb9144a518f407ae59fd1302f2
parentcee0f082df0bb0f90c7ee38c98ba8071c3be8d0c

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(+), 32 deletions(-)

src/Sema.zig+11-5
...@@ -5145,11 +5145,6 @@ fn funcCommon(...@@ -5145,11 +5145,6 @@ fn funcCommon(
5145 if (opt_lib_name) |lib_name| blk: {5145 if (opt_lib_name) |lib_name| blk: {
5146 const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset };5146 const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset };
5147 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});5147 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
5148 mod.comp.stage1AddLinkLib(lib_name) catch |err| {
5149 return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
5150 lib_name, @errorName(err),
5151 });
5152 };
5153 const target = mod.getTarget();5148 const target = mod.getTarget();
5154 if (target_util.is_libc_lib_name(target, lib_name)) {5149 if (target_util.is_libc_lib_name(target, lib_name)) {
5155 if (!mod.comp.bin_file.options.link_libc) {5150 if (!mod.comp.bin_file.options.link_libc) {
...@@ -5160,6 +5155,7 @@ fn funcCommon(...@@ -5160,6 +5155,7 @@ fn funcCommon(
5160 .{},5155 .{},
5161 );5156 );
5162 }5157 }
5158 mod.comp.bin_file.options.link_libc = true;
5163 break :blk;5159 break :blk;
5164 }5160 }
5165 if (target_util.is_libcpp_lib_name(target, lib_name)) {5161 if (target_util.is_libcpp_lib_name(target, lib_name)) {
...@@ -5171,6 +5167,11 @@ fn funcCommon(...@@ -5171,6 +5167,11 @@ fn funcCommon(
5171 .{},5167 .{},
5172 );5168 );
5173 }5169 }
5170 mod.comp.bin_file.options.link_libcpp = true;
5171 break :blk;
5172 }
5173 if (mem.eql(u8, lib_name, "unwind")) {
5174 mod.comp.bin_file.options.link_libunwind = true;
5174 break :blk;5175 break :blk;
5175 }5176 }
5176 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {5177 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
...@@ -5181,6 +5182,11 @@ fn funcCommon(...@@ -5181,6 +5182,11 @@ fn funcCommon(
5181 .{ lib_name, lib_name },5182 .{ lib_name, lib_name },
5182 );5183 );
5183 }5184 }
5185 mod.comp.stage1AddLinkLib(lib_name) catch |err| {
5186 return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{
5187 lib_name, @errorName(err),
5188 });
5189 };
5184 }5190 }
51855191
5186 if (is_extern) {5192 if (is_extern) {
src/link/MachO.zig+14-8
...@@ -143,9 +143,6 @@ objc_data_section_index: ?u16 = null,...@@ -143,9 +143,6 @@ objc_data_section_index: ?u16 = null,
143rustc_section_index: ?u16 = null,143rustc_section_index: ?u16 = null,
144rustc_section_size: u64 = 0,144rustc_section_size: u64 = 0,
145145
146bss_file_offset: u32 = 0,
147tlv_bss_file_offset: u32 = 0,
148
149locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},146locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
150globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},147globals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
151undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},148undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{},
...@@ -384,7 +381,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {...@@ -384,7 +381,8 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
384 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator381 // Adhoc code signature is required when targeting aarch64-macos either directly or indirectly via the simulator
385 // ABI such as aarch64-ios-simulator, etc.382 // ABI such as aarch64-ios-simulator, etc.
386 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);383 const requires_adhoc_codesig = cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator);
387 const needs_prealloc = !(build_options.is_stage1 and options.use_stage1);384 const use_stage1 = build_options.is_stage1 and options.use_stage1;
385 const needs_prealloc = !(use_stage1 or options.cache_mode == .whole);
388386
389 self.* = .{387 self.* = .{
390 .base = .{388 .base = .{
...@@ -2129,7 +2127,8 @@ fn writeAtoms(self: *MachO) !void {...@@ -2129,7 +2127,8 @@ fn writeAtoms(self: *MachO) !void {
2129 const sect = seg.sections.items[match.sect];2127 const sect = seg.sections.items[match.sect];
2130 var atom: *Atom = entry.value_ptr.*;2128 var atom: *Atom = entry.value_ptr.*;
21312129
2132 if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;2130 // TODO handle zerofill in stage2
2131 // if (sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL) continue;
21332132
2134 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });2133 log.debug("writing atoms in {s},{s}", .{ sect.segName(), sect.sectName() });
21352134
...@@ -4566,9 +4565,12 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4566,9 +4565,12 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
4566 var start: u64 = offset;4565 var start: u64 = offset;
4567 for (seg.sections.items) |*sect, sect_id| {4566 for (seg.sections.items) |*sect, sect_id| {
4568 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;4567 const is_zerofill = sect.flags == macho.S_ZEROFILL or sect.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4568 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
4569 const alignment = try math.powi(u32, 2, sect.@"align");4569 const alignment = try math.powi(u32, 2, sect.@"align");
4570 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);4570 const start_aligned = mem.alignForwardGeneric(u64, start, alignment);
4571 sect.offset = if (is_zerofill) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);4571
4572 // TODO handle zerofill sections in stage2
4573 sect.offset = if (is_zerofill and use_stage1) 0 else @intCast(u32, seg.inner.fileoff + start_aligned);
4572 sect.addr = seg.inner.vmaddr + start_aligned;4574 sect.addr = seg.inner.vmaddr + start_aligned;
45734575
4574 // Recalculate section size given the allocated start address4576 // Recalculate section size given the allocated start address
...@@ -4596,7 +4598,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {...@@ -4596,7 +4598,7 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void {
45964598
4597 start = start_aligned + sect.size;4599 start = start_aligned + sect.size;
45984600
4599 if (!is_zerofill) {4601 if (!(is_zerofill and use_stage1)) {
4600 seg.inner.filesize = start;4602 seg.inner.filesize = start;
4601 }4603 }
4602 seg.inner.vmsize = start;4604 seg.inner.vmsize = start;
...@@ -4644,7 +4646,11 @@ fn initSection(...@@ -4644,7 +4646,11 @@ fn initSection(
46444646
4645 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;4647 sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff;
46464648
4647 if (opts.flags != macho.S_ZEROFILL and opts.flags != macho.S_THREAD_LOCAL_ZEROFILL) {4649 const is_zerofill = opts.flags == macho.S_ZEROFILL or opts.flags == macho.S_THREAD_LOCAL_ZEROFILL;
4650 const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1;
4651
4652 // TODO handle zerofill in stage2
4653 if (!(is_zerofill and use_stage1)) {
4648 sect.offset = @intCast(u32, off);4654 sect.offset = @intCast(u32, off);
4649 }4655 }
4650 }4656 }
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;
...@@ -1877,8 +1877,8 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -1877,8 +1877,8 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
18771877
1878 // Regular old hello world1878 // Regular old hello world
1879 case.addCompareOutput(1879 case.addCompareOutput(
1880 \\extern fn write(usize, usize, usize) usize;1880 \\extern "c" fn write(usize, usize, usize) usize;
1881 \\extern fn exit(usize) noreturn;1881 \\extern "c" fn exit(usize) noreturn;
1882 \\1882 \\
1883 \\pub export fn main() noreturn {1883 \\pub export fn main() noreturn {
1884 \\ print();1884 \\ print();
...@@ -1897,7 +1897,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -1897,7 +1897,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
18971897
1898 // Now using start.zig without an explicit extern exit fn1898 // Now using start.zig without an explicit extern exit fn
1899 case.addCompareOutput(1899 case.addCompareOutput(
1900 \\extern fn write(usize, usize, usize) usize;1900 \\extern "c" fn write(usize, usize, usize) usize;
1901 \\1901 \\
1902 \\pub fn main() void {1902 \\pub fn main() void {
1903 \\ print();1903 \\ print();
...@@ -1914,7 +1914,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -1914,7 +1914,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
19141914
1915 // Print it 4 times and force growth and realloc.1915 // Print it 4 times and force growth and realloc.
1916 case.addCompareOutput(1916 case.addCompareOutput(
1917 \\extern fn write(usize, usize, usize) usize;1917 \\extern "c" fn write(usize, usize, usize) usize;
1918 \\1918 \\
1919 \\pub fn main() void {1919 \\pub fn main() void {
1920 \\ print();1920 \\ print();
...@@ -1938,7 +1938,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -1938,7 +1938,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
19381938
1939 // Print it once, and change the message.1939 // Print it once, and change the message.
1940 case.addCompareOutput(1940 case.addCompareOutput(
1941 \\extern fn write(usize, usize, usize) usize;1941 \\extern "c" fn write(usize, usize, usize) usize;
1942 \\1942 \\
1943 \\pub fn main() void {1943 \\pub fn main() void {
1944 \\ print();1944 \\ print();
...@@ -1955,7 +1955,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {...@@ -1955,7 +1955,7 @@ fn addMacOsTestCases(ctx: *TestContext) !void {
19551955
1956 // Now we print it twice.1956 // Now we print it twice.
1957 case.addCompareOutput(1957 case.addCompareOutput(
1958 \\extern fn write(usize, usize, usize) usize;1958 \\extern "c" fn write(usize, usize, usize) usize;
1959 \\1959 \\
1960 \\pub fn main() void {1960 \\pub fn main() void {
1961 \\ print();1961 \\ print();