From 496a067d3f7c2d48c68ff0adae389994e68b70ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 03:53:27 +0200 Subject: [PATCH 1/7] std.elf: Define ET.(LOOS,HIOS) constants. --- lib/std/elf.zig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index d92973c314cb9fa866525d999386dc761ebfd2fd..f09bbb63fb4374e74325af18ae1020a5eb764d19 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -453,10 +453,16 @@ pub const ET = enum(u16) { /// Core file CORE = 4, + /// Beginning of OS-specific codes + pub const LOOS = 0xfe00; + + /// End of OS-specific codes + pub const HIOS = 0xfeff; + /// Beginning of processor-specific codes pub const LOPROC = 0xff00; - /// Processor-specific + /// End of processor-specific codes pub const HIPROC = 0xffff; }; -- 2.54.0 From 5db04e05951d46709dba0316bc7676a19399337e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 03:53:58 +0200 Subject: [PATCH 2/7] std.elf: Define EI_(OSABI,ABIVERSION,PAD) constants. --- lib/std/elf.zig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index f09bbb63fb4374e74325af18ae1020a5eb764d19..2215c1341b9d99c041e2780c64c10f14092924b9 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -663,21 +663,24 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 { } } -pub const EI_NIDENT = 16; - -pub const EI_CLASS = 4; pub const ELFCLASSNONE = 0; pub const ELFCLASS32 = 1; pub const ELFCLASS64 = 2; pub const ELFCLASSNUM = 3; -pub const EI_DATA = 5; pub const ELFDATANONE = 0; pub const ELFDATA2LSB = 1; pub const ELFDATA2MSB = 2; pub const ELFDATANUM = 3; +pub const EI_CLASS = 4; +pub const EI_DATA = 5; pub const EI_VERSION = 6; +pub const EI_OSABI = 7; +pub const EI_ABIVERSION = 8; +pub const EI_PAD = 9; + +pub const EI_NIDENT = 16; pub const Elf32_Half = u16; pub const Elf64_Half = u16; -- 2.54.0 From 604ff131dd79064535f82b453c5dcb648add171d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 03:54:22 +0200 Subject: [PATCH 3/7] std.elf: Add OSABI enum sourced from binutils. --- lib/std/elf.zig | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index 2215c1341b9d99c041e2780c64c10f14092924b9..0f8d4d10f082e2634ba77e3a08cf21a4f92c88be 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -1103,6 +1103,57 @@ pub const Addr = switch (@sizeOf(usize)) { }; pub const Half = u16; +pub const OSABI = enum(u8) { + /// UNIX System V ABI + NONE = 0, + /// HP-UX operating system + HPUX = 1, + /// NetBSD + NETBSD = 2, + /// GNU (Hurd/Linux) + GNU = 3, + /// Solaris + SOLARIS = 6, + /// AIX + AIX = 7, + /// IRIX + IRIX = 8, + /// FreeBSD + FREEBSD = 9, + /// TRU64 UNIX + TRU64 = 10, + /// Novell Modesto + MODESTO = 11, + /// OpenBSD + OPENBSD = 12, + /// OpenVMS + OPENVMS = 13, + /// Hewlett-Packard Non-Stop Kernel + NSK = 14, + /// AROS + AROS = 15, + /// FenixOS + FENIXOS = 16, + /// Nuxi CloudABI + CLOUDABI = 17, + /// Stratus Technologies OpenVOS + OPENVOS = 18, + /// NVIDIA CUDA architecture + CUDA = 51, + /// AMD HSA Runtime + AMDGPU_HSA = 64, + /// AMD PAL Runtime + AMDGPU_PAL = 65, + /// AMD Mesa3D Runtime + AMDGPU_MESA3D = 66, + /// ARM + ARM = 97, + /// Standalone (embedded) application + STANDALONE = 255, + + _, +}; + /// Machine architectures. /// /// See current registered ELF machine architectures at: -- 2.54.0 From 9bbfc864af0311403aa19538999b170dbd35b7dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 03:54:42 +0200 Subject: [PATCH 4/7] std.elf: Parse and make available some extra fields on Header. Closes #19830. --- lib/std/elf.zig | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index 0f8d4d10f082e2634ba77e3a08cf21a4f92c88be..0fedffdd14f0accaac4d6586f7c6030faa284a2b 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -468,9 +468,12 @@ pub const ET = enum(u16) { /// All integers are native endian. pub const Header = struct { + is_64: bool, endian: std.builtin.Endian, + os_abi: OSABI, + abi_version: u8, + type: ET, machine: EM, - is_64: bool, entry: u64, phoff: u64, shoff: u64, @@ -507,6 +510,12 @@ pub const Header = struct { if (!mem.eql(u8, hdr32.e_ident[0..4], MAGIC)) return error.InvalidElfMagic; if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion; + const is_64 = switch (hdr32.e_ident[EI_CLASS]) { + ELFCLASS32 => false, + ELFCLASS64 => true, + else => return error.InvalidElfClass, + }; + const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) { ELFDATA2LSB => .little, ELFDATA2MSB => .big, @@ -514,11 +523,15 @@ pub const Header = struct { }; const need_bswap = endian != native_endian; - const is_64 = switch (hdr32.e_ident[EI_CLASS]) { - ELFCLASS32 => false, - ELFCLASS64 => true, - else => return error.InvalidElfClass, - }; + const os_abi: OSABI = @enumFromInt(hdr32.e_ident[EI_OSABI]); + + // The meaning of this value depends on `os_abi` so just make it available as `u8`. + const abi_version = hdr32.e_ident[EI_ABIVERSION]; + + const @"type" = if (need_bswap) blk: { + const value = @intFromEnum(hdr32.e_type); + break :blk @as(ET, @enumFromInt(@byteSwap(value))); + } else hdr32.e_type; const machine = if (need_bswap) blk: { const value = @intFromEnum(hdr32.e_machine); @@ -526,9 +539,12 @@ pub const Header = struct { } else hdr32.e_machine; return @as(Header, .{ + .is_64 = is_64, .endian = endian, + .os_abi = os_abi, + .abi_version = abi_version, + .type = @"type", .machine = machine, - .is_64 = is_64, .entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry), .phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff), .shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff), -- 2.54.0 From b569ead29ea4459d0d363bf5a878ddb53f8f14f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 04:32:42 +0200 Subject: [PATCH 5/7] std.elf: Make int() and int32() functions private. These have no callers outside std.elf. Even if the standard library should provide functions like these, std.elf is probably not the place, given how general they are. --- lib/std/elf.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/std/elf.zig b/lib/std/elf.zig index 0fedffdd14f0accaac4d6586f7c6030faa284a2b..d948e8fcc5c784fcb7331dbb29b21e8c7294a92c 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -659,7 +659,7 @@ pub fn SectionHeaderIterator(comptime ParseSource: anytype) type { }; } -pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) { +fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) { if (is_64) { if (need_bswap) { return @byteSwap(int_64); @@ -671,7 +671,7 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @Typ } } -pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 { +fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 { if (need_bswap) { return @byteSwap(int_32); } else { -- 2.54.0 From 125c043abc208842cd7e1deb188136600eb5c3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 04:34:32 +0200 Subject: [PATCH 6/7] link.Elf: Set EI_OSABI value correctly depending on target arch/OS. --- src/link/Elf.zig | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index f610f2519d4e6137c72bc148b485d1b282685d18..52929aa7a61eb9ebae733f064c4fbc20e23d9774 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2589,11 +2589,28 @@ pub fn writeElfHeader(self: *Elf) !void { hdr_buf[index] = 1; // ELF version index += 1; - // OS ABI, often set to 0 regardless of target platform + hdr_buf[index] = @intFromEnum(@as(elf.OSABI, switch (target.cpu.arch) { + .amdgcn => switch (target.os.tag) { + .amdhsa => .AMDGPU_HSA, + .amdpal => .AMDGPU_PAL, + .mesa3d => .AMDGPU_MESA3D, + else => .NONE, + }, + .msp430 => .STANDALONE, + else => switch (target.os.tag) { + .freebsd, .ps4 => .FREEBSD, + .hermit => .STANDALONE, + .illumos, .solaris => .SOLARIS, + .openbsd => .OPENBSD, + else => .NONE, + }, + })); + index += 1; + // ABI Version, possibly used by glibc but not by static executables // padding - @memset(hdr_buf[index..][0..9], 0); - index += 9; + @memset(hdr_buf[index..][0..8], 0); + index += 8; assert(index == 16); -- 2.54.0 From 710a3b37e2f51010dcb37e4d39ba9ac77eddbd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 1 Oct 2024 02:06:24 +0200 Subject: [PATCH 7/7] link.MachO: Add exhaustive handling for all Apple target triples. --- src/link/MachO.zig | 47 ++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 13a33b4cfa6cd8a3585c4364fcb54ad10408d1a2..9e2dbf6007e70734691505d13808010a79cd1738 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3542,8 +3542,8 @@ pub fn requiresCodeSig(self: MachO) bool { const target = self.getTarget(); return switch (target.cpu.arch) { .aarch64 => switch (target.os.tag) { - .macos => true, - .watchos, .tvos, .ios, .visionos => target.abi == .simulator, + .bridgeos, .driverkit, .macos => true, + .ios, .tvos, .visionos, .watchos => target.abi == .simulator, else => false, }, .x86_64 => false, @@ -4172,36 +4172,38 @@ pub const Platform = struct { const cmd = lc.cast(macho.build_version_command).?; return .{ .os_tag = switch (cmd.platform) { - .MACOS => .macos, + .BRIDGEOS => .bridgeos, + .DRIVERKIT => .driverkit, .IOS, .IOSSIMULATOR => .ios, - .TVOS, .TVOSSIMULATOR => .tvos, - .WATCHOS, .WATCHOSSIMULATOR => .watchos, .MACCATALYST => .ios, + .MACOS => .macos, + .TVOS, .TVOSSIMULATOR => .tvos, .VISIONOS, .VISIONOSSIMULATOR => .visionos, + .WATCHOS, .WATCHOSSIMULATOR => .watchos, else => @panic("TODO"), }, .abi = switch (cmd.platform) { .MACCATALYST => .macabi, .IOSSIMULATOR, .TVOSSIMULATOR, - .WATCHOSSIMULATOR, .VISIONOSSIMULATOR, + .WATCHOSSIMULATOR, => .simulator, else => .none, }, .version = appleVersionToSemanticVersion(cmd.minos), }; }, - .VERSION_MIN_MACOSX, .VERSION_MIN_IPHONEOS, + .VERSION_MIN_MACOSX, .VERSION_MIN_TVOS, .VERSION_MIN_WATCHOS, => { const cmd = lc.cast(macho.version_min_command).?; return .{ .os_tag = switch (lc.cmd()) { - .VERSION_MIN_MACOSX => .macos, .VERSION_MIN_IPHONEOS => .ios, + .VERSION_MIN_MACOSX => .macos, .VERSION_MIN_TVOS => .tvos, .VERSION_MIN_WATCHOS => .watchos, else => unreachable, @@ -4228,15 +4230,17 @@ pub const Platform = struct { pub fn toApplePlatform(plat: Platform) macho.PLATFORM { return switch (plat.os_tag) { - .macos => .MACOS, + .bridgeos => .BRIDGEOS, + .driverkit => .DRIVERKIT, .ios => switch (plat.abi) { - .simulator => .IOSSIMULATOR, .macabi => .MACCATALYST, + .simulator => .IOSSIMULATOR, else => .IOS, }, + .macos => .MACOS, .tvos => if (plat.abi == .simulator) .TVOSSIMULATOR else .TVOS, - .watchos => if (plat.abi == .simulator) .WATCHOSSIMULATOR else .WATCHOS, .visionos => if (plat.abi == .simulator) .VISIONOSSIMULATOR else .VISIONOS, + .watchos => if (plat.abi == .simulator) .WATCHOSSIMULATOR else .WATCHOS, else => unreachable, }; } @@ -4305,15 +4309,18 @@ const SupportedPlatforms = struct { // Source: https://github.com/apple-oss-distributions/ld64/blob/59a99ab60399c5e6c49e6945a9e1049c42b71135/src/ld/PlatformSupport.cpp#L52 // zig fmt: off const supported_platforms = [_]SupportedPlatforms{ - .{ .macos, .none, 0xA0E00, 0xA0800 }, - .{ .ios, .none, 0xC0000, 0x70000 }, - .{ .tvos, .none, 0xC0000, 0x70000 }, - .{ .watchos, .none, 0x50000, 0x20000 }, - .{ .visionos, .none, 0x10000, 0x10000 }, - .{ .ios, .simulator, 0xD0000, 0x80000 }, - .{ .tvos, .simulator, 0xD0000, 0x80000 }, - .{ .watchos, .simulator, 0x60000, 0x20000 }, - .{ .visionos, .simulator, 0x10000, 0x10000 }, + .{ .bridgeos, .none, 0x010000, 0x010000 }, + .{ .driverkit, .none, 0x130000, 0x130000 }, + .{ .ios, .none, 0x0C0000, 0x070000 }, + .{ .ios, .macabi, 0x0D0000, 0x0D0000 }, + .{ .ios, .simulator, 0x0D0000, 0x080000 }, + .{ .macos, .none, 0x0A0E00, 0x0A0800 }, + .{ .tvos, .none, 0x0C0000, 0x070000 }, + .{ .tvos, .simulator, 0x0D0000, 0x080000 }, + .{ .visionos, .none, 0x010000, 0x010000 }, + .{ .visionos, .simulator, 0x010000, 0x010000 }, + .{ .watchos, .none, 0x050000, 0x020000 }, + .{ .watchos, .simulator, 0x060000, 0x020000 }, }; // zig fmt: on -- 2.54.0