| author | |
| committer | |
| log | 55a8b7e1fa4d36f5283d1f8655d3baecfefeffa3 |
| tree | a427e2fac6d904759d6f7e00356744f7ec331e48 |
| parent | 4ebf483e0da2f85e00918b7900afaf73e111b727 |
| parent | b086b7da9e9adbb4445363f635d3bb37177b2f18 |
| signature |
add linker -wrap flag4 files changed, 24 insertions(+), 1 deletions(-)
src/Compilation.zig+5-1| ... | @@ -494,6 +494,7 @@ pub const InitOptions = struct { | ... | @@ -494,6 +494,7 @@ pub const InitOptions = struct { |
| 494 | clang_argv: []const []const u8 = &[0][]const u8{}, | 494 | clang_argv: []const []const u8 = &[0][]const u8{}, |
| 495 | lib_dirs: []const []const u8 = &[0][]const u8{}, | 495 | lib_dirs: []const []const u8 = &[0][]const u8{}, |
| 496 | rpath_list: []const []const u8 = &[0][]const u8{}, | 496 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 497 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}, | ||
| 497 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, | 498 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 498 | link_objects: []LinkObject = &[0]LinkObject{}, | 499 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 499 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 500 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| ... | @@ -825,7 +826,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -825,7 +826,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 825 | options.output_mode == .Lib or | 826 | options.output_mode == .Lib or |
| 826 | options.linker_script != null or options.version_script != null or | 827 | options.linker_script != null or options.version_script != null or |
| 827 | options.emit_implib != null or | 828 | options.emit_implib != null or |
| 828 | build_id) | 829 | build_id or |
| 830 | options.symbol_wrap_set.count() > 0) | ||
| 829 | { | 831 | { |
| 830 | break :blk true; | 832 | break :blk true; |
| 831 | } | 833 | } |
| ... | @@ -1438,6 +1440,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1438,6 +1440,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1438 | .wasi_emulated_libs = options.wasi_emulated_libs, | 1440 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 1439 | .lib_dirs = options.lib_dirs, | 1441 | .lib_dirs = options.lib_dirs, |
| 1440 | .rpath_list = options.rpath_list, | 1442 | .rpath_list = options.rpath_list, |
| 1443 | .symbol_wrap_set = options.symbol_wrap_set, | ||
| 1441 | .strip = strip, | 1444 | .strip = strip, |
| 1442 | .is_native_os = options.is_native_os, | 1445 | .is_native_os = options.is_native_os, |
| 1443 | .is_native_abi = options.is_native_abi, | 1446 | .is_native_abi = options.is_native_abi, |
| ... | @@ -2259,6 +2262,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2259,6 +2262,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2259 | man.hash.add(comp.bin_file.options.rdynamic); | 2262 | man.hash.add(comp.bin_file.options.rdynamic); |
| 2260 | man.hash.addListOfBytes(comp.bin_file.options.lib_dirs); | 2263 | man.hash.addListOfBytes(comp.bin_file.options.lib_dirs); |
| 2261 | man.hash.addListOfBytes(comp.bin_file.options.rpath_list); | 2264 | man.hash.addListOfBytes(comp.bin_file.options.rpath_list); |
| 2265 | man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys()); | ||
| 2262 | man.hash.add(comp.bin_file.options.each_lib_rpath); | 2266 | man.hash.add(comp.bin_file.options.each_lib_rpath); |
| 2263 | man.hash.add(comp.bin_file.options.build_id); | 2267 | man.hash.add(comp.bin_file.options.build_id); |
| 2264 | man.hash.add(comp.bin_file.options.skip_linker_dependencies); | 2268 | man.hash.add(comp.bin_file.options.skip_linker_dependencies); |
src/link.zig+7| ... | @@ -188,6 +188,13 @@ pub const Options = struct { | ... | @@ -188,6 +188,13 @@ pub const Options = struct { |
| 188 | /// thus forcing their resolution by the linker. | 188 | /// thus forcing their resolution by the linker. |
| 189 | /// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE. | 189 | /// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE. |
| 190 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void), | 190 | force_undefined_symbols: std.StringArrayHashMapUnmanaged(void), |
| 191 | /// Use a wrapper function for symbol. Any undefined reference to symbol | ||
| 192 | /// will be resolved to __wrap_symbol. Any undefined reference to | ||
| 193 | /// __real_symbol will be resolved to symbol. This can be used to provide a | ||
| 194 | /// wrapper for a system function. The wrapper function should be called | ||
| 195 | /// __wrap_symbol. If it wishes to call the system function, it should call | ||
| 196 | /// __real_symbol. | ||
| 197 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void), | ||
| 191 | 198 | ||
| 192 | version: ?std.builtin.Version, | 199 | version: ?std.builtin.Version, |
| 193 | compatibility_version: ?std.builtin.Version, | 200 | compatibility_version: ?std.builtin.Version, |
src/link/Elf.zig+6| ... | @@ -1386,6 +1386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1386,6 +1386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1386 | man.hash.add(stack_size); | 1386 | man.hash.add(stack_size); |
| 1387 | man.hash.add(self.base.options.build_id); | 1387 | man.hash.add(self.base.options.build_id); |
| 1388 | } | 1388 | } |
| 1389 | man.hash.addListOfBytes(self.base.options.symbol_wrap_set.keys()); | ||
| 1389 | man.hash.add(self.base.options.skip_linker_dependencies); | 1390 | man.hash.add(self.base.options.skip_linker_dependencies); |
| 1390 | man.hash.add(self.base.options.z_nodelete); | 1391 | man.hash.add(self.base.options.z_nodelete); |
| 1391 | man.hash.add(self.base.options.z_notext); | 1392 | man.hash.add(self.base.options.z_notext); |
| ... | @@ -1665,6 +1666,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1665,6 +1666,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1665 | try argv.append(rpath); | 1666 | try argv.append(rpath); |
| 1666 | } | 1667 | } |
| 1667 | } | 1668 | } |
| 1669 | |||
| 1670 | for (self.base.options.symbol_wrap_set.keys()) |symbol_name| { | ||
| 1671 | try argv.appendSlice(&.{ "-wrap", symbol_name }); | ||
| 1672 | } | ||
| 1673 | |||
| 1668 | if (self.base.options.each_lib_rpath) { | 1674 | if (self.base.options.each_lib_rpath) { |
| 1669 | var test_path = std.ArrayList(u8).init(self.base.allocator); | 1675 | var test_path = std.ArrayList(u8).init(self.base.allocator); |
| 1670 | defer test_path.deinit(); | 1676 | defer test_path.deinit(); |
src/main.zig+6| ... | @@ -874,6 +874,8 @@ fn buildOutputType( | ... | @@ -874,6 +874,8 @@ fn buildOutputType( |
| 874 | var rpath_list = std.ArrayList([]const u8).init(gpa); | 874 | var rpath_list = std.ArrayList([]const u8).init(gpa); |
| 875 | defer rpath_list.deinit(); | 875 | defer rpath_list.deinit(); |
| 876 | 876 | ||
| 877 | var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}; | ||
| 878 | |||
| 877 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); | 879 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); |
| 878 | defer c_source_files.deinit(); | 880 | defer c_source_files.deinit(); |
| 879 | 881 | ||
| ... | @@ -2155,6 +2157,9 @@ fn buildOutputType( | ... | @@ -2155,6 +2157,9 @@ fn buildOutputType( |
| 2155 | next_arg, | 2157 | next_arg, |
| 2156 | }); | 2158 | }); |
| 2157 | }; | 2159 | }; |
| 2160 | } else if (mem.eql(u8, arg, "-wrap")) { | ||
| 2161 | const next_arg = linker_args_it.nextOrFatal(); | ||
| 2162 | try symbol_wrap_set.put(arena, next_arg, {}); | ||
| 2158 | } else if (mem.startsWith(u8, arg, "/subsystem:")) { | 2163 | } else if (mem.startsWith(u8, arg, "/subsystem:")) { |
| 2159 | var split_it = mem.splitBackwards(u8, arg, ":"); | 2164 | var split_it = mem.splitBackwards(u8, arg, ":"); |
| 2160 | subsystem = try parseSubSystem(split_it.first()); | 2165 | subsystem = try parseSubSystem(split_it.first()); |
| ... | @@ -3039,6 +3044,7 @@ fn buildOutputType( | ... | @@ -3039,6 +3044,7 @@ fn buildOutputType( |
| 3039 | .clang_argv = clang_argv.items, | 3044 | .clang_argv = clang_argv.items, |
| 3040 | .lib_dirs = lib_dirs.items, | 3045 | .lib_dirs = lib_dirs.items, |
| 3041 | .rpath_list = rpath_list.items, | 3046 | .rpath_list = rpath_list.items, |
| 3047 | .symbol_wrap_set = symbol_wrap_set, | ||
| 3042 | .c_source_files = c_source_files.items, | 3048 | .c_source_files = c_source_files.items, |
| 3043 | .link_objects = link_objects.items, | 3049 | .link_objects = link_objects.items, |
| 3044 | .framework_dirs = framework_dirs.items, | 3050 | .framework_dirs = framework_dirs.items, |