| author | |
| committer | |
| log | b086b7da9e9adbb4445363f635d3bb37177b2f18 |
| tree | e288dc1b7191c94b74a2f300524bfbd1d7459d37 |
| parent | 1fdea551b22726783356c5bed90bce63706b550f |
* use a set instead of a list
* use of this flag currently requires LLD
* add documentation
* make it only a zig cc compatibility flag for now because I personally
think this is an anti-feature.4 files changed, 19 insertions(+), 26 deletions(-)
src/Compilation.zig+5-4| ... | @@ -494,7 +494,7 @@ pub const InitOptions = struct { | ... | @@ -494,7 +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 | wrap_list: []const []const u8 = &[0][]const u8{}, | 497 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}, |
| 498 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, | 498 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 499 | link_objects: []LinkObject = &[0]LinkObject{}, | 499 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 500 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 500 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| ... | @@ -826,7 +826,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -826,7 +826,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 826 | options.output_mode == .Lib or | 826 | options.output_mode == .Lib or |
| 827 | options.linker_script != null or options.version_script != null or | 827 | options.linker_script != null or options.version_script != null or |
| 828 | options.emit_implib != null or | 828 | options.emit_implib != null or |
| 829 | build_id) | 829 | build_id or |
| 830 | options.symbol_wrap_set.count() > 0) | ||
| 830 | { | 831 | { |
| 831 | break :blk true; | 832 | break :blk true; |
| 832 | } | 833 | } |
| ... | @@ -1439,7 +1440,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1439,7 +1440,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1439 | .wasi_emulated_libs = options.wasi_emulated_libs, | 1440 | .wasi_emulated_libs = options.wasi_emulated_libs, |
| 1440 | .lib_dirs = options.lib_dirs, | 1441 | .lib_dirs = options.lib_dirs, |
| 1441 | .rpath_list = options.rpath_list, | 1442 | .rpath_list = options.rpath_list, |
| 1442 | .wrap_list = options.wrap_list, | 1443 | .symbol_wrap_set = options.symbol_wrap_set, |
| 1443 | .strip = strip, | 1444 | .strip = strip, |
| 1444 | .is_native_os = options.is_native_os, | 1445 | .is_native_os = options.is_native_os, |
| 1445 | .is_native_abi = options.is_native_abi, | 1446 | .is_native_abi = options.is_native_abi, |
| ... | @@ -2261,7 +2262,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2261,7 +2262,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2261 | man.hash.add(comp.bin_file.options.rdynamic); | 2262 | man.hash.add(comp.bin_file.options.rdynamic); |
| 2262 | man.hash.addListOfBytes(comp.bin_file.options.lib_dirs); | 2263 | man.hash.addListOfBytes(comp.bin_file.options.lib_dirs); |
| 2263 | man.hash.addListOfBytes(comp.bin_file.options.rpath_list); | 2264 | man.hash.addListOfBytes(comp.bin_file.options.rpath_list); |
| 2264 | man.hash.addListOfBytes(comp.bin_file.options.wrap_list); | 2265 | man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys()); |
| 2265 | man.hash.add(comp.bin_file.options.each_lib_rpath); | 2266 | man.hash.add(comp.bin_file.options.each_lib_rpath); |
| 2266 | man.hash.add(comp.bin_file.options.build_id); | 2267 | man.hash.add(comp.bin_file.options.build_id); |
| 2267 | 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-1| ... | @@ -183,12 +183,18 @@ pub const Options = struct { | ... | @@ -183,12 +183,18 @@ pub const Options = struct { |
| 183 | wasi_emulated_libs: []const wasi_libc.CRTFile, | 183 | wasi_emulated_libs: []const wasi_libc.CRTFile, |
| 184 | lib_dirs: []const []const u8, | 184 | lib_dirs: []const []const u8, |
| 185 | rpath_list: []const []const u8, | 185 | rpath_list: []const []const u8, |
| 186 | wrap_list: []const []const u8, | ||
| 187 | 186 | ||
| 188 | /// List of symbols forced as undefined in the symbol table | 187 | /// List of symbols forced as undefined in the symbol table |
| 189 | /// thus forcing their resolution by the linker. | 188 | /// thus forcing their resolution by the linker. |
| 190 | /// 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. |
| 191 | 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), | ||
| 192 | 198 | ||
| 193 | version: ?std.builtin.Version, | 199 | version: ?std.builtin.Version, |
| 194 | compatibility_version: ?std.builtin.Version, | 200 | compatibility_version: ?std.builtin.Version, |
src/link/Elf.zig+3-9| ... | @@ -1386,7 +1386,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1386,7 +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.wrap_list); | 1389 | man.hash.addListOfBytes(self.base.options.symbol_wrap_set.keys()); |
| 1390 | man.hash.add(self.base.options.skip_linker_dependencies); | 1390 | man.hash.add(self.base.options.skip_linker_dependencies); |
| 1391 | man.hash.add(self.base.options.z_nodelete); | 1391 | man.hash.add(self.base.options.z_nodelete); |
| 1392 | man.hash.add(self.base.options.z_notext); | 1392 | man.hash.add(self.base.options.z_notext); |
| ... | @@ -1667,14 +1667,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -1667,14 +1667,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1667 | } | 1667 | } |
| 1668 | } | 1668 | } |
| 1669 | 1669 | ||
| 1670 | // wrap | 1670 | for (self.base.options.symbol_wrap_set.keys()) |symbol_name| { |
| 1671 | var wrap_table = std.StringHashMap(void).init(self.base.allocator); | 1671 | try argv.appendSlice(&.{ "-wrap", symbol_name }); |
| 1672 | defer wrap_table.deinit(); | ||
| 1673 | for (self.base.options.wrap_list) |wrap| { | ||
| 1674 | if ((try wrap_table.fetchPut(wrap, {})) == null) { | ||
| 1675 | try argv.append("-wrap"); | ||
| 1676 | try argv.append(wrap); | ||
| 1677 | } | ||
| 1678 | } | 1672 | } |
| 1679 | 1673 | ||
| 1680 | if (self.base.options.each_lib_rpath) { | 1674 | if (self.base.options.each_lib_rpath) { |
src/main.zig+4-12| ... | @@ -487,7 +487,6 @@ const usage_build_generic = | ... | @@ -487,7 +487,6 @@ const usage_build_generic = |
| 487 | \\ -fno-compiler-rt Prevent including compiler-rt symbols in output | 487 | \\ -fno-compiler-rt Prevent including compiler-rt symbols in output |
| 488 | \\ -rdynamic Add all symbols to the dynamic symbol table | 488 | \\ -rdynamic Add all symbols to the dynamic symbol table |
| 489 | \\ -rpath [path] Add directory to the runtime library search path | 489 | \\ -rpath [path] Add directory to the runtime library search path |
| 490 | \\ -wrap [symbol] Override the symbol with the wrapped symbol definition | ||
| 491 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library | 490 | \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library |
| 492 | \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library | 491 | \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library |
| 493 | \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries | 492 | \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries |
| ... | @@ -875,8 +874,7 @@ fn buildOutputType( | ... | @@ -875,8 +874,7 @@ fn buildOutputType( |
| 875 | var rpath_list = std.ArrayList([]const u8).init(gpa); | 874 | var rpath_list = std.ArrayList([]const u8).init(gpa); |
| 876 | defer rpath_list.deinit(); | 875 | defer rpath_list.deinit(); |
| 877 | 876 | ||
| 878 | var wrap_list = std.ArrayList([]const u8).init(gpa); | 877 | var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}; |
| 879 | defer wrap_list.deinit(); | ||
| 880 | 878 | ||
| 881 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); | 879 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); |
| 882 | defer c_source_files.deinit(); | 880 | defer c_source_files.deinit(); |
| ... | @@ -1479,9 +1477,6 @@ fn buildOutputType( | ... | @@ -1479,9 +1477,6 @@ fn buildOutputType( |
| 1479 | try system_libs.put(arg["-needed-l".len..], .{ .needed = true }); | 1477 | try system_libs.put(arg["-needed-l".len..], .{ .needed = true }); |
| 1480 | } else if (mem.startsWith(u8, arg, "-weak-l")) { | 1478 | } else if (mem.startsWith(u8, arg, "-weak-l")) { |
| 1481 | try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); | 1479 | try system_libs.put(arg["-weak-l".len..], .{ .weak = true }); |
| 1482 | } else if (mem.eql(u8, arg, "-wrap")){ | ||
| 1483 | try wrap_list.append(arg); | ||
| 1484 | try wrap_list.append(args_iter.nextOrFatal()); | ||
| 1485 | } else if (mem.startsWith(u8, arg, "-D")) { | 1480 | } else if (mem.startsWith(u8, arg, "-D")) { |
| 1486 | try clang_argv.append(arg); | 1481 | try clang_argv.append(arg); |
| 1487 | } else if (mem.startsWith(u8, arg, "-I")) { | 1482 | } else if (mem.startsWith(u8, arg, "-I")) { |
| ... | @@ -2163,11 +2158,8 @@ fn buildOutputType( | ... | @@ -2163,11 +2158,8 @@ fn buildOutputType( |
| 2163 | }); | 2158 | }); |
| 2164 | }; | 2159 | }; |
| 2165 | } else if (mem.eql(u8, arg, "-wrap")) { | 2160 | } else if (mem.eql(u8, arg, "-wrap")) { |
| 2166 | i += 1; | 2161 | const next_arg = linker_args_it.nextOrFatal(); |
| 2167 | if (i >= linker_args.items.len) { | 2162 | try symbol_wrap_set.put(arena, next_arg, {}); |
| 2168 | fatal("expected linker arg after '{s}'", .{arg}); | ||
| 2169 | } | ||
| 2170 | try wrap_list.append(linker_args.items[i]); | ||
| 2171 | } else if (mem.startsWith(u8, arg, "/subsystem:")) { | 2163 | } else if (mem.startsWith(u8, arg, "/subsystem:")) { |
| 2172 | var split_it = mem.splitBackwards(u8, arg, ":"); | 2164 | var split_it = mem.splitBackwards(u8, arg, ":"); |
| 2173 | subsystem = try parseSubSystem(split_it.first()); | 2165 | subsystem = try parseSubSystem(split_it.first()); |
| ... | @@ -3052,7 +3044,7 @@ fn buildOutputType( | ... | @@ -3052,7 +3044,7 @@ fn buildOutputType( |
| 3052 | .clang_argv = clang_argv.items, | 3044 | .clang_argv = clang_argv.items, |
| 3053 | .lib_dirs = lib_dirs.items, | 3045 | .lib_dirs = lib_dirs.items, |
| 3054 | .rpath_list = rpath_list.items, | 3046 | .rpath_list = rpath_list.items, |
| 3055 | .wrap_list = wrap_list.items, | 3047 | .symbol_wrap_set = symbol_wrap_set, |
| 3056 | .c_source_files = c_source_files.items, | 3048 | .c_source_files = c_source_files.items, |
| 3057 | .link_objects = link_objects.items, | 3049 | .link_objects = link_objects.items, |
| 3058 | .framework_dirs = framework_dirs.items, | 3050 | .framework_dirs = framework_dirs.items, |