mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
Merge pull request #13463 from ziglang/fix-13056
macho: parse weak imports in tbd descriptors
This commit is contained in:
parent
5f74bec076
commit
8d488246da
@ -22,7 +22,14 @@ weak: bool = false,
|
||||
/// Parsed symbol table represented as hash map of symbols'
|
||||
/// names. We can and should defer creating *Symbols until
|
||||
/// a symbol is referenced by an object file.
|
||||
symbols: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||
///
|
||||
/// The value for each parsed symbol represents whether the
|
||||
/// symbol is defined as a weak symbol or strong.
|
||||
/// TODO when the referenced symbol is weak, ld64 marks it as
|
||||
/// N_REF_TO_WEAK but need to investigate if there's more to it
|
||||
/// such as weak binding entry or simply weak. For now, we generate
|
||||
/// standard bind or lazy bind.
|
||||
symbols: std.StringArrayHashMapUnmanaged(bool) = .{},
|
||||
|
||||
pub const Id = struct {
|
||||
name: []const u8,
|
||||
@ -168,7 +175,7 @@ pub fn parseFromBinary(
|
||||
if (!add_to_symtab) continue;
|
||||
|
||||
const sym_name = mem.sliceTo(@ptrCast([*:0]const u8, strtab.ptr + sym.n_strx), 0);
|
||||
try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});
|
||||
try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false);
|
||||
}
|
||||
},
|
||||
.ID_DYLIB => {
|
||||
@ -202,25 +209,30 @@ fn addObjCClassSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8)
|
||||
|
||||
for (expanded) |sym| {
|
||||
if (self.symbols.contains(sym)) continue;
|
||||
try self.symbols.putNoClobber(allocator, sym, {});
|
||||
try self.symbols.putNoClobber(allocator, sym, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn addObjCIVarSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
|
||||
const expanded = try std.fmt.allocPrint(allocator, "_OBJC_IVAR_$_{s}", .{sym_name});
|
||||
if (self.symbols.contains(expanded)) return;
|
||||
try self.symbols.putNoClobber(allocator, expanded, {});
|
||||
try self.symbols.putNoClobber(allocator, expanded, false);
|
||||
}
|
||||
|
||||
fn addObjCEhTypeSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
|
||||
const expanded = try std.fmt.allocPrint(allocator, "_OBJC_EHTYPE_$_{s}", .{sym_name});
|
||||
if (self.symbols.contains(expanded)) return;
|
||||
try self.symbols.putNoClobber(allocator, expanded, {});
|
||||
try self.symbols.putNoClobber(allocator, expanded, false);
|
||||
}
|
||||
|
||||
fn addSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
|
||||
if (self.symbols.contains(sym_name)) return;
|
||||
try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), {});
|
||||
try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), false);
|
||||
}
|
||||
|
||||
fn addWeakSymbol(self: *Dylib, allocator: Allocator, sym_name: []const u8) !void {
|
||||
if (self.symbols.contains(sym_name)) return;
|
||||
try self.symbols.putNoClobber(allocator, try allocator.dupe(u8, sym_name), true);
|
||||
}
|
||||
|
||||
const TargetMatcher = struct {
|
||||
@ -359,6 +371,12 @@ pub fn parseFromStub(
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.weak_symbols) |symbols| {
|
||||
for (symbols) |sym_name| {
|
||||
try self.addWeakSymbol(allocator, sym_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.objc_classes) |objc_classes| {
|
||||
for (objc_classes) |class_name| {
|
||||
try self.addObjCClassSymbol(allocator, class_name);
|
||||
@ -402,6 +420,12 @@ pub fn parseFromStub(
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.weak_symbols) |symbols| {
|
||||
for (symbols) |sym_name| {
|
||||
try self.addWeakSymbol(allocator, sym_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (exp.objc_classes) |classes| {
|
||||
for (classes) |sym_name| {
|
||||
try self.addObjCClassSymbol(allocator, sym_name);
|
||||
@ -432,6 +456,12 @@ pub fn parseFromStub(
|
||||
}
|
||||
}
|
||||
|
||||
if (reexp.weak_symbols) |symbols| {
|
||||
for (symbols) |sym_name| {
|
||||
try self.addWeakSymbol(allocator, sym_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (reexp.objc_classes) |classes| {
|
||||
for (classes) |sym_name| {
|
||||
try self.addObjCClassSymbol(allocator, sym_name);
|
||||
|
||||
@ -26,6 +26,7 @@ pub const TbdV3 = struct {
|
||||
allowable_clients: ?[]const []const u8,
|
||||
re_exports: ?[]const []const u8,
|
||||
symbols: ?[]const []const u8,
|
||||
weak_symbols: ?[]const []const u8,
|
||||
objc_classes: ?[]const []const u8,
|
||||
objc_ivars: ?[]const []const u8,
|
||||
objc_eh_types: ?[]const []const u8,
|
||||
@ -53,6 +54,7 @@ pub const TbdV4 = struct {
|
||||
exports: ?[]const struct {
|
||||
targets: []const []const u8,
|
||||
symbols: ?[]const []const u8,
|
||||
weak_symbols: ?[]const []const u8,
|
||||
objc_classes: ?[]const []const u8,
|
||||
objc_ivars: ?[]const []const u8,
|
||||
objc_eh_types: ?[]const []const u8,
|
||||
@ -60,6 +62,7 @@ pub const TbdV4 = struct {
|
||||
reexports: ?[]const struct {
|
||||
targets: []const []const u8,
|
||||
symbols: ?[]const []const u8,
|
||||
weak_symbols: ?[]const []const u8,
|
||||
objc_classes: ?[]const []const u8,
|
||||
objc_ivars: ?[]const []const u8,
|
||||
objc_eh_types: ?[]const []const u8,
|
||||
|
||||
@ -79,6 +79,11 @@ fn addWasmCases(cases: *tests.StandaloneContext) void {
|
||||
}
|
||||
|
||||
fn addMachOCases(cases: *tests.StandaloneContext) void {
|
||||
cases.addBuildFile("test/link/macho/bugs/13056/build.zig", .{
|
||||
.build_modes = true,
|
||||
.requires_macos_sdk = true,
|
||||
});
|
||||
|
||||
cases.addBuildFile("test/link/macho/bugs/13457/build.zig", .{
|
||||
.build_modes = true,
|
||||
});
|
||||
|
||||
29
test/link/macho/bugs/13056/build.zig
Normal file
29
test/link/macho/bugs/13056/build.zig
Normal file
@ -0,0 +1,29 @@
|
||||
const std = @import("std");
|
||||
const Builder = std.build.Builder;
|
||||
|
||||
pub fn build(b: *Builder) void {
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const target: std.zig.CrossTarget = .{ .os_tag = .macos };
|
||||
const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable;
|
||||
const sdk = std.zig.system.darwin.getDarwinSDK(b.allocator, target_info.target) orelse
|
||||
@panic("macOS SDK is required to run the test");
|
||||
|
||||
const test_step = b.step("test", "Test the program");
|
||||
|
||||
const exe = b.addExecutable("test", null);
|
||||
b.default_step.dependOn(&exe.step);
|
||||
exe.addIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include" }) catch unreachable);
|
||||
exe.addIncludePath(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/include/c++/v1" }) catch unreachable);
|
||||
exe.addCSourceFile("test.cpp", &.{
|
||||
"-nostdlib++",
|
||||
"-nostdinc++",
|
||||
});
|
||||
exe.addObjectFile(std.fs.path.join(b.allocator, &.{ sdk.path, "/usr/lib/libc++.tbd" }) catch unreachable);
|
||||
exe.setBuildMode(mode);
|
||||
|
||||
const run_cmd = exe.run();
|
||||
run_cmd.expectStdErrEqual("x: 5\n");
|
||||
|
||||
test_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
10
test/link/macho/bugs/13056/test.cpp
Normal file
10
test/link/macho/bugs/13056/test.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
// test.cpp
|
||||
#include <new>
|
||||
#include <cstdio>
|
||||
|
||||
int main() {
|
||||
int *x = new int;
|
||||
*x = 5;
|
||||
fprintf(stderr, "x: %d\n", *x);
|
||||
delete x;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user