| ... | ... | @@ -820,55 +820,87 @@ pub fn abiAndDynamicLinkerFromFile( |
| 820 | 820 | while (it.next()) |rpath| { |
| 821 | 821 | if (glibcVerFromRPath(rpath)) |ver| { |
| 822 | 822 | result.target.os.version_range.linux.glibc = ver; |
| 823 | | break; |
| 823 | return result; |
| 824 | 824 | } else |err| switch (err) { |
| 825 | 825 | error.GLibCNotFound => continue, |
| 826 | 826 | else => |e| return e, |
| 827 | 827 | } |
| 828 | 828 | } |
| 829 | | } else if (result.dynamic_linker.get()) |dl_path| glibc_ver: { |
| 830 | | // There is no DT_RUNPATH so we try to find libc.so.6 inside the same |
| 831 | | // directory as the dynamic linker. |
| 832 | | if (fs.path.dirname(dl_path)) |rpath| { |
| 833 | | if (glibcVerFromRPath(rpath)) |ver| { |
| 834 | | result.target.os.version_range.linux.glibc = ver; |
| 835 | | break :glibc_ver; |
| 836 | | } else |err| switch (err) { |
| 837 | | error.GLibCNotFound => {}, |
| 838 | | else => |e| return e, |
| 839 | | } |
| 840 | | } |
| 829 | } |
| 830 | } |
| 841 | 831 | |
| 842 | | // So far, no luck. Next we try to see if the information is |
| 843 | | // present in the symlink data for the dynamic linker path. |
| 844 | | var link_buf: [std.os.PATH_MAX]u8 = undefined; |
| 845 | | const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) { |
| 846 | | error.NameTooLong => unreachable, |
| 847 | | error.InvalidUtf8 => unreachable, // Windows only |
| 848 | | error.BadPathName => unreachable, // Windows only |
| 849 | | error.UnsupportedReparsePointType => unreachable, // Windows only |
| 850 | | |
| 851 | | error.AccessDenied, |
| 852 | | error.FileNotFound, |
| 853 | | error.NotLink, |
| 854 | | error.NotDir, |
| 855 | | => break :glibc_ver, |
| 856 | | |
| 857 | | error.SystemResources, |
| 858 | | error.FileSystem, |
| 859 | | error.SymLinkLoop, |
| 860 | | error.Unexpected, |
| 861 | | => |e| return e, |
| 862 | | }; |
| 863 | | result.target.os.version_range.linux.glibc = glibcVerFromLinkName( |
| 864 | | fs.path.basename(link_name), |
| 865 | | "ld-", |
| 866 | | ) catch |err| switch (err) { |
| 867 | | error.UnrecognizedGnuLibCFileName, |
| 868 | | error.InvalidGnuLibCVersion, |
| 869 | | => break :glibc_ver, |
| 870 | | }; |
| 832 | if (result.dynamic_linker.get()) |dl_path| glibc_ver: { |
| 833 | // There is no DT_RUNPATH so we try to find libc.so.6 inside the same |
| 834 | // directory as the dynamic linker. |
| 835 | if (fs.path.dirname(dl_path)) |rpath| { |
| 836 | if (glibcVerFromRPath(rpath)) |ver| { |
| 837 | result.target.os.version_range.linux.glibc = ver; |
| 838 | return result; |
| 839 | } else |err| switch (err) { |
| 840 | error.GLibCNotFound => {}, |
| 841 | else => |e| return e, |
| 842 | } |
| 871 | 843 | } |
| 844 | |
| 845 | // So far, no luck. Next we try to see if the information is |
| 846 | // present in the symlink data for the dynamic linker path. |
| 847 | var link_buf: [std.os.PATH_MAX]u8 = undefined; |
| 848 | const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) { |
| 849 | error.NameTooLong => unreachable, |
| 850 | error.InvalidUtf8 => unreachable, // Windows only |
| 851 | error.BadPathName => unreachable, // Windows only |
| 852 | error.UnsupportedReparsePointType => unreachable, // Windows only |
| 853 | |
| 854 | error.AccessDenied, |
| 855 | error.FileNotFound, |
| 856 | error.NotLink, |
| 857 | error.NotDir, |
| 858 | => break :glibc_ver, |
| 859 | |
| 860 | error.SystemResources, |
| 861 | error.FileSystem, |
| 862 | error.SymLinkLoop, |
| 863 | error.Unexpected, |
| 864 | => |e| return e, |
| 865 | }; |
| 866 | result.target.os.version_range.linux.glibc = glibcVerFromLinkName( |
| 867 | fs.path.basename(link_name), |
| 868 | "ld-", |
| 869 | ) catch |err| switch (err) { |
| 870 | error.UnrecognizedGnuLibCFileName, |
| 871 | error.InvalidGnuLibCVersion, |
| 872 | => break :glibc_ver, |
| 873 | }; |
| 874 | return result; |
| 875 | } |
| 876 | |
| 877 | // Nothing worked so far. Finally we fall back to hard-coded search paths. |
| 878 | // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`. |
| 879 | var path_buf: [std.os.PATH_MAX]u8 = undefined; |
| 880 | var index: usize = 0; |
| 881 | const prefix = "/lib/"; |
| 882 | const cpu_arch = @tagName(result.target.cpu.arch); |
| 883 | const os_tag = @tagName(result.target.os.tag); |
| 884 | const abi = @tagName(result.target.abi); |
| 885 | mem.copy(u8, path_buf[index..], prefix); |
| 886 | index += prefix.len; |
| 887 | mem.copy(u8, path_buf[index..], cpu_arch); |
| 888 | index += cpu_arch.len; |
| 889 | path_buf[index] = '-'; |
| 890 | index += 1; |
| 891 | mem.copy(u8, path_buf[index..], os_tag); |
| 892 | index += os_tag.len; |
| 893 | path_buf[index] = '-'; |
| 894 | index += 1; |
| 895 | mem.copy(u8, path_buf[index..], abi); |
| 896 | index += abi.len; |
| 897 | const rpath = path_buf[0..index]; |
| 898 | if (glibcVerFromRPath(rpath)) |ver| { |
| 899 | result.target.os.version_range.linux.glibc = ver; |
| 900 | return result; |
| 901 | } else |err| switch (err) { |
| 902 | error.GLibCNotFound => {}, |
| 903 | else => |e| return e, |
| 872 | 904 | } |
| 873 | 905 | } |
| 874 | 906 | |