mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
Merge pull request #21573 from alexrp/elf-header
Some additions to `std.elf` addressing #19830, plus some zld improvements
This commit is contained in:
commit
69ce7f0e08
108
lib/std/elf.zig
108
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:
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user