authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-10-03 15:19:58+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-03 15:19:58+02:00
log69ce7f0e085b5fb3bf7356e9999940c60c79cfe2
tree564b875b1be006deeb3931d4a9252a836b195e44
parent3bcdca07a37d29256c56c2b681d43d74cd0f88b5
parent710a3b37e2f51010dcb37e4d39ba9ac77eddbd82
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21573 from alexrp/elf-header

Some additions to `std.elf` addressing #19830, plus some zld improvements

3 files changed, 137 insertions(+), 37 deletions(-)

lib/std/elf.zig+90-14
...@@ -453,18 +453,27 @@ pub const ET = enum(u16) {...@@ -453,18 +453,27 @@ pub const ET = enum(u16) {
453 /// Core file453 /// Core file
454 CORE = 4,454 CORE = 4,
455455
456 /// Beginning of OS-specific codes
457 pub const LOOS = 0xfe00;
458
459 /// End of OS-specific codes
460 pub const HIOS = 0xfeff;
461
456 /// Beginning of processor-specific codes462 /// Beginning of processor-specific codes
457 pub const LOPROC = 0xff00;463 pub const LOPROC = 0xff00;
458464
459 /// Processor-specific465 /// End of processor-specific codes
460 pub const HIPROC = 0xffff;466 pub const HIPROC = 0xffff;
461};467};
462468
463/// All integers are native endian.469/// All integers are native endian.
464pub const Header = struct {470pub const Header = struct {
471 is_64: bool,
465 endian: std.builtin.Endian,472 endian: std.builtin.Endian,
473 os_abi: OSABI,
474 abi_version: u8,
475 type: ET,
466 machine: EM,476 machine: EM,
467 is_64: bool,
468 entry: u64,477 entry: u64,
469 phoff: u64,478 phoff: u64,
470 shoff: u64,479 shoff: u64,
...@@ -501,6 +510,12 @@ pub const Header = struct {...@@ -501,6 +510,12 @@ pub const Header = struct {
501 if (!mem.eql(u8, hdr32.e_ident[0..4], MAGIC)) return error.InvalidElfMagic;510 if (!mem.eql(u8, hdr32.e_ident[0..4], MAGIC)) return error.InvalidElfMagic;
502 if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion;511 if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion;
503512
513 const is_64 = switch (hdr32.e_ident[EI_CLASS]) {
514 ELFCLASS32 => false,
515 ELFCLASS64 => true,
516 else => return error.InvalidElfClass,
517 };
518
504 const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) {519 const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) {
505 ELFDATA2LSB => .little,520 ELFDATA2LSB => .little,
506 ELFDATA2MSB => .big,521 ELFDATA2MSB => .big,
...@@ -508,11 +523,15 @@ pub const Header = struct {...@@ -508,11 +523,15 @@ pub const Header = struct {
508 };523 };
509 const need_bswap = endian != native_endian;524 const need_bswap = endian != native_endian;
510525
511 const is_64 = switch (hdr32.e_ident[EI_CLASS]) {526 const os_abi: OSABI = @enumFromInt(hdr32.e_ident[EI_OSABI]);
512 ELFCLASS32 => false,527
513 ELFCLASS64 => true,528 // The meaning of this value depends on `os_abi` so just make it available as `u8`.
514 else => return error.InvalidElfClass,529 const abi_version = hdr32.e_ident[EI_ABIVERSION];
515 };530
531 const @"type" = if (need_bswap) blk: {
532 const value = @intFromEnum(hdr32.e_type);
533 break :blk @as(ET, @enumFromInt(@byteSwap(value)));
534 } else hdr32.e_type;
516535
517 const machine = if (need_bswap) blk: {536 const machine = if (need_bswap) blk: {
518 const value = @intFromEnum(hdr32.e_machine);537 const value = @intFromEnum(hdr32.e_machine);
...@@ -520,9 +539,12 @@ pub const Header = struct {...@@ -520,9 +539,12 @@ pub const Header = struct {
520 } else hdr32.e_machine;539 } else hdr32.e_machine;
521540
522 return @as(Header, .{541 return @as(Header, .{
542 .is_64 = is_64,
523 .endian = endian,543 .endian = endian,
544 .os_abi = os_abi,
545 .abi_version = abi_version,
546 .type = @"type",
524 .machine = machine,547 .machine = machine,
525 .is_64 = is_64,
526 .entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry),548 .entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry),
527 .phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff),549 .phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff),
528 .shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff),550 .shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff),
...@@ -637,7 +659,7 @@ pub fn SectionHeaderIterator(comptime ParseSource: anytype) type {...@@ -637,7 +659,7 @@ pub fn SectionHeaderIterator(comptime ParseSource: anytype) type {
637 };659 };
638}660}
639661
640pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {662fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
641 if (is_64) {663 if (is_64) {
642 if (need_bswap) {664 if (need_bswap) {
643 return @byteSwap(int_64);665 return @byteSwap(int_64);
...@@ -649,7 +671,7 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @Typ...@@ -649,7 +671,7 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @Typ
649 }671 }
650}672}
651673
652pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {674fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
653 if (need_bswap) {675 if (need_bswap) {
654 return @byteSwap(int_32);676 return @byteSwap(int_32);
655 } else {677 } else {
...@@ -657,21 +679,24 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {...@@ -657,21 +679,24 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
657 }679 }
658}680}
659681
660pub const EI_NIDENT = 16;
661
662pub const EI_CLASS = 4;
663pub const ELFCLASSNONE = 0;682pub const ELFCLASSNONE = 0;
664pub const ELFCLASS32 = 1;683pub const ELFCLASS32 = 1;
665pub const ELFCLASS64 = 2;684pub const ELFCLASS64 = 2;
666pub const ELFCLASSNUM = 3;685pub const ELFCLASSNUM = 3;
667686
668pub const EI_DATA = 5;
669pub const ELFDATANONE = 0;687pub const ELFDATANONE = 0;
670pub const ELFDATA2LSB = 1;688pub const ELFDATA2LSB = 1;
671pub const ELFDATA2MSB = 2;689pub const ELFDATA2MSB = 2;
672pub const ELFDATANUM = 3;690pub const ELFDATANUM = 3;
673691
692pub const EI_CLASS = 4;
693pub const EI_DATA = 5;
674pub const EI_VERSION = 6;694pub const EI_VERSION = 6;
695pub const EI_OSABI = 7;
696pub const EI_ABIVERSION = 8;
697pub const EI_PAD = 9;
698
699pub const EI_NIDENT = 16;
675700
676pub const Elf32_Half = u16;701pub const Elf32_Half = u16;
677pub const Elf64_Half = u16;702pub const Elf64_Half = u16;
...@@ -1094,6 +1119,57 @@ pub const Addr = switch (@sizeOf(usize)) {...@@ -1094,6 +1119,57 @@ pub const Addr = switch (@sizeOf(usize)) {
1094};1119};
1095pub const Half = u16;1120pub const Half = u16;
10961121
1122pub const OSABI = enum(u8) {
1123 /// UNIX System V ABI
1124 NONE = 0,
1125 /// HP-UX operating system
1126 HPUX = 1,
1127 /// NetBSD
1128 NETBSD = 2,
1129 /// GNU (Hurd/Linux)
1130 GNU = 3,
1131 /// Solaris
1132 SOLARIS = 6,
1133 /// AIX
1134 AIX = 7,
1135 /// IRIX
1136 IRIX = 8,
1137 /// FreeBSD
1138 FREEBSD = 9,
1139 /// TRU64 UNIX
1140 TRU64 = 10,
1141 /// Novell Modesto
1142 MODESTO = 11,
1143 /// OpenBSD
1144 OPENBSD = 12,
1145 /// OpenVMS
1146 OPENVMS = 13,
1147 /// Hewlett-Packard Non-Stop Kernel
1148 NSK = 14,
1149 /// AROS
1150 AROS = 15,
1151 /// FenixOS
1152 FENIXOS = 16,
1153 /// Nuxi CloudABI
1154 CLOUDABI = 17,
1155 /// Stratus Technologies OpenVOS
1156 OPENVOS = 18,
1157 /// NVIDIA CUDA architecture
1158 CUDA = 51,
1159 /// AMD HSA Runtime
1160 AMDGPU_HSA = 64,
1161 /// AMD PAL Runtime
1162 AMDGPU_PAL = 65,
1163 /// AMD Mesa3D Runtime
1164 AMDGPU_MESA3D = 66,
1165 /// ARM
1166 ARM = 97,
1167 /// Standalone (embedded) application
1168 STANDALONE = 255,
1169
1170 _,
1171};
1172
1097/// Machine architectures.1173/// Machine architectures.
1098///1174///
1099/// See current registered ELF machine architectures at:1175/// See current registered ELF machine architectures at:
src/link/Elf.zig+20-3
...@@ -2584,11 +2584,28 @@ pub fn writeElfHeader(self: *Elf) !void {...@@ -2584,11 +2584,28 @@ pub fn writeElfHeader(self: *Elf) !void {
2584 hdr_buf[index] = 1; // ELF version2584 hdr_buf[index] = 1; // ELF version
2585 index += 1;2585 index += 1;
25862586
2587 // OS ABI, often set to 0 regardless of target platform2587 hdr_buf[index] = @intFromEnum(@as(elf.OSABI, switch (target.cpu.arch) {
2588 .amdgcn => switch (target.os.tag) {
2589 .amdhsa => .AMDGPU_HSA,
2590 .amdpal => .AMDGPU_PAL,
2591 .mesa3d => .AMDGPU_MESA3D,
2592 else => .NONE,
2593 },
2594 .msp430 => .STANDALONE,
2595 else => switch (target.os.tag) {
2596 .freebsd, .ps4 => .FREEBSD,
2597 .hermit => .STANDALONE,
2598 .illumos, .solaris => .SOLARIS,
2599 .openbsd => .OPENBSD,
2600 else => .NONE,
2601 },
2602 }));
2603 index += 1;
2604
2588 // ABI Version, possibly used by glibc but not by static executables2605 // ABI Version, possibly used by glibc but not by static executables
2589 // padding2606 // padding
2590 @memset(hdr_buf[index..][0..9], 0);2607 @memset(hdr_buf[index..][0..8], 0);
2591 index += 9;2608 index += 8;
25922609
2593 assert(index == 16);2610 assert(index == 16);
25942611
src/link/MachO.zig+27-20
...@@ -3542,8 +3542,8 @@ pub fn requiresCodeSig(self: MachO) bool {...@@ -3542,8 +3542,8 @@ pub fn requiresCodeSig(self: MachO) bool {
3542 const target = self.getTarget();3542 const target = self.getTarget();
3543 return switch (target.cpu.arch) {3543 return switch (target.cpu.arch) {
3544 .aarch64 => switch (target.os.tag) {3544 .aarch64 => switch (target.os.tag) {
3545 .macos => true,3545 .bridgeos, .driverkit, .macos => true,
3546 .watchos, .tvos, .ios, .visionos => target.abi == .simulator,3546 .ios, .tvos, .visionos, .watchos => target.abi == .simulator,
3547 else => false,3547 else => false,
3548 },3548 },
3549 .x86_64 => false,3549 .x86_64 => false,
...@@ -4172,36 +4172,38 @@ pub const Platform = struct {...@@ -4172,36 +4172,38 @@ pub const Platform = struct {
4172 const cmd = lc.cast(macho.build_version_command).?;4172 const cmd = lc.cast(macho.build_version_command).?;
4173 return .{4173 return .{
4174 .os_tag = switch (cmd.platform) {4174 .os_tag = switch (cmd.platform) {
4175 .MACOS => .macos,4175 .BRIDGEOS => .bridgeos,
4176 .DRIVERKIT => .driverkit,
4176 .IOS, .IOSSIMULATOR => .ios,4177 .IOS, .IOSSIMULATOR => .ios,
4177 .TVOS, .TVOSSIMULATOR => .tvos,
4178 .WATCHOS, .WATCHOSSIMULATOR => .watchos,
4179 .MACCATALYST => .ios,4178 .MACCATALYST => .ios,
4179 .MACOS => .macos,
4180 .TVOS, .TVOSSIMULATOR => .tvos,
4180 .VISIONOS, .VISIONOSSIMULATOR => .visionos,4181 .VISIONOS, .VISIONOSSIMULATOR => .visionos,
4182 .WATCHOS, .WATCHOSSIMULATOR => .watchos,
4181 else => @panic("TODO"),4183 else => @panic("TODO"),
4182 },4184 },
4183 .abi = switch (cmd.platform) {4185 .abi = switch (cmd.platform) {
4184 .MACCATALYST => .macabi,4186 .MACCATALYST => .macabi,
4185 .IOSSIMULATOR,4187 .IOSSIMULATOR,
4186 .TVOSSIMULATOR,4188 .TVOSSIMULATOR,
4187 .WATCHOSSIMULATOR,
4188 .VISIONOSSIMULATOR,4189 .VISIONOSSIMULATOR,
4190 .WATCHOSSIMULATOR,
4189 => .simulator,4191 => .simulator,
4190 else => .none,4192 else => .none,
4191 },4193 },
4192 .version = appleVersionToSemanticVersion(cmd.minos),4194 .version = appleVersionToSemanticVersion(cmd.minos),
4193 };4195 };
4194 },4196 },
4195 .VERSION_MIN_MACOSX,
4196 .VERSION_MIN_IPHONEOS,4197 .VERSION_MIN_IPHONEOS,
4198 .VERSION_MIN_MACOSX,
4197 .VERSION_MIN_TVOS,4199 .VERSION_MIN_TVOS,
4198 .VERSION_MIN_WATCHOS,4200 .VERSION_MIN_WATCHOS,
4199 => {4201 => {
4200 const cmd = lc.cast(macho.version_min_command).?;4202 const cmd = lc.cast(macho.version_min_command).?;
4201 return .{4203 return .{
4202 .os_tag = switch (lc.cmd()) {4204 .os_tag = switch (lc.cmd()) {
4203 .VERSION_MIN_MACOSX => .macos,
4204 .VERSION_MIN_IPHONEOS => .ios,4205 .VERSION_MIN_IPHONEOS => .ios,
4206 .VERSION_MIN_MACOSX => .macos,
4205 .VERSION_MIN_TVOS => .tvos,4207 .VERSION_MIN_TVOS => .tvos,
4206 .VERSION_MIN_WATCHOS => .watchos,4208 .VERSION_MIN_WATCHOS => .watchos,
4207 else => unreachable,4209 else => unreachable,
...@@ -4228,15 +4230,17 @@ pub const Platform = struct {...@@ -4228,15 +4230,17 @@ pub const Platform = struct {
42284230
4229 pub fn toApplePlatform(plat: Platform) macho.PLATFORM {4231 pub fn toApplePlatform(plat: Platform) macho.PLATFORM {
4230 return switch (plat.os_tag) {4232 return switch (plat.os_tag) {
4231 .macos => .MACOS,4233 .bridgeos => .BRIDGEOS,
4234 .driverkit => .DRIVERKIT,
4232 .ios => switch (plat.abi) {4235 .ios => switch (plat.abi) {
4233 .simulator => .IOSSIMULATOR,
4234 .macabi => .MACCATALYST,4236 .macabi => .MACCATALYST,
4237 .simulator => .IOSSIMULATOR,
4235 else => .IOS,4238 else => .IOS,
4236 },4239 },
4240 .macos => .MACOS,
4237 .tvos => if (plat.abi == .simulator) .TVOSSIMULATOR else .TVOS,4241 .tvos => if (plat.abi == .simulator) .TVOSSIMULATOR else .TVOS,
4238 .watchos => if (plat.abi == .simulator) .WATCHOSSIMULATOR else .WATCHOS,
4239 .visionos => if (plat.abi == .simulator) .VISIONOSSIMULATOR else .VISIONOS,4242 .visionos => if (plat.abi == .simulator) .VISIONOSSIMULATOR else .VISIONOS,
4243 .watchos => if (plat.abi == .simulator) .WATCHOSSIMULATOR else .WATCHOS,
4240 else => unreachable,4244 else => unreachable,
4241 };4245 };
4242 }4246 }
...@@ -4305,15 +4309,18 @@ const SupportedPlatforms = struct {...@@ -4305,15 +4309,18 @@ const SupportedPlatforms = struct {
4305// Source: https://github.com/apple-oss-distributions/ld64/blob/59a99ab60399c5e6c49e6945a9e1049c42b71135/src/ld/PlatformSupport.cpp#L524309// Source: https://github.com/apple-oss-distributions/ld64/blob/59a99ab60399c5e6c49e6945a9e1049c42b71135/src/ld/PlatformSupport.cpp#L52
4306// zig fmt: off4310// zig fmt: off
4307const supported_platforms = [_]SupportedPlatforms{4311const supported_platforms = [_]SupportedPlatforms{
4308 .{ .macos, .none, 0xA0E00, 0xA0800 },4312 .{ .bridgeos, .none, 0x010000, 0x010000 },
4309 .{ .ios, .none, 0xC0000, 0x70000 },4313 .{ .driverkit, .none, 0x130000, 0x130000 },
4310 .{ .tvos, .none, 0xC0000, 0x70000 },4314 .{ .ios, .none, 0x0C0000, 0x070000 },
4311 .{ .watchos, .none, 0x50000, 0x20000 },4315 .{ .ios, .macabi, 0x0D0000, 0x0D0000 },
4312 .{ .visionos, .none, 0x10000, 0x10000 },4316 .{ .ios, .simulator, 0x0D0000, 0x080000 },
4313 .{ .ios, .simulator, 0xD0000, 0x80000 },4317 .{ .macos, .none, 0x0A0E00, 0x0A0800 },
4314 .{ .tvos, .simulator, 0xD0000, 0x80000 },4318 .{ .tvos, .none, 0x0C0000, 0x070000 },
4315 .{ .watchos, .simulator, 0x60000, 0x20000 },4319 .{ .tvos, .simulator, 0x0D0000, 0x080000 },
4316 .{ .visionos, .simulator, 0x10000, 0x10000 },4320 .{ .visionos, .none, 0x010000, 0x010000 },
4321 .{ .visionos, .simulator, 0x010000, 0x010000 },
4322 .{ .watchos, .none, 0x050000, 0x020000 },
4323 .{ .watchos, .simulator, 0x060000, 0x020000 },
4317};4324};
4318// zig fmt: on4325// zig fmt: on
43194326