| ... | ... | @@ -1768,156 +1768,332 @@ pub const DynamicLinker = struct { |
| 1768 | 1768 | return std.mem.eql(u8, lhs.buffer[0..lhs.len], rhs.buffer[0..rhs.len]); |
| 1769 | 1769 | } |
| 1770 | 1770 | |
| 1771 | | pub fn standard(cpu: Cpu, os_tag: Os.Tag, abi: Abi) DynamicLinker { |
| 1772 | | return if (abi.isAndroid()) initFmt("/system/bin/linker{s}", .{ |
| 1773 | | if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else "", |
| 1774 | | }) catch unreachable else if (abi.isMusl()) return initFmt("/lib/ld-musl-{s}{s}.so.1", .{ |
| 1775 | | @tagName(switch (cpu.arch) { |
| 1776 | | .thumb => .arm, |
| 1777 | | .thumbeb => .armeb, |
| 1778 | | else => cpu.arch, |
| 1779 | | }), |
| 1780 | | if (cpu.arch.isArmOrThumb() and abi.floatAbi() == .hard) "hf" else "", |
| 1781 | | }) catch unreachable else switch (os_tag) { |
| 1782 | | .freebsd => init("/libexec/ld-elf.so.1"), |
| 1783 | | .netbsd => init("/libexec/ld.elf_so"), |
| 1784 | | .openbsd => init("/usr/libexec/ld.so"), |
| 1785 | | .dragonfly => init("/libexec/ld-elf.so.2"), |
| 1786 | | .solaris, .illumos => init("/lib/64/ld.so.1"), |
| 1787 | | .linux => switch (cpu.arch) { |
| 1788 | | .x86, |
| 1789 | | .sparc, |
| 1790 | | => init("/lib/ld-linux.so.2"), |
| 1771 | pub fn standard(cpu: Cpu, os: Os, abi: Abi) DynamicLinker { |
| 1772 | return switch (os.tag) { |
| 1773 | .fuchsia => init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename. |
| 1791 | 1774 | |
| 1792 | | .aarch64 => init("/lib/ld-linux-aarch64.so.1"), |
| 1793 | | .aarch64_be => init("/lib/ld-linux-aarch64_be.so.1"), |
| 1775 | .haiku => init("/system/runtime_loader"), |
| 1776 | |
| 1777 | .hurd => switch (cpu.arch) { |
| 1778 | .aarch64, |
| 1779 | .aarch64_be, |
| 1780 | => |arch| initFmt("/lib/ld-{s}{s}.so.1", .{ |
| 1781 | @tagName(arch), |
| 1782 | if (abi == .gnuilp32) "_ilp32" else "", |
| 1783 | }), |
| 1794 | 1784 | |
| 1785 | .x86 => init("/lib/ld.so.1"), |
| 1786 | .x86_64 => initFmt("/lib/ld-{s}.so.1", .{if (abi == .gnux32) "x32" else "x86-64"}), |
| 1787 | |
| 1788 | // These are unsupported by Hurd/glibc. |
| 1789 | .amdgcn, |
| 1790 | .arc, |
| 1795 | 1791 | .arm, |
| 1796 | 1792 | .armeb, |
| 1797 | 1793 | .thumb, |
| 1798 | 1794 | .thumbeb, |
| 1799 | | => initFmt("/lib/ld-linux{s}.so.3", .{switch (abi.floatAbi()) { |
| 1800 | | .hard => "-armhf", |
| 1801 | | else => "", |
| 1802 | | }}) catch unreachable, |
| 1803 | | |
| 1804 | | .loongarch64 => init("/lib64/ld-linux-loongarch-lp64d.so.1"), |
| 1805 | | |
| 1795 | .avr, |
| 1796 | .bpfel, |
| 1797 | .bpfeb, |
| 1798 | .csky, |
| 1799 | .hexagon, |
| 1800 | .kalimba, |
| 1801 | .lanai, |
| 1802 | .loongarch32, |
| 1803 | .loongarch64, |
| 1804 | .m68k, |
| 1806 | 1805 | .mips, |
| 1807 | 1806 | .mipsel, |
| 1808 | 1807 | .mips64, |
| 1809 | 1808 | .mips64el, |
| 1810 | | => initFmt("/lib{s}/{s}", .{ |
| 1811 | | switch (abi) { |
| 1812 | | .gnuabin32, .gnux32 => "32", |
| 1813 | | .gnuabi64 => "64", |
| 1814 | | else => "", |
| 1815 | | }, |
| 1816 | | if (mips.featureSetHas(cpu.features, .nan2008)) |
| 1817 | | "ld-linux-mipsn8.so.1" |
| 1818 | | else |
| 1819 | | "ld.so.1", |
| 1820 | | }) catch unreachable, |
| 1821 | | |
| 1822 | | .powerpc, .powerpcle => init("/lib/ld.so.1"), |
| 1823 | | .powerpc64, .powerpc64le => init("/lib64/ld64.so.2"), |
| 1824 | | .s390x => init("/lib64/ld64.so.1"), |
| 1825 | | .sparc64 => init("/lib64/ld-linux.so.2"), |
| 1826 | | .x86_64 => init(switch (abi) { |
| 1827 | | .gnux32 => "/libx32/ld-linux-x32.so.2", |
| 1828 | | else => "/lib64/ld-linux-x86-64.so.2", |
| 1829 | | }), |
| 1830 | | |
| 1831 | | .riscv32 => init("/lib/ld-linux-riscv32-ilp32d.so.1"), |
| 1832 | | .riscv64 => init("/lib/ld-linux-riscv64-lp64d.so.1"), |
| 1833 | | |
| 1834 | | // Architectures in this list have been verified as not having a standard |
| 1835 | | // dynamic linker path. |
| 1836 | | .wasm32, |
| 1837 | | .wasm64, |
| 1838 | | .bpfel, |
| 1839 | | .bpfeb, |
| 1809 | .msp430, |
| 1840 | 1810 | .nvptx, |
| 1841 | 1811 | .nvptx64, |
| 1842 | | .spu_2, |
| 1843 | | .avr, |
| 1812 | .powerpc, |
| 1813 | .powerpcle, |
| 1814 | .powerpc64, |
| 1815 | .powerpc64le, |
| 1816 | .propeller1, |
| 1817 | .propeller2, |
| 1818 | .riscv32, |
| 1819 | .riscv64, |
| 1820 | .s390x, |
| 1821 | .sparc, |
| 1822 | .sparc64, |
| 1844 | 1823 | .spirv, |
| 1845 | 1824 | .spirv32, |
| 1846 | 1825 | .spirv64, |
| 1847 | | .propeller1, |
| 1848 | | .propeller2, |
| 1849 | | => none, |
| 1850 | | |
| 1851 | | // TODO go over each item in this list and either move it to the above list, or |
| 1852 | | // implement the standard dynamic linker path code for it. |
| 1853 | | .arc, |
| 1854 | | .csky, |
| 1855 | | .hexagon, |
| 1856 | | .m68k, |
| 1857 | | .msp430, |
| 1858 | | .amdgcn, |
| 1859 | | .xcore, |
| 1860 | | .kalimba, |
| 1861 | | .lanai, |
| 1826 | .spu_2, |
| 1862 | 1827 | .ve, |
| 1863 | | .loongarch32, |
| 1828 | .wasm32, |
| 1829 | .wasm64, |
| 1830 | .xcore, |
| 1864 | 1831 | .xtensa, |
| 1865 | 1832 | => none, |
| 1866 | 1833 | }, |
| 1867 | 1834 | |
| 1835 | .linux => if (abi.isAndroid()) |
| 1836 | initFmt("/system/bin/linker{s}", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else ""}) |
| 1837 | else if (abi.isMusl()) |
| 1838 | switch (cpu.arch) { |
| 1839 | .arm, |
| 1840 | .armeb, |
| 1841 | .thumb, |
| 1842 | .thumbeb, |
| 1843 | .aarch64, |
| 1844 | .aarch64_be, |
| 1845 | .loongarch64, |
| 1846 | .m68k, |
| 1847 | .powerpc, |
| 1848 | .powerpc64, |
| 1849 | .powerpc64le, |
| 1850 | .riscv32, |
| 1851 | .riscv64, |
| 1852 | .s390x, |
| 1853 | .x86, |
| 1854 | .x86_64, |
| 1855 | => |arch| initFmt("/lib/ld-musl-{s}{s}.so.1", .{ |
| 1856 | switch (arch) { |
| 1857 | .thumb => "arm", |
| 1858 | .thumbeb => "armeb", |
| 1859 | .x86 => "i386", |
| 1860 | .x86_64 => if (abi == .muslx32) "x32" else "x86_64", |
| 1861 | else => @tagName(arch), |
| 1862 | }, |
| 1863 | switch (arch) { |
| 1864 | .arm, .armeb, .thumb, .thumbeb => if (abi.floatAbi() == .hard) "hf" else "", |
| 1865 | .aarch64, .aarch64_be => if (abi == .gnuilp32) "_ilp32" else "", |
| 1866 | .riscv32, .riscv64 => if (std.Target.riscv.featureSetHas(cpu.features, .d)) |
| 1867 | "" |
| 1868 | else if (std.Target.riscv.featureSetHas(cpu.features, .f)) |
| 1869 | "-sp" |
| 1870 | else |
| 1871 | "-sf", |
| 1872 | else => if (abi.floatAbi() == .soft) "-sf" else "", |
| 1873 | }, |
| 1874 | }), |
| 1875 | |
| 1876 | // The naming scheme for MIPS is a bit irregular. |
| 1877 | .mips, |
| 1878 | .mipsel, |
| 1879 | .mips64, |
| 1880 | .mips64el, |
| 1881 | => |arch| initFmt("/lib/ld-musl-mips{s}{s}{s}{s}.so.1", .{ |
| 1882 | if (arch.isMIPS64()) "64" else "", // TODO: `n32` ABI support in LLVM 20. |
| 1883 | if (mips.featureSetHas(cpu.features, if (arch.isMIPS64()) .mips64r6 else .mips32r6)) "r6" else "", |
| 1884 | if (arch.endian() == .little) "el" else "", |
| 1885 | if (abi.floatAbi() == .soft) "-sf" else "", |
| 1886 | }), |
| 1887 | |
| 1888 | // These are unsupported by musl. |
| 1889 | .amdgcn, |
| 1890 | .arc, |
| 1891 | .avr, |
| 1892 | .csky, |
| 1893 | .bpfel, |
| 1894 | .bpfeb, |
| 1895 | .hexagon, |
| 1896 | .kalimba, |
| 1897 | .lanai, |
| 1898 | .loongarch32, |
| 1899 | .msp430, |
| 1900 | .nvptx, |
| 1901 | .nvptx64, |
| 1902 | .powerpcle, |
| 1903 | .propeller1, |
| 1904 | .propeller2, |
| 1905 | .sparc, |
| 1906 | .sparc64, |
| 1907 | .spirv, |
| 1908 | .spirv32, |
| 1909 | .spirv64, |
| 1910 | .spu_2, |
| 1911 | .ve, |
| 1912 | .wasm32, |
| 1913 | .wasm64, |
| 1914 | .xcore, |
| 1915 | .xtensa, |
| 1916 | => none, |
| 1917 | } |
| 1918 | else if (abi.isGnu()) |
| 1919 | switch (cpu.arch) { |
| 1920 | // TODO: `eb` architecture support. |
| 1921 | // TODO: `700` ABI support. |
| 1922 | .arc => init("/lib/ld-linux-arc.so.2"), |
| 1923 | |
| 1924 | // TODO: OABI support (`/lib/ld-linux.so.2`). |
| 1925 | .arm, |
| 1926 | .armeb, |
| 1927 | .thumb, |
| 1928 | .thumbeb, |
| 1929 | => initFmt("/lib/ld-linux{s}.so.3", .{if (abi.floatAbi() == .hard) "-armhf" else ""}), |
| 1930 | |
| 1931 | .aarch64, |
| 1932 | .aarch64_be, |
| 1933 | => |arch| initFmt("/lib/ld-linux-{s}{s}.so.1", .{ |
| 1934 | @tagName(arch), |
| 1935 | if (abi == .gnuilp32) "_ilp32" else "", |
| 1936 | }), |
| 1937 | |
| 1938 | // TODO: `-be` architecture support. |
| 1939 | .csky => initFmt("/lib/ld-linux-cskyv2{s}.so.1", .{if (abi.floatAbi() == .hard) "-hf" else ""}), |
| 1940 | |
| 1941 | .loongarch64 => initFmt("/lib64/ld-linux-loongarch-{s}.so.1", .{switch (abi) { |
| 1942 | .gnuf32 => "lp64f", |
| 1943 | .gnusf => "lp64s", |
| 1944 | else => "lp64d", |
| 1945 | }}), |
| 1946 | |
| 1947 | .m68k => init("/lib/ld.so.1"), |
| 1948 | |
| 1949 | .mips, |
| 1950 | .mipsel, |
| 1951 | .mips64, |
| 1952 | .mips64el, |
| 1953 | => initFmt("/lib{s}/ld{s}.so.1", .{ |
| 1954 | switch (abi) { |
| 1955 | .gnuabin32 => "32", |
| 1956 | .gnuabi64 => "64", |
| 1957 | else => "", |
| 1958 | }, |
| 1959 | if (mips.featureSetHas(cpu.features, .nan2008)) "-linux-mipsn8" else "", |
| 1960 | }), |
| 1961 | |
| 1962 | .powerpc => init("/lib/ld.so.1"), |
| 1963 | // TODO: ELFv2 ABI opt-in support. |
| 1964 | .powerpc64 => init("/lib64/ld64.so.1"), |
| 1965 | .powerpc64le => init("/lib64/ld64.so.2"), |
| 1966 | |
| 1967 | .riscv32, |
| 1968 | .riscv64, |
| 1969 | => |arch| initFmt("/lib/ld-linux-{s}-{s}{s}.so.1", .{ |
| 1970 | @tagName(arch), |
| 1971 | switch (arch) { |
| 1972 | .riscv32 => "ilp32", |
| 1973 | .riscv64 => "lp64", |
| 1974 | else => unreachable, |
| 1975 | }, |
| 1976 | if (riscv.featureSetHas(cpu.features, .d)) |
| 1977 | "d" |
| 1978 | else if (riscv.featureSetHas(cpu.features, .f)) |
| 1979 | "f" |
| 1980 | else |
| 1981 | "", |
| 1982 | }), |
| 1983 | |
| 1984 | .s390x => init("/lib/ld64.so.1"), |
| 1985 | |
| 1986 | .sparc => init("/lib/ld-linux.so.2"), |
| 1987 | .sparc64 => init("/lib64/ld-linux.so.2"), |
| 1988 | |
| 1989 | .x86 => init("/lib/ld-linux.so.2"), |
| 1990 | .x86_64 => init(if (abi == .gnux32) "/libx32/ld-linux-x32.so.2" else "/lib64/ld-linux-x86-64.so.2"), |
| 1991 | |
| 1992 | .xtensa => init("/lib/ld.so.1"), |
| 1993 | |
| 1994 | // These are unsupported by glibc. |
| 1995 | .amdgcn, |
| 1996 | .avr, |
| 1997 | .bpfeb, |
| 1998 | .bpfel, |
| 1999 | .hexagon, |
| 2000 | .kalimba, |
| 2001 | .lanai, |
| 2002 | .loongarch32, |
| 2003 | .msp430, |
| 2004 | .nvptx, |
| 2005 | .nvptx64, |
| 2006 | .powerpcle, |
| 2007 | .propeller1, |
| 2008 | .propeller2, |
| 2009 | .spirv, |
| 2010 | .spirv32, |
| 2011 | .spirv64, |
| 2012 | .spu_2, |
| 2013 | .ve, |
| 2014 | .wasm32, |
| 2015 | .wasm64, |
| 2016 | .xcore, |
| 2017 | => none, |
| 2018 | } |
| 2019 | else |
| 2020 | none, // Not a known Linux libc. |
| 2021 | |
| 2022 | .serenity => init("/usr/lib/Loader.so"), |
| 2023 | |
| 2024 | .dragonfly => initFmt("{s}/libexec/ld-elf.so.2", .{ |
| 2025 | if (os.version_range.semver.isAtLeast(.{ .major = 3, .minor = 8, .patch = 0 }) orelse false) |
| 2026 | "" |
| 2027 | else |
| 2028 | "/usr", |
| 2029 | }), |
| 2030 | |
| 2031 | .freebsd => initFmt("{s}/libexec/ld-elf.so.1", .{ |
| 2032 | if (os.version_range.semver.isAtLeast(.{ .major = 6, .minor = 0, .patch = 0 }) orelse false) |
| 2033 | "" |
| 2034 | else |
| 2035 | "/usr", |
| 2036 | }), |
| 2037 | |
| 2038 | .netbsd => init("/libexec/ld.elf_so"), |
| 2039 | |
| 2040 | .openbsd => init("/usr/libexec/ld.so"), |
| 2041 | |
| 1868 | 2042 | .bridgeos, |
| 1869 | 2043 | .driverkit, |
| 1870 | 2044 | .ios, |
| 1871 | | .tvos, |
| 1872 | | .watchos, |
| 1873 | 2045 | .macos, |
| 2046 | .tvos, |
| 1874 | 2047 | .visionos, |
| 2048 | .watchos, |
| 1875 | 2049 | => init("/usr/lib/dyld"), |
| 1876 | 2050 | |
| 1877 | | .serenity => init("/usr/lib/Loader.so"), |
| 2051 | .illumos, |
| 2052 | .solaris, |
| 2053 | => initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64/" else ""}), |
| 1878 | 2054 | |
| 1879 | 2055 | // Operating systems in this list have been verified as not having a standard |
| 1880 | 2056 | // dynamic linker path. |
| 1881 | 2057 | .freestanding, |
| 2058 | .other, |
| 2059 | |
| 2060 | .contiki, |
| 2061 | .elfiamcu, |
| 2062 | .hermit, |
| 2063 | |
| 2064 | .aix, |
| 2065 | .plan9, |
| 2066 | .rtems, |
| 2067 | .zos, |
| 2068 | |
| 1882 | 2069 | .uefi, |
| 1883 | 2070 | .windows, |
| 2071 | |
| 1884 | 2072 | .emscripten, |
| 1885 | 2073 | .wasi, |
| 2074 | |
| 2075 | .amdhsa, |
| 2076 | .amdpal, |
| 2077 | .cuda, |
| 2078 | .mesa3d, |
| 2079 | .nvcl, |
| 1886 | 2080 | .opencl, |
| 1887 | 2081 | .opengl, |
| 1888 | 2082 | .vulkan, |
| 1889 | | .other, |
| 1890 | | .plan9, |
| 1891 | 2083 | => none, |
| 1892 | 2084 | |
| 1893 | | // TODO revisit when multi-arch for Haiku is available |
| 1894 | | .haiku => init("/system/runtime_loader"), |
| 1895 | | |
| 1896 | 2085 | // TODO go over each item in this list and either move it to the above list, or |
| 1897 | 2086 | // implement the standard dynamic linker path code for it. |
| 1898 | | .fuchsia, |
| 1899 | 2087 | .ps3, |
| 1900 | | .zos, |
| 1901 | | .rtems, |
| 1902 | | .aix, |
| 1903 | | .cuda, |
| 1904 | | .nvcl, |
| 1905 | | .amdhsa, |
| 1906 | 2088 | .ps4, |
| 1907 | 2089 | .ps5, |
| 1908 | | .elfiamcu, |
| 1909 | | .mesa3d, |
| 1910 | | .contiki, |
| 1911 | | .amdpal, |
| 1912 | | .hermit, |
| 1913 | | .hurd, |
| 1914 | 2090 | => none, |
| 1915 | | }; |
| 2091 | } catch unreachable; |
| 1916 | 2092 | } |
| 1917 | 2093 | }; |
| 1918 | 2094 | |
| 1919 | 2095 | pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { |
| 1920 | | return DynamicLinker.standard(target.cpu, target.os.tag, target.abi); |
| 2096 | return DynamicLinker.standard(target.cpu, target.os, target.abi); |
| 1921 | 2097 | } |
| 1922 | 2098 | |
| 1923 | 2099 | pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { |