commit 55a8b7e1fa4d36f5283d1f8655d3baecfefeffa3 (tree)
parent 4ebf483e0da2f85e00918b7900afaf73e111b727
Author: Andrew Kelley <andrew@ziglang.org>
Date: Fri, 7 Apr 2023 19:58:55 -0400
Merge pull request #15097 from zachcheu/add-wrap-flag
add linker -wrap flag
Diffstat:
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/Compilation.zig b/src/Compilation.zig
@@ -494,6 +494,7 @@ pub const InitOptions = struct {
clang_argv: []const []const u8 = &[0][]const u8{},
lib_dirs: []const []const u8 = &[0][]const u8{},
rpath_list: []const []const u8 = &[0][]const u8{},
+ symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{},
c_source_files: []const CSourceFile = &[0]CSourceFile{},
link_objects: []LinkObject = &[0]LinkObject{},
framework_dirs: []const []const u8 = &[0][]const u8{},
@@ -825,7 +826,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
options.output_mode == .Lib or
options.linker_script != null or options.version_script != null or
options.emit_implib != null or
- build_id)
+ build_id or
+ options.symbol_wrap_set.count() > 0)
{
break :blk true;
}
@@ -1438,6 +1440,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.wasi_emulated_libs = options.wasi_emulated_libs,
.lib_dirs = options.lib_dirs,
.rpath_list = options.rpath_list,
+ .symbol_wrap_set = options.symbol_wrap_set,
.strip = strip,
.is_native_os = options.is_native_os,
.is_native_abi = options.is_native_abi,
@@ -2259,6 +2262,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.add(comp.bin_file.options.rdynamic);
man.hash.addListOfBytes(comp.bin_file.options.lib_dirs);
man.hash.addListOfBytes(comp.bin_file.options.rpath_list);
+ man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys());
man.hash.add(comp.bin_file.options.each_lib_rpath);
man.hash.add(comp.bin_file.options.build_id);
man.hash.add(comp.bin_file.options.skip_linker_dependencies);
diff --git a/src/link.zig b/src/link.zig
@@ -188,6 +188,13 @@ pub const Options = struct {
/// thus forcing their resolution by the linker.
/// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE.
force_undefined_symbols: std.StringArrayHashMapUnmanaged(void),
+ /// Use a wrapper function for symbol. Any undefined reference to symbol
+ /// will be resolved to __wrap_symbol. Any undefined reference to
+ /// __real_symbol will be resolved to symbol. This can be used to provide a
+ /// wrapper for a system function. The wrapper function should be called
+ /// __wrap_symbol. If it wishes to call the system function, it should call
+ /// __real_symbol.
+ symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
version: ?std.builtin.Version,
compatibility_version: ?std.builtin.Version,
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
@@ -1386,6 +1386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
man.hash.add(stack_size);
man.hash.add(self.base.options.build_id);
}
+ man.hash.addListOfBytes(self.base.options.symbol_wrap_set.keys());
man.hash.add(self.base.options.skip_linker_dependencies);
man.hash.add(self.base.options.z_nodelete);
man.hash.add(self.base.options.z_notext);
@@ -1665,6 +1666,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
try argv.append(rpath);
}
}
+
+ for (self.base.options.symbol_wrap_set.keys()) |symbol_name| {
+ try argv.appendSlice(&.{ "-wrap", symbol_name });
+ }
+
if (self.base.options.each_lib_rpath) {
var test_path = std.ArrayList(u8).init(self.base.allocator);
defer test_path.deinit();
diff --git a/src/main.zig b/src/main.zig
@@ -874,6 +874,8 @@ fn buildOutputType(
var rpath_list = std.ArrayList([]const u8).init(gpa);
defer rpath_list.deinit();
+ var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{};
+
var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa);
defer c_source_files.deinit();
@@ -2155,6 +2157,9 @@ fn buildOutputType(
next_arg,
});
};
+ } else if (mem.eql(u8, arg, "-wrap")) {
+ const next_arg = linker_args_it.nextOrFatal();
+ try symbol_wrap_set.put(arena, next_arg, {});
} else if (mem.startsWith(u8, arg, "/subsystem:")) {
var split_it = mem.splitBackwards(u8, arg, ":");
subsystem = try parseSubSystem(split_it.first());
@@ -3039,6 +3044,7 @@ fn buildOutputType(
.clang_argv = clang_argv.items,
.lib_dirs = lib_dirs.items,
.rpath_list = rpath_list.items,
+ .symbol_wrap_set = symbol_wrap_set,
.c_source_files = c_source_files.items,
.link_objects = link_objects.items,
.framework_dirs = framework_dirs.items,