authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-13 17:12:26+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-04-13 17:12:26+02:00
log36a33c99e3bc0825ada2ce1b374c32b4d6dee6b0
treed94b91c8915261eb8bb239a9b7d2b846fc1bcd27
parenta5bbc66f10339cb2e17ef996ef097b696980595a
parent461543a5fd27415710f027d034b83ef196bc8a44
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8517 from ziglang/zld-archive-fix

zld: fix symbol resolution from interdependent static archives

8 files changed, 56 insertions(+), 21 deletions(-)

src/link/MachO/Zld.zig+9-21
...@@ -1284,17 +1284,14 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1284,17 +1284,14 @@ fn resolveSymbols(self: *Zld) !void {
1284 }1284 }
12851285
1286 // Second pass, resolve symbols in static libraries.1286 // Second pass, resolve symbols in static libraries.
1287 var next: usize = 0;1287 var next_sym: usize = 0;
1288 var hit: bool = undefined;1288 var nsyms: usize = self.symtab.items().len;
1289 while (true) {1289 while (next_sym < nsyms) : (next_sym += 1) {
1290 var archive = &self.archives.items[next];1290 const sym = self.symtab.items()[next_sym];
1291 hit = false;1291 if (sym.value.tag != .undef) continue;
12921292
1293 for (self.symtab.items()) |entry| {1293 const sym_name = sym.value.name;
1294 if (entry.value.tag != .undef) continue;1294 for (self.archives.items) |archive| {
1295
1296 const sym_name = entry.value.name;
1297
1298 // Check if the entry exists in a static archive.1295 // Check if the entry exists in a static archive.
1299 const offsets = archive.toc.get(sym_name) orelse {1296 const offsets = archive.toc.get(sym_name) orelse {
1300 // No hit.1297 // No hit.
...@@ -1307,18 +1304,9 @@ fn resolveSymbols(self: *Zld) !void {...@@ -1307,18 +1304,9 @@ fn resolveSymbols(self: *Zld) !void {
1307 try self.objects.append(self.allocator, object);1304 try self.objects.append(self.allocator, object);
1308 try self.resolveSymbolsInObject(object_id);1305 try self.resolveSymbolsInObject(object_id);
13091306
1310 hit = true;1307 nsyms = self.symtab.items().len;
1311 break;1308 break;
1312 }1309 }
1313
1314 if (!hit) {
1315 // Next archive.
1316 next += 1;
1317 if (next == self.archives.items.len) {
1318 break;
1319 }
1320 archive = &self.archives.items[next];
1321 }
1322 }1310 }
13231311
1324 // Third pass, resolve symbols in dynamic libraries.1312 // Third pass, resolve symbols in dynamic libraries.
test/standalone.zig+1
...@@ -16,6 +16,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -16,6 +16,7 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
16 cases.addBuildFile("test/standalone/mix_o_files/build.zig");16 cases.addBuildFile("test/standalone/mix_o_files/build.zig");
17 cases.addBuildFile("test/standalone/global_linkage/build.zig");17 cases.addBuildFile("test/standalone/global_linkage/build.zig");
18 cases.addBuildFile("test/standalone/static_c_lib/build.zig");18 cases.addBuildFile("test/standalone/static_c_lib/build.zig");
19 cases.addBuildFile("test/standalone/link_interdependent_static_c_libs/build.zig");
19 cases.addBuildFile("test/standalone/issue_339/build.zig");20 cases.addBuildFile("test/standalone/issue_339/build.zig");
20 cases.addBuildFile("test/standalone/issue_794/build.zig");21 cases.addBuildFile("test/standalone/issue_794/build.zig");
21 cases.addBuildFile("test/standalone/issue_5825/build.zig");22 cases.addBuildFile("test/standalone/issue_5825/build.zig");
test/standalone/link_interdependent_static_c_libs/a.c created+4
...@@ -0,0 +1,4 @@
1#include "a.h"
2int32_t add(int32_t a, int32_t b) {
3 return a + b;
4}
test/standalone/link_interdependent_static_c_libs/a.h created+2
...@@ -0,0 +1,2 @@
1#include <stdint.h>
2int32_t add(int32_t a, int32_t b);
test/standalone/link_interdependent_static_c_libs/b.c created+6
...@@ -0,0 +1,6 @@
1#include "a.h"
2#include "b.h"
3
4int32_t sub(int32_t a, int32_t b) {
5 return add(a, -1 * b);
6}
test/standalone/link_interdependent_static_c_libs/b.h created+2
...@@ -0,0 +1,2 @@
1#include <stdint.h>
2int32_t sub(int32_t a, int32_t b);
test/standalone/link_interdependent_static_c_libs/build.zig created+24
...@@ -0,0 +1,24 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const mode = b.standardReleaseOptions();
5
6 const lib_a = b.addStaticLibrary("a", null);
7 lib_a.addCSourceFile("a.c", &[_][]const u8{});
8 lib_a.setBuildMode(mode);
9 lib_a.addIncludeDir(".");
10
11 const lib_b = b.addStaticLibrary("b", null);
12 lib_b.addCSourceFile("b.c", &[_][]const u8{});
13 lib_b.setBuildMode(mode);
14 lib_b.addIncludeDir(".");
15
16 const test_exe = b.addTest("main.zig");
17 test_exe.setBuildMode(mode);
18 test_exe.linkLibrary(lib_a);
19 test_exe.linkLibrary(lib_b);
20 test_exe.addIncludeDir(".");
21
22 const test_step = b.step("test", "Test it");
23 test_step.dependOn(&test_exe.step);
24}
test/standalone/link_interdependent_static_c_libs/main.zig created+8
...@@ -0,0 +1,8 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const c = @cImport(@cInclude("b.h"));
4
5test "import C sub" {
6 const result = c.sub(2, 1);
7 expect(result == 1);
8}