authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-10-06 09:17:57+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-06 09:17:57+02:00
log516cb5a5e86bb9d30c16d0692e3b9eb706812b42
tree9807f4c7395b0bdbe23e98056bdf923dcbc3fa15
parentac247c9943385dce3d90647e26387914f65979b9
parent9a5b0a67621d163fb2616acbfab16388d3173564
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21037 from alexrp/target-dyld

`std.Target`: Rewrite DynamicLinker.standard() and fill in some missing details.

2 files changed, 277 insertions(+), 101 deletions(-)

lib/std/Target.zig+276-100
......@@ -1768,156 +1768,332 @@ pub const DynamicLinker = struct {
17681768 return std.mem.eql(u8, lhs.buffer[0..lhs.len], rhs.buffer[0..rhs.len]);
17691769 }
17701770
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.
17911774
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 }),
17941784
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,
17951791 .arm,
17961792 .armeb,
17971793 .thumb,
17981794 .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,
18061805 .mips,
18071806 .mipsel,
18081807 .mips64,
18091808 .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,
18401810 .nvptx,
18411811 .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,
18441823 .spirv,
18451824 .spirv32,
18461825 .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,
18621827 .ve,
1863 .loongarch32,
1828 .wasm32,
1829 .wasm64,
1830 .xcore,
18641831 .xtensa,
18651832 => none,
18661833 },
18671834
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
18682042 .bridgeos,
18692043 .driverkit,
18702044 .ios,
1871 .tvos,
1872 .watchos,
18732045 .macos,
2046 .tvos,
18742047 .visionos,
2048 .watchos,
18752049 => init("/usr/lib/dyld"),
18762050
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 ""}),
18782054
18792055 // Operating systems in this list have been verified as not having a standard
18802056 // dynamic linker path.
18812057 .freestanding,
2058 .other,
2059
2060 .contiki,
2061 .elfiamcu,
2062 .hermit,
2063
2064 .aix,
2065 .plan9,
2066 .rtems,
2067 .zos,
2068
18822069 .uefi,
18832070 .windows,
2071
18842072 .emscripten,
18852073 .wasi,
2074
2075 .amdhsa,
2076 .amdpal,
2077 .cuda,
2078 .mesa3d,
2079 .nvcl,
18862080 .opencl,
18872081 .opengl,
18882082 .vulkan,
1889 .other,
1890 .plan9,
18912083 => none,
18922084
1893 // TODO revisit when multi-arch for Haiku is available
1894 .haiku => init("/system/runtime_loader"),
1895
18962085 // TODO go over each item in this list and either move it to the above list, or
18972086 // implement the standard dynamic linker path code for it.
1898 .fuchsia,
18992087 .ps3,
1900 .zos,
1901 .rtems,
1902 .aix,
1903 .cuda,
1904 .nvcl,
1905 .amdhsa,
19062088 .ps4,
19072089 .ps5,
1908 .elfiamcu,
1909 .mesa3d,
1910 .contiki,
1911 .amdpal,
1912 .hermit,
1913 .hurd,
19142090 => none,
1915 };
2091 } catch unreachable;
19162092 }
19172093};
19182094
19192095pub 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);
19212097}
19222098
19232099pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 {
lib/std/zig/system.zig+1-1
......@@ -1152,7 +1152,7 @@ fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Quer
11521152 .abi = abi,
11531153 .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
11541154 .dynamic_linker = if (query.dynamic_linker.get() == null)
1155 Target.DynamicLinker.standard(cpu, os.tag, abi)
1155 Target.DynamicLinker.standard(cpu, os, abi)
11561156 else
11571157 query.dynamic_linker,
11581158 };