structstd.elf.Header[src]

All integers are native endian.

Fields

is_64: bool
endian: std.builtin.Endian
os_abi: OSABI
abi_version: u8
type: ET
machine: EM
entry: u64
phoff: u64
shoff: u64
phentsize: u16
phnum: u16
shentsize: u16
shnum: u16
shstrndx: u16

Functions

Functionprogram_header_iterator[src]

pub fn program_header_iterator(self: Header, parse_source: anytype) ProgramHeaderIterator(@TypeOf(parse_source))

Parameters

self: Header

Source Code

Source code
pub fn program_header_iterator(self: Header, parse_source: anytype) ProgramHeaderIterator(@TypeOf(parse_source)) {
    return ProgramHeaderIterator(@TypeOf(parse_source)){
        .elf_header = self,
        .parse_source = parse_source,
    };
}

Functionsection_header_iterator[src]

pub fn section_header_iterator(self: Header, parse_source: anytype) SectionHeaderIterator(@TypeOf(parse_source))

Parameters

self: Header

Source Code

Source code
pub fn section_header_iterator(self: Header, parse_source: anytype) SectionHeaderIterator(@TypeOf(parse_source)) {
    return SectionHeaderIterator(@TypeOf(parse_source)){
        .elf_header = self,
        .parse_source = parse_source,
    };
}

Functionread[src]

pub fn read(parse_source: anytype) !Header

Source Code

Source code
pub fn read(parse_source: anytype) !Header {
    var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined;
    try parse_source.seekableStream().seekTo(0);
    try parse_source.reader().readNoEof(&hdr_buf);
    return Header.parse(&hdr_buf);
}

Functionparse[src]

pub fn parse(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header

Parameters

hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8

Source Code

Source code
pub fn parse(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header {
    const hdr32 = @as(*const Elf32_Ehdr, @ptrCast(hdr_buf));
    const hdr64 = @as(*const Elf64_Ehdr, @ptrCast(hdr_buf));
    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,
        else => return error.InvalidElfEndian,
    };
    const need_bswap = endian != native_endian;

    // Converting integers to exhaustive enums using `@enumFromInt` could cause a panic.
    comptime assert(!@typeInfo(OSABI).@"enum".is_exhaustive);
    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: {
        comptime assert(!@typeInfo(ET).@"enum".is_exhaustive);
        const value = @intFromEnum(hdr32.e_type);
        break :blk @as(ET, @enumFromInt(@byteSwap(value)));
    } else hdr32.e_type;

    const machine = if (need_bswap) blk: {
        comptime assert(!@typeInfo(EM).@"enum".is_exhaustive);
        const value = @intFromEnum(hdr32.e_machine);
        break :blk @as(EM, @enumFromInt(@byteSwap(value)));
    } 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,
        .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),
        .phentsize = int(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize),
        .phnum = int(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum),
        .shentsize = int(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize),
        .shnum = int(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum),
        .shstrndx = int(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx),
    });
}

Source Code

Source code
pub const Header = struct {
    is_64: bool,
    endian: std.builtin.Endian,
    os_abi: OSABI,
    abi_version: u8,
    type: ET,
    machine: EM,
    entry: u64,
    phoff: u64,
    shoff: u64,
    phentsize: u16,
    phnum: u16,
    shentsize: u16,
    shnum: u16,
    shstrndx: u16,

    pub fn program_header_iterator(self: Header, parse_source: anytype) ProgramHeaderIterator(@TypeOf(parse_source)) {
        return ProgramHeaderIterator(@TypeOf(parse_source)){
            .elf_header = self,
            .parse_source = parse_source,
        };
    }

    pub fn section_header_iterator(self: Header, parse_source: anytype) SectionHeaderIterator(@TypeOf(parse_source)) {
        return SectionHeaderIterator(@TypeOf(parse_source)){
            .elf_header = self,
            .parse_source = parse_source,
        };
    }

    pub fn read(parse_source: anytype) !Header {
        var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined;
        try parse_source.seekableStream().seekTo(0);
        try parse_source.reader().readNoEof(&hdr_buf);
        return Header.parse(&hdr_buf);
    }

    pub fn parse(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header {
        const hdr32 = @as(*const Elf32_Ehdr, @ptrCast(hdr_buf));
        const hdr64 = @as(*const Elf64_Ehdr, @ptrCast(hdr_buf));
        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,
            else => return error.InvalidElfEndian,
        };
        const need_bswap = endian != native_endian;

        // Converting integers to exhaustive enums using `@enumFromInt` could cause a panic.
        comptime assert(!@typeInfo(OSABI).@"enum".is_exhaustive);
        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: {
            comptime assert(!@typeInfo(ET).@"enum".is_exhaustive);
            const value = @intFromEnum(hdr32.e_type);
            break :blk @as(ET, @enumFromInt(@byteSwap(value)));
        } else hdr32.e_type;

        const machine = if (need_bswap) blk: {
            comptime assert(!@typeInfo(EM).@"enum".is_exhaustive);
            const value = @intFromEnum(hdr32.e_machine);
            break :blk @as(EM, @enumFromInt(@byteSwap(value)));
        } 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,
            .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),
            .phentsize = int(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize),
            .phnum = int(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum),
            .shentsize = int(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize),
            .shnum = int(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum),
            .shstrndx = int(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx),
        });
    }
}