| ... | @@ -1768,156 +1768,332 @@ pub const DynamicLinker = struct { | ... | @@ -1768,156 +1768,332 @@ pub const DynamicLinker = struct { |
| 1768 | return std.mem.eql(u8, lhs.buffer[0..lhs.len], rhs.buffer[0..rhs.len]); | 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 { | 1771 | pub fn standard(cpu: Cpu, os: Os, abi: Abi) DynamicLinker { |
| 1772 | return if (abi.isAndroid()) initFmt("/system/bin/linker{s}", .{ | 1772 | return switch (os.tag) { |
| 1773 | if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else "", | 1773 | .fuchsia => init("ld.so.1"), // Fuchsia is unusual in that `DT_INTERP` is just a basename. |
| 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"), | | |
| 1791 | | 1774 | |
| 1792 | .aarch64 => init("/lib/ld-linux-aarch64.so.1"), | 1775 | .haiku => init("/system/runtime_loader"), |
| 1793 | .aarch64_be => init("/lib/ld-linux-aarch64_be.so.1"), | 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 | .arm, | 1791 | .arm, |
| 1796 | .armeb, | 1792 | .armeb, |
| 1797 | .thumb, | 1793 | .thumb, |
| 1798 | .thumbeb, | 1794 | .thumbeb, |
| 1799 | => initFmt("/lib/ld-linux{s}.so.3", .{switch (abi.floatAbi()) { | 1795 | .avr, |
| 1800 | .hard => "-armhf", | 1796 | .bpfel, |
| 1801 | else => "", | 1797 | .bpfeb, |
| 1802 | }}) catch unreachable, | 1798 | .csky, |
| 1803 | | 1799 | .hexagon, |
| 1804 | .loongarch64 => init("/lib64/ld-linux-loongarch-lp64d.so.1"), | 1800 | .kalimba, |
| 1805 | | 1801 | .lanai, |
| | 1802 | .loongarch32, |
| | 1803 | .loongarch64, |
| | 1804 | .m68k, |
| 1806 | .mips, | 1805 | .mips, |
| 1807 | .mipsel, | 1806 | .mipsel, |
| 1808 | .mips64, | 1807 | .mips64, |
| 1809 | .mips64el, | 1808 | .mips64el, |
| 1810 | => initFmt("/lib{s}/{s}", .{ | 1809 | .msp430, |
| 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, | | |
| 1840 | .nvptx, | 1810 | .nvptx, |
| 1841 | .nvptx64, | 1811 | .nvptx64, |
| 1842 | .spu_2, | 1812 | .powerpc, |
| 1843 | .avr, | 1813 | .powerpcle, |
| | 1814 | .powerpc64, |
| | 1815 | .powerpc64le, |
| | 1816 | .propeller1, |
| | 1817 | .propeller2, |
| | 1818 | .riscv32, |
| | 1819 | .riscv64, |
| | 1820 | .s390x, |
| | 1821 | .sparc, |
| | 1822 | .sparc64, |
| 1844 | .spirv, | 1823 | .spirv, |
| 1845 | .spirv32, | 1824 | .spirv32, |
| 1846 | .spirv64, | 1825 | .spirv64, |
| 1847 | .propeller1, | 1826 | .spu_2, |
| 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, | | |
| 1862 | .ve, | 1827 | .ve, |
| 1863 | .loongarch32, | 1828 | .wasm32, |
| | 1829 | .wasm64, |
| | 1830 | .xcore, |
| 1864 | .xtensa, | 1831 | .xtensa, |
| 1865 | => none, | 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 | .bridgeos, | 2042 | .bridgeos, |
| 1869 | .driverkit, | 2043 | .driverkit, |
| 1870 | .ios, | 2044 | .ios, |
| 1871 | .tvos, | | |
| 1872 | .watchos, | | |
| 1873 | .macos, | 2045 | .macos, |
| | 2046 | .tvos, |
| 1874 | .visionos, | 2047 | .visionos, |
| | 2048 | .watchos, |
| 1875 | => init("/usr/lib/dyld"), | 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 | // Operating systems in this list have been verified as not having a standard | 2055 | // Operating systems in this list have been verified as not having a standard |
| 1880 | // dynamic linker path. | 2056 | // dynamic linker path. |
| 1881 | .freestanding, | 2057 | .freestanding, |
| | 2058 | .other, |
| | 2059 | |
| | 2060 | .contiki, |
| | 2061 | .elfiamcu, |
| | 2062 | .hermit, |
| | 2063 | |
| | 2064 | .aix, |
| | 2065 | .plan9, |
| | 2066 | .rtems, |
| | 2067 | .zos, |
| | 2068 | |
| 1882 | .uefi, | 2069 | .uefi, |
| 1883 | .windows, | 2070 | .windows, |
| | 2071 | |
| 1884 | .emscripten, | 2072 | .emscripten, |
| 1885 | .wasi, | 2073 | .wasi, |
| | 2074 | |
| | 2075 | .amdhsa, |
| | 2076 | .amdpal, |
| | 2077 | .cuda, |
| | 2078 | .mesa3d, |
| | 2079 | .nvcl, |
| 1886 | .opencl, | 2080 | .opencl, |
| 1887 | .opengl, | 2081 | .opengl, |
| 1888 | .vulkan, | 2082 | .vulkan, |
| 1889 | .other, | | |
| 1890 | .plan9, | | |
| 1891 | => none, | 2083 | => none, |
| 1892 | | 2084 | |
| 1893 | // TODO revisit when multi-arch for Haiku is available | | |
| 1894 | .haiku => init("/system/runtime_loader"), | | |
| 1895 | | | |
| 1896 | // TODO go over each item in this list and either move it to the above list, or | 2085 | // TODO go over each item in this list and either move it to the above list, or |
| 1897 | // implement the standard dynamic linker path code for it. | 2086 | // implement the standard dynamic linker path code for it. |
| 1898 | .fuchsia, | | |
| 1899 | .ps3, | 2087 | .ps3, |
| 1900 | .zos, | | |
| 1901 | .rtems, | | |
| 1902 | .aix, | | |
| 1903 | .cuda, | | |
| 1904 | .nvcl, | | |
| 1905 | .amdhsa, | | |
| 1906 | .ps4, | 2088 | .ps4, |
| 1907 | .ps5, | 2089 | .ps5, |
| 1908 | .elfiamcu, | | |
| 1909 | .mesa3d, | | |
| 1910 | .contiki, | | |
| 1911 | .amdpal, | | |
| 1912 | .hermit, | | |
| 1913 | .hurd, | | |
| 1914 | => none, | 2090 | => none, |
| 1915 | }; | 2091 | } catch unreachable; |
| 1916 | } | 2092 | } |
| 1917 | }; | 2093 | }; |
| 1918 | | 2094 | |
| 1919 | pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { | 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 | pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { | 2099 | pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { |