Skip to content

lib/std/elf.zig: use Word-sized enum for Phdr.p_type fields #23178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 1 addition & 35 deletions lib/std/Build/Step/CheckObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2012,7 +2012,7 @@ const ElfDumper = struct {

for (ctx.phdrs, 0..) |phdr, phndx| {
try writer.print("phdr {d}\n", .{phndx});
try writer.print("type {s}\n", .{fmtPhType(phdr.p_type)});
try writer.print("type {s}\n", .{phdr.p_type});
try writer.print("vaddr {x}\n", .{phdr.p_vaddr});
try writer.print("paddr {x}\n", .{phdr.p_paddr});
try writer.print("offset {x}\n", .{phdr.p_offset});
Expand Down Expand Up @@ -2371,40 +2371,6 @@ const ElfDumper = struct {
};
try writer.writeAll(name);
}

fn fmtPhType(ph_type: u32) std.fmt.Formatter(formatPhType) {
return .{ .data = ph_type };
}

fn formatPhType(
ph_type: u32,
comptime unused_fmt_string: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = unused_fmt_string;
_ = options;
const p_type = switch (ph_type) {
elf.PT_NULL => "NULL",
elf.PT_LOAD => "LOAD",
elf.PT_DYNAMIC => "DYNAMIC",
elf.PT_INTERP => "INTERP",
elf.PT_NOTE => "NOTE",
elf.PT_SHLIB => "SHLIB",
elf.PT_PHDR => "PHDR",
elf.PT_TLS => "TLS",
elf.PT_NUM => "NUM",
elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME",
elf.PT_GNU_STACK => "GNU_STACK",
elf.PT_GNU_RELRO => "GNU_RELRO",
else => if (elf.PT_LOOS <= ph_type and ph_type < elf.PT_HIOS) {
return try writer.print("LOOS+0x{x}", .{ph_type - elf.PT_LOOS});
} else if (elf.PT_LOPROC <= ph_type and ph_type < elf.PT_HIPROC) {
return try writer.print("LOPROC+0x{x}", .{ph_type - elf.PT_LOPROC});
} else "UNKNOWN",
};
try writer.writeAll(p_type);
}
};

const WasmDumper = struct {
Expand Down
116 changes: 75 additions & 41 deletions lib/std/elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -284,45 +284,6 @@ pub const VER_FLG_BASE = 1;
/// Weak version identifier
pub const VER_FLG_WEAK = 2;

/// Program header table entry unused
pub const PT_NULL = 0;
/// Loadable program segment
pub const PT_LOAD = 1;
/// Dynamic linking information
pub const PT_DYNAMIC = 2;
/// Program interpreter
pub const PT_INTERP = 3;
/// Auxiliary information
pub const PT_NOTE = 4;
/// Reserved
pub const PT_SHLIB = 5;
/// Entry for header table itself
pub const PT_PHDR = 6;
/// Thread-local storage segment
pub const PT_TLS = 7;
/// Number of defined types
pub const PT_NUM = 8;
/// Start of OS-specific
pub const PT_LOOS = 0x60000000;
/// GCC .eh_frame_hdr segment
pub const PT_GNU_EH_FRAME = 0x6474e550;
/// Indicates stack executability
pub const PT_GNU_STACK = 0x6474e551;
/// Read-only after relocation
pub const PT_GNU_RELRO = 0x6474e552;
pub const PT_LOSUNW = 0x6ffffffa;
/// Sun specific segment
pub const PT_SUNWBSS = 0x6ffffffa;
/// Stack segment
pub const PT_SUNWSTACK = 0x6ffffffb;
pub const PT_HISUNW = 0x6fffffff;
/// End of OS-specific
pub const PT_HIOS = 0x6fffffff;
/// Start of processor-specific
pub const PT_LOPROC = 0x70000000;
/// End of processor-specific
pub const PT_HIPROC = 0x7fffffff;

/// Section header table entry unused
pub const SHT_NULL = 0;
/// Program data
Expand Down Expand Up @@ -758,8 +719,81 @@ pub const Elf64_Ehdr = extern struct {
e_shnum: Half,
e_shstrndx: Half,
};

pub const PhdrType = enum(Word) {
/// Program header table entry unused
null = 0,
/// Loadable program segment
load = 1,
/// Dynamic linking information
dynamic = 2,
/// Program interpreter
interp = 3,
/// Auxiliary information
note = 4,
/// Reserved
shlib = 5,
/// Entry for header table itself
phdr = 6,
/// Thread-local storage segment
tls = 7,
/// Number of defined types
num = 8,
/// Start of OS-specific
loos = 0x60000000,
/// GCC .eh_frame_hdr segment
gnu_eh_frame = 0x6474e550,
/// Indicates stack executability
gnu_stack = 0x6474e551,
/// Read-only after relocation
gnu_relro = 0x6474e552,
/// Sun specific segment
sunwbss = 0x6ffffffa,
/// Stack segment
sunwstack = 0x6ffffffb,
/// End of OS-specific
hios = 0x6fffffff,
/// Start of processor-specific
loproc = 0x70000000,
/// End of processor-specific
hiproc = 0x7fffffff,
_,

pub const losunw = PhdrType.sunwbss;
pub const hisunw = PhdrType.hios;

pub fn format(
ph_type: PhdrType,
comptime _: []const u8,
_: std.fmt.FormatOptions,
writer: anytype,
) !void {
const as_int = @intFromEnum(ph_type);
const display: []const u8 = switch (ph_type) {
.null => "NULL",
.load => "LOAD",
.dynamic => "DYNAMIC",
.interp => "INTERP",
.note => "NOTE",
.shlib => "SHLIB",
.phdr => "PHDR",
.tls => "TLS",
.num => "NUM",
.gnu_eh_frame => "GNU_EH_FRAME",
.gnu_relro => "GNU_RELRO",
else => if (@intFromEnum(PhdrType.loos) <= as_int and as_int < @intFromEnum(PhdrType.hios)) {
return try writer.print("LOOS+0x{x}", .{as_int - @intFromEnum(PhdrType.loos)});
} else if (@intFromEnum(PhdrType.loproc) <= as_int and as_int < @intFromEnum(PhdrType.hiproc)) {
return try writer.print("LOPROC+0x{x}", .{as_int - @intFromEnum(PhdrType.loproc)});
} else "UNKNOWN",
};

try writer.writeAll(display);
}
};

pub const Elf32_Phdr = extern struct {
p_type: Word,
p_type: PhdrType,
p_offset: Elf32_Off,
p_vaddr: Elf32_Addr,
p_paddr: Elf32_Addr,
Expand All @@ -769,7 +803,7 @@ pub const Elf32_Phdr = extern struct {
p_align: Word,
};
pub const Elf64_Phdr = extern struct {
p_type: Word,
p_type: PhdrType,
p_flags: Word,
p_offset: Elf64_Off,
p_vaddr: Elf64_Addr,
Expand Down
44 changes: 22 additions & 22 deletions src/link/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ pub fn createEmpty(
.memsz = reserved,
})).toOptional();
self.phdr_indexes.table_load = (try self.addPhdr(.{
.type = elf.PT_LOAD,
.type = .load,
.flags = elf.PF_R,
.@"align" = self.page_size,
.addr = self.image_base,
Expand Down Expand Up @@ -566,7 +566,7 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) !?u64 {
}

for (self.phdrs.items) |phdr| {
if (phdr.p_type != elf.PT_LOAD) continue;
if (phdr.p_type != .load) continue;
const increased_size = padToIdeal(phdr.p_filesz);
const test_end = phdr.p_offset +| increased_size;
if (start < test_end) {
Expand Down Expand Up @@ -2992,13 +2992,13 @@ fn setHashSections(self: *Elf) !void {

fn phdrRank(phdr: elf.Elf64_Phdr) u8 {
return switch (phdr.p_type) {
elf.PT_NULL => 0,
elf.PT_PHDR => 1,
elf.PT_INTERP => 2,
elf.PT_LOAD => 3,
elf.PT_DYNAMIC, elf.PT_TLS => 4,
elf.PT_GNU_EH_FRAME => 5,
elf.PT_GNU_STACK => 6,
.null => 0,
.phdr => 1,
.interp => 2,
.load => 3,
.dynamic, .tls => 4,
.gnu_eh_frame => 5,
.gnu_stack => 6,
else => 7,
};
}
Expand Down Expand Up @@ -4213,7 +4213,7 @@ pub fn isEffectivelyDynLib(self: Elf) bool {
}

fn getPhdr(self: *Elf, opts: struct {
type: u32 = 0,
type: elf.PhdrType = .null,
flags: u32 = 0,
}) OptionalProgramHeaderIndex {
for (self.phdrs.items, 0..) |phdr, phndx| {
Expand All @@ -4227,7 +4227,7 @@ fn getPhdr(self: *Elf, opts: struct {
}

fn addPhdr(self: *Elf, opts: struct {
type: u32 = 0,
type: elf.PhdrType = .null,
flags: u32 = 0,
@"align": u64 = 0,
offset: u64 = 0,
Expand Down Expand Up @@ -4750,20 +4750,20 @@ fn formatPhdr(
if (write) flags[1] = 'W';
if (read) flags[2] = 'R';
const p_type = switch (phdr.p_type) {
elf.PT_LOAD => "LOAD",
elf.PT_TLS => "TLS",
elf.PT_GNU_EH_FRAME => "GNU_EH_FRAME",
elf.PT_GNU_STACK => "GNU_STACK",
elf.PT_DYNAMIC => "DYNAMIC",
elf.PT_INTERP => "INTERP",
elf.PT_NULL => "NULL",
elf.PT_PHDR => "PHDR",
elf.PT_NOTE => "NOTE",
.load => "LOAD",
.tls => "TLS",
.gnu_eh_frame => "GNU_EH_FRAME",
.gnu_stack => "GNU_STACK",
.dynamic => "DYNAMIC",
.interp => "INTERP",
.null => "NULL",
.phdr => "PHDR",
.note => "NOTE",
else => "UNKNOWN",
};
try writer.print("{s} : {s} : @{x} ({x}) : align({x}) : filesz({x}) : memsz({x})", .{
p_type, flags, phdr.p_offset, phdr.p_vaddr,
phdr.p_align, phdr.p_filesz, phdr.p_memsz,
@tagName(p_type), flags, phdr.p_offset, phdr.p_vaddr,
phdr.p_align, phdr.p_filesz, phdr.p_memsz,
});
}

Expand Down
Loading