| ... | ... | @@ -744,6 +744,9 @@ pub const BuiltSharedObjects = struct { |
| 744 | 744 | |
| 745 | 745 | const all_map_basename = "all.map"; |
| 746 | 746 | |
| 747 | // TODO Turn back on zig fmt when https://github.com/ziglang/zig/issues/5948 is implemented. |
| 748 | // zig fmt: off |
| 749 | |
| 747 | 750 | pub fn buildSharedObjects(comp: *Compilation) !void { |
| 748 | 751 | const tracy = trace(@src()); |
| 749 | 752 | defer tracy.end(); |
| ... | ... | @@ -765,8 +768,6 @@ pub fn buildSharedObjects(comp: *Compilation) !void { |
| 765 | 768 | cache.hash.addBytes(build_options.version); |
| 766 | 769 | cache.hash.addBytes(comp.zig_lib_directory.path orelse "."); |
| 767 | 770 | cache.hash.add(target.cpu.arch); |
| 768 | | cache.hash.addBytes(target.cpu.model.name); |
| 769 | | cache.hash.add(target.cpu.features.ints); |
| 770 | 771 | cache.hash.add(target.abi); |
| 771 | 772 | cache.hash.add(target_version); |
| 772 | 773 | |
| ... | ... | @@ -832,17 +833,9 @@ pub fn buildSharedObjects(comp: *Compilation) !void { |
| 832 | 833 | } |
| 833 | 834 | var zig_body = std.ArrayList(u8).init(comp.gpa); |
| 834 | 835 | defer zig_body.deinit(); |
| 835 | | var zig_footer = std.ArrayList(u8).init(comp.gpa); |
| 836 | | defer zig_footer.deinit(); |
| 837 | 836 | for (libs) |*lib| { |
| 838 | 837 | zig_body.shrinkRetainingCapacity(0); |
| 839 | | zig_footer.shrinkRetainingCapacity(0); |
| 840 | 838 | |
| 841 | | try zig_body.appendSlice( |
| 842 | | \\comptime { |
| 843 | | \\ asm ( |
| 844 | | \\ |
| 845 | | ); |
| 846 | 839 | for (metadata.all_functions) |*libc_fn, fn_i| { |
| 847 | 840 | if (libc_fn.lib != lib) continue; |
| 848 | 841 | |
| ... | ... | @@ -868,46 +861,66 @@ pub fn buildSharedObjects(comp: *Compilation) !void { |
| 868 | 861 | { |
| 869 | 862 | var ver_i: u8 = 0; |
| 870 | 863 | while (ver_i < ver_list.len) : (ver_i += 1) { |
| 864 | // Example: |
| 865 | // .globl _Exit_2_2_5 |
| 866 | // .type _Exit_2_2_5, @function; |
| 867 | // .symver _Exit_2_2_5, _Exit@@GLIBC_2.2.5 |
| 868 | // .hidden _Exit_2_2_5 |
| 869 | // _Exit_2_2_5: |
| 871 | 870 | const ver_index = ver_list.versions[ver_i]; |
| 872 | 871 | const ver = metadata.all_versions[ver_index]; |
| 873 | 872 | const sym_name = libc_fn.name; |
| 874 | | const stub_name = if (ver.patch == 0) |
| 875 | | try std.fmt.allocPrint(arena, "{s}_{d}_{d}", .{ sym_name, ver.major, ver.minor }) |
| 876 | | else |
| 877 | | try std.fmt.allocPrint(arena, "{s}_{d}_{d}_{d}", .{ sym_name, ver.major, ver.minor, ver.patch }); |
| 878 | | |
| 879 | | try zig_footer.writer().print("export fn {s}() void {{}}\n", .{stub_name}); |
| 880 | | |
| 881 | 873 | // Default symbol version definition vs normal symbol version definition |
| 882 | 874 | const want_two_ats = chosen_def_ver_index != 255 and ver_index == chosen_def_ver_index; |
| 883 | 875 | const at_sign_str = "@@"[0 .. @boolToInt(want_two_ats) + @as(usize, 1)]; |
| 876 | |
| 884 | 877 | if (ver.patch == 0) { |
| 885 | | try zig_body.writer().print(" \\\\.symver {s}, {s}{s}GLIBC_{d}.{d}\n", .{ |
| 886 | | stub_name, sym_name, at_sign_str, ver.major, ver.minor, |
| 878 | const sym_plus_ver = try std.fmt.allocPrint( |
| 879 | arena, "{s}_{d}_{d}", |
| 880 | .{sym_name, ver.major, ver.minor}, |
| 881 | ); |
| 882 | try zig_body.writer().print( |
| 883 | \\.globl {s} |
| 884 | \\.type {s}, @function; |
| 885 | \\.symver {s}, {s}{s}GLIBC_{d}.{d} |
| 886 | \\.hidden {s} |
| 887 | \\{s}: |
| 888 | \\ |
| 889 | , .{ |
| 890 | sym_plus_ver, |
| 891 | sym_plus_ver, |
| 892 | sym_plus_ver, sym_name, at_sign_str, ver.major, ver.minor, |
| 893 | sym_plus_ver, |
| 894 | sym_plus_ver, |
| 887 | 895 | }); |
| 888 | 896 | } else { |
| 889 | | try zig_body.writer().print(" \\\\.symver {s}, {s}{s}GLIBC_{d}.{d}.{d}\n", .{ |
| 890 | | stub_name, sym_name, at_sign_str, ver.major, ver.minor, ver.patch, |
| 897 | const sym_plus_ver = try std.fmt.allocPrint(arena, "{s}_{d}_{d}_{d}", |
| 898 | .{sym_name, ver.major, ver.minor, ver.patch}, |
| 899 | ); |
| 900 | try zig_body.writer().print( |
| 901 | \\.globl {s} |
| 902 | \\.type {s}, @function; |
| 903 | \\.symver {s}, {s}{s}GLIBC_{d}.{d}.{d} |
| 904 | \\.hidden {s} |
| 905 | \\{s}: |
| 906 | \\ |
| 907 | , .{ |
| 908 | sym_plus_ver, |
| 909 | sym_plus_ver, |
| 910 | sym_plus_ver, sym_name, at_sign_str, ver.major, ver.minor, ver.patch, |
| 911 | sym_plus_ver, |
| 912 | sym_plus_ver, |
| 891 | 913 | }); |
| 892 | 914 | } |
| 893 | | // Hide the stub to keep the symbol table clean |
| 894 | | try zig_body.writer().print(" \\\\.hidden {s}\n", .{stub_name}); |
| 895 | 915 | } |
| 896 | 916 | } |
| 897 | 917 | } |
| 898 | 918 | |
| 899 | | try zig_body.appendSlice( |
| 900 | | \\ ); |
| 901 | | \\} |
| 902 | | \\ |
| 903 | | ); |
| 904 | | try zig_body.appendSlice(zig_footer.items); |
| 905 | | |
| 906 | 919 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. |
| 907 | | const zig_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.zig", .{lib.name}) catch unreachable; |
| 908 | | try o_directory.handle.writeFile(zig_file_basename, zig_body.items); |
| 920 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; |
| 921 | try o_directory.handle.writeFile(asm_file_basename, zig_body.items); |
| 909 | 922 | |
| 910 | | try buildSharedLib(comp, arena, comp.zig_cache_directory, o_directory, zig_file_basename, lib); |
| 923 | try buildSharedLib(comp, arena, comp.zig_cache_directory, o_directory, asm_file_basename, lib); |
| 911 | 924 | } |
| 912 | 925 | // No need to write the manifest because there are no file inputs associated with this cache hash. |
| 913 | 926 | // However we do need to write the ok file now. |
| ... | ... | @@ -925,12 +938,14 @@ pub fn buildSharedObjects(comp: *Compilation) !void { |
| 925 | 938 | }; |
| 926 | 939 | } |
| 927 | 940 | |
| 941 | // zig fmt: on |
| 942 | |
| 928 | 943 | fn buildSharedLib( |
| 929 | 944 | comp: *Compilation, |
| 930 | 945 | arena: *Allocator, |
| 931 | 946 | zig_cache_directory: Compilation.Directory, |
| 932 | 947 | bin_directory: Compilation.Directory, |
| 933 | | zig_file_basename: []const u8, |
| 948 | asm_file_basename: []const u8, |
| 934 | 949 | lib: *const Lib, |
| 935 | 950 | ) !void { |
| 936 | 951 | const tracy = trace(@src()); |
| ... | ... | @@ -944,15 +959,17 @@ fn buildSharedLib( |
| 944 | 959 | const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?); |
| 945 | 960 | const override_soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else null; |
| 946 | 961 | const map_file_path = try path.join(arena, &[_][]const u8{ bin_directory.path.?, all_map_basename }); |
| 947 | | // TODO we should be able to just give the open directory to Package |
| 948 | | const root_pkg = try Package.create(comp.gpa, std.fs.cwd(), bin_directory.path.?, zig_file_basename); |
| 949 | | defer root_pkg.destroy(comp.gpa); |
| 962 | const c_source_files = [1]Compilation.CSourceFile{ |
| 963 | .{ |
| 964 | .src_path = try path.join(arena, &[_][]const u8{ bin_directory.path.?, asm_file_basename }), |
| 965 | }, |
| 966 | }; |
| 950 | 967 | const sub_compilation = try Compilation.create(comp.gpa, .{ |
| 951 | 968 | .zig_cache_directory = zig_cache_directory, |
| 952 | 969 | .zig_lib_directory = comp.zig_lib_directory, |
| 953 | 970 | .target = comp.getTarget(), |
| 954 | 971 | .root_name = lib.name, |
| 955 | | .root_pkg = root_pkg, |
| 972 | .root_pkg = null, |
| 956 | 973 | .output_mode = .Lib, |
| 957 | 974 | .link_mode = .Dynamic, |
| 958 | 975 | .rand = comp.rand, |
| ... | ... | @@ -973,6 +990,7 @@ fn buildSharedLib( |
| 973 | 990 | .stage1_is_dummy_so = true, |
| 974 | 991 | .version_script = map_file_path, |
| 975 | 992 | .override_soname = override_soname, |
| 993 | .c_source_files = &c_source_files, |
| 976 | 994 | }); |
| 977 | 995 | defer sub_compilation.destroy(); |
| 978 | 996 | |