diff --git a/lib/std/elf.zig b/lib/std/elf.zig index d92973c314..d948e8fcc5 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -453,18 +453,27 @@ 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; }; /// All integers are native endian. pub const Header = struct { - endian: std.builtin.Endian, - machine: EM, is_64: bool, + endian: std.builtin.Endian, + os_abi: OSABI, + abi_version: u8, + type: ET, + machine: EM, entry: u64, phoff: u64, shoff: u64, @@ -501,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, @@ -508,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); @@ -520,9 +539,12 @@ pub const Header = struct { } else hdr32.e_machine; return @as(Header, .{ - .endian = endian, - .machine = machine, .is_64 = is_64, + .endian = endian, + .os_abi = os_abi, + .abi_version = abi_version, + .type = @"type", + .machine = machine, .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), @@ -637,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); @@ -649,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 { @@ -657,21 +679,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; @@ -1094,6 +1119,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: diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 919122799f..00ea5a778d 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2584,11 +2584,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); diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 13a33b4cfa..9e2dbf6007 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