mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Merge pull request #7763 from kivikakk/zig-elf-parse
std.elf: expose parsing decoupled from std.fs.File
This commit is contained in:
commit
ffb2568a9f
@ -51,9 +51,9 @@ const BinaryElfOutput = struct {
|
|||||||
.segments = ArrayList(*BinaryElfSegment).init(allocator),
|
.segments = ArrayList(*BinaryElfSegment).init(allocator),
|
||||||
.sections = ArrayList(*BinaryElfSection).init(allocator),
|
.sections = ArrayList(*BinaryElfSection).init(allocator),
|
||||||
};
|
};
|
||||||
const elf_hdr = try std.elf.readHeader(elf_file);
|
const elf_hdr = try std.elf.Header.read(&elf_file);
|
||||||
|
|
||||||
var section_headers = elf_hdr.section_header_iterator(elf_file);
|
var section_headers = elf_hdr.section_header_iterator(&elf_file);
|
||||||
while (try section_headers.next()) |section| {
|
while (try section_headers.next()) |section| {
|
||||||
if (sectionValidForOutput(section)) {
|
if (sectionValidForOutput(section)) {
|
||||||
const newSection = try allocator.create(BinaryElfSection);
|
const newSection = try allocator.create(BinaryElfSection);
|
||||||
@ -67,7 +67,7 @@ const BinaryElfOutput = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var program_headers = elf_hdr.program_header_iterator(elf_file);
|
var program_headers = elf_hdr.program_header_iterator(&elf_file);
|
||||||
while (try program_headers.next()) |phdr| {
|
while (try program_headers.next()) |phdr| {
|
||||||
if (phdr.p_type == elf.PT_LOAD) {
|
if (phdr.p_type == elf.PT_LOAD) {
|
||||||
const newSegment = try allocator.create(BinaryElfSegment);
|
const newSegment = try allocator.create(BinaryElfSegment);
|
||||||
|
|||||||
351
lib/std/elf.zig
351
lib/std/elf.zig
@ -335,7 +335,7 @@ pub const ET = extern enum(u16) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// All integers are native endian.
|
/// All integers are native endian.
|
||||||
const Header = struct {
|
pub const Header = struct {
|
||||||
endian: builtin.Endian,
|
endian: builtin.Endian,
|
||||||
is_64: bool,
|
is_64: bool,
|
||||||
entry: u64,
|
entry: u64,
|
||||||
@ -347,187 +347,200 @@ const Header = struct {
|
|||||||
shnum: u16,
|
shnum: u16,
|
||||||
shstrndx: u16,
|
shstrndx: u16,
|
||||||
|
|
||||||
pub fn program_header_iterator(self: Header, file: File) ProgramHeaderIterator {
|
pub fn program_header_iterator(self: Header, parse_source: anytype) ProgramHeaderIterator(@TypeOf(parse_source)) {
|
||||||
return .{
|
return ProgramHeaderIterator(@TypeOf(parse_source)){
|
||||||
.elf_header = self,
|
.elf_header = self,
|
||||||
.file = file,
|
.parse_source = parse_source,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn section_header_iterator(self: Header, file: File) SectionHeaderIterator {
|
pub fn section_header_iterator(self: Header, parse_source: anytype) SectionHeaderIterator(@TypeOf(parse_source)) {
|
||||||
return .{
|
return SectionHeaderIterator(@TypeOf(parse_source)){
|
||||||
.elf_header = self,
|
.elf_header = self,
|
||||||
.file = file,
|
.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 = @ptrCast(*const Elf32_Ehdr, hdr_buf);
|
||||||
|
const hdr64 = @ptrCast(*const Elf64_Ehdr, hdr_buf);
|
||||||
|
if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
|
||||||
|
if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion;
|
||||||
|
|
||||||
|
const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) {
|
||||||
|
ELFDATA2LSB => .Little,
|
||||||
|
ELFDATA2MSB => .Big,
|
||||||
|
else => return error.InvalidElfEndian,
|
||||||
|
};
|
||||||
|
const need_bswap = endian != std.builtin.endian;
|
||||||
|
|
||||||
|
const is_64 = switch (hdr32.e_ident[EI_CLASS]) {
|
||||||
|
ELFCLASS32 => false,
|
||||||
|
ELFCLASS64 => true,
|
||||||
|
else => return error.InvalidElfClass,
|
||||||
|
};
|
||||||
|
|
||||||
|
return @as(Header, .{
|
||||||
|
.endian = endian,
|
||||||
|
.is_64 = is_64,
|
||||||
|
.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),
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn readHeader(file: File) !Header {
|
pub fn ProgramHeaderIterator(ParseSource: anytype) type {
|
||||||
var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined;
|
return struct {
|
||||||
try preadNoEof(file, &hdr_buf, 0);
|
elf_header: Header,
|
||||||
const hdr32 = @ptrCast(*Elf32_Ehdr, &hdr_buf);
|
parse_source: ParseSource,
|
||||||
const hdr64 = @ptrCast(*Elf64_Ehdr, &hdr_buf);
|
index: usize = 0,
|
||||||
if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
|
|
||||||
if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion;
|
|
||||||
|
|
||||||
const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) {
|
pub fn next(self: *@This()) !?Elf64_Phdr {
|
||||||
ELFDATA2LSB => .Little,
|
if (self.index >= self.elf_header.phnum) return null;
|
||||||
ELFDATA2MSB => .Big,
|
defer self.index += 1;
|
||||||
else => return error.InvalidElfEndian,
|
|
||||||
|
if (self.elf_header.is_64) {
|
||||||
|
var phdr: Elf64_Phdr = undefined;
|
||||||
|
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
|
||||||
|
try self.parse_source.seekableStream().seekTo(offset);
|
||||||
|
try self.parse_source.reader().readNoEof(mem.asBytes(&phdr));
|
||||||
|
|
||||||
|
// ELF endianness matches native endianness.
|
||||||
|
if (self.elf_header.endian == std.builtin.endian) return phdr;
|
||||||
|
|
||||||
|
// Convert fields to native endianness.
|
||||||
|
return Elf64_Phdr{
|
||||||
|
.p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
|
||||||
|
.p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
|
||||||
|
.p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
|
||||||
|
.p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
|
||||||
|
.p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
|
||||||
|
.p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
|
||||||
|
.p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
|
||||||
|
.p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var phdr: Elf32_Phdr = undefined;
|
||||||
|
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
|
||||||
|
try self.parse_source.seekableStream().seekTo(offset);
|
||||||
|
try self.parse_source.reader().readNoEof(mem.asBytes(&phdr));
|
||||||
|
|
||||||
|
// ELF endianness does NOT match native endianness.
|
||||||
|
if (self.elf_header.endian != std.builtin.endian) {
|
||||||
|
// Convert fields to native endianness.
|
||||||
|
phdr = .{
|
||||||
|
.p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
|
||||||
|
.p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
|
||||||
|
.p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
|
||||||
|
.p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
|
||||||
|
.p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
|
||||||
|
.p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
|
||||||
|
.p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
|
||||||
|
.p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert 32-bit header to 64-bit.
|
||||||
|
return Elf64_Phdr{
|
||||||
|
.p_type = phdr.p_type,
|
||||||
|
.p_offset = phdr.p_offset,
|
||||||
|
.p_vaddr = phdr.p_vaddr,
|
||||||
|
.p_paddr = phdr.p_paddr,
|
||||||
|
.p_filesz = phdr.p_filesz,
|
||||||
|
.p_memsz = phdr.p_memsz,
|
||||||
|
.p_flags = phdr.p_flags,
|
||||||
|
.p_align = phdr.p_align,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const need_bswap = endian != std.builtin.endian;
|
|
||||||
|
|
||||||
const is_64 = switch (hdr32.e_ident[EI_CLASS]) {
|
|
||||||
ELFCLASS32 => false,
|
|
||||||
ELFCLASS64 => true,
|
|
||||||
else => return error.InvalidElfClass,
|
|
||||||
};
|
|
||||||
|
|
||||||
return @as(Header, .{
|
|
||||||
.endian = endian,
|
|
||||||
.is_64 = is_64,
|
|
||||||
.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),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ProgramHeaderIterator = struct {
|
pub fn SectionHeaderIterator(ParseSource: anytype) type {
|
||||||
elf_header: Header,
|
return struct {
|
||||||
file: File,
|
elf_header: Header,
|
||||||
index: usize = 0,
|
parse_source: ParseSource,
|
||||||
|
index: usize = 0,
|
||||||
|
|
||||||
pub fn next(self: *ProgramHeaderIterator) !?Elf64_Phdr {
|
pub fn next(self: *@This()) !?Elf64_Shdr {
|
||||||
if (self.index >= self.elf_header.phnum) return null;
|
if (self.index >= self.elf_header.shnum) return null;
|
||||||
defer self.index += 1;
|
defer self.index += 1;
|
||||||
|
|
||||||
if (self.elf_header.is_64) {
|
if (self.elf_header.is_64) {
|
||||||
var phdr: Elf64_Phdr = undefined;
|
var shdr: Elf64_Shdr = undefined;
|
||||||
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
|
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
|
||||||
try preadNoEof(self.file, mem.asBytes(&phdr), offset);
|
try self.parse_source.seekableStream().seekTo(offset);
|
||||||
|
try self.parse_source.reader().readNoEof(mem.asBytes(&shdr));
|
||||||
|
|
||||||
// ELF endianness matches native endianness.
|
// ELF endianness matches native endianness.
|
||||||
if (self.elf_header.endian == std.builtin.endian) return phdr;
|
if (self.elf_header.endian == std.builtin.endian) return shdr;
|
||||||
|
|
||||||
// Convert fields to native endianness.
|
// Convert fields to native endianness.
|
||||||
return Elf64_Phdr{
|
return Elf64_Shdr{
|
||||||
.p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
|
.sh_name = @byteSwap(@TypeOf(shdr.sh_name), shdr.sh_name),
|
||||||
.p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
|
.sh_type = @byteSwap(@TypeOf(shdr.sh_type), shdr.sh_type),
|
||||||
.p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
|
.sh_flags = @byteSwap(@TypeOf(shdr.sh_flags), shdr.sh_flags),
|
||||||
.p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
|
.sh_addr = @byteSwap(@TypeOf(shdr.sh_addr), shdr.sh_addr),
|
||||||
.p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
|
.sh_offset = @byteSwap(@TypeOf(shdr.sh_offset), shdr.sh_offset),
|
||||||
.p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
|
.sh_size = @byteSwap(@TypeOf(shdr.sh_size), shdr.sh_size),
|
||||||
.p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
|
.sh_link = @byteSwap(@TypeOf(shdr.sh_link), shdr.sh_link),
|
||||||
.p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
|
.sh_info = @byteSwap(@TypeOf(shdr.sh_info), shdr.sh_info),
|
||||||
};
|
.sh_addralign = @byteSwap(@TypeOf(shdr.sh_addralign), shdr.sh_addralign),
|
||||||
}
|
.sh_entsize = @byteSwap(@TypeOf(shdr.sh_entsize), shdr.sh_entsize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var phdr: Elf32_Phdr = undefined;
|
var shdr: Elf32_Shdr = undefined;
|
||||||
const offset = self.elf_header.phoff + @sizeOf(@TypeOf(phdr)) * self.index;
|
|
||||||
try preadNoEof(self.file, mem.asBytes(&phdr), offset);
|
|
||||||
|
|
||||||
// ELF endianness does NOT match native endianness.
|
|
||||||
if (self.elf_header.endian != std.builtin.endian) {
|
|
||||||
// Convert fields to native endianness.
|
|
||||||
phdr = .{
|
|
||||||
.p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
|
|
||||||
.p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
|
|
||||||
.p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
|
|
||||||
.p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
|
|
||||||
.p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
|
|
||||||
.p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
|
|
||||||
.p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
|
|
||||||
.p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert 32-bit header to 64-bit.
|
|
||||||
return Elf64_Phdr{
|
|
||||||
.p_type = phdr.p_type,
|
|
||||||
.p_offset = phdr.p_offset,
|
|
||||||
.p_vaddr = phdr.p_vaddr,
|
|
||||||
.p_paddr = phdr.p_paddr,
|
|
||||||
.p_filesz = phdr.p_filesz,
|
|
||||||
.p_memsz = phdr.p_memsz,
|
|
||||||
.p_flags = phdr.p_flags,
|
|
||||||
.p_align = phdr.p_align,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const SectionHeaderIterator = struct {
|
|
||||||
elf_header: Header,
|
|
||||||
file: File,
|
|
||||||
index: usize = 0,
|
|
||||||
|
|
||||||
pub fn next(self: *SectionHeaderIterator) !?Elf64_Shdr {
|
|
||||||
if (self.index >= self.elf_header.shnum) return null;
|
|
||||||
defer self.index += 1;
|
|
||||||
|
|
||||||
if (self.elf_header.is_64) {
|
|
||||||
var shdr: Elf64_Shdr = undefined;
|
|
||||||
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
|
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
|
||||||
try preadNoEof(self.file, mem.asBytes(&shdr), offset);
|
try self.parse_source.seekableStream().seekTo(offset);
|
||||||
|
try self.parse_source.reader().readNoEof(mem.asBytes(&shdr));
|
||||||
|
|
||||||
// ELF endianness matches native endianness.
|
// ELF endianness does NOT match native endianness.
|
||||||
if (self.elf_header.endian == std.builtin.endian) return shdr;
|
if (self.elf_header.endian != std.builtin.endian) {
|
||||||
|
// Convert fields to native endianness.
|
||||||
|
shdr = .{
|
||||||
|
.sh_name = @byteSwap(@TypeOf(shdr.sh_name), shdr.sh_name),
|
||||||
|
.sh_type = @byteSwap(@TypeOf(shdr.sh_type), shdr.sh_type),
|
||||||
|
.sh_flags = @byteSwap(@TypeOf(shdr.sh_flags), shdr.sh_flags),
|
||||||
|
.sh_addr = @byteSwap(@TypeOf(shdr.sh_addr), shdr.sh_addr),
|
||||||
|
.sh_offset = @byteSwap(@TypeOf(shdr.sh_offset), shdr.sh_offset),
|
||||||
|
.sh_size = @byteSwap(@TypeOf(shdr.sh_size), shdr.sh_size),
|
||||||
|
.sh_link = @byteSwap(@TypeOf(shdr.sh_link), shdr.sh_link),
|
||||||
|
.sh_info = @byteSwap(@TypeOf(shdr.sh_info), shdr.sh_info),
|
||||||
|
.sh_addralign = @byteSwap(@TypeOf(shdr.sh_addralign), shdr.sh_addralign),
|
||||||
|
.sh_entsize = @byteSwap(@TypeOf(shdr.sh_entsize), shdr.sh_entsize),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Convert fields to native endianness.
|
// Convert 32-bit header to 64-bit.
|
||||||
return Elf64_Shdr{
|
return Elf64_Shdr{
|
||||||
.sh_name = @byteSwap(@TypeOf(shdr.sh_name), shdr.sh_name),
|
.sh_name = shdr.sh_name,
|
||||||
.sh_type = @byteSwap(@TypeOf(shdr.sh_type), shdr.sh_type),
|
.sh_type = shdr.sh_type,
|
||||||
.sh_flags = @byteSwap(@TypeOf(shdr.sh_flags), shdr.sh_flags),
|
.sh_flags = shdr.sh_flags,
|
||||||
.sh_addr = @byteSwap(@TypeOf(shdr.sh_addr), shdr.sh_addr),
|
.sh_addr = shdr.sh_addr,
|
||||||
.sh_offset = @byteSwap(@TypeOf(shdr.sh_offset), shdr.sh_offset),
|
.sh_offset = shdr.sh_offset,
|
||||||
.sh_size = @byteSwap(@TypeOf(shdr.sh_size), shdr.sh_size),
|
.sh_size = shdr.sh_size,
|
||||||
.sh_link = @byteSwap(@TypeOf(shdr.sh_link), shdr.sh_link),
|
.sh_link = shdr.sh_link,
|
||||||
.sh_info = @byteSwap(@TypeOf(shdr.sh_info), shdr.sh_info),
|
.sh_info = shdr.sh_info,
|
||||||
.sh_addralign = @byteSwap(@TypeOf(shdr.sh_addralign), shdr.sh_addralign),
|
.sh_addralign = shdr.sh_addralign,
|
||||||
.sh_entsize = @byteSwap(@TypeOf(shdr.sh_entsize), shdr.sh_entsize),
|
.sh_entsize = shdr.sh_entsize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
};
|
||||||
var shdr: Elf32_Shdr = undefined;
|
}
|
||||||
const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index;
|
|
||||||
try preadNoEof(self.file, mem.asBytes(&shdr), offset);
|
|
||||||
|
|
||||||
// ELF endianness does NOT match native endianness.
|
|
||||||
if (self.elf_header.endian != std.builtin.endian) {
|
|
||||||
// Convert fields to native endianness.
|
|
||||||
shdr = .{
|
|
||||||
.sh_name = @byteSwap(@TypeOf(shdr.sh_name), shdr.sh_name),
|
|
||||||
.sh_type = @byteSwap(@TypeOf(shdr.sh_type), shdr.sh_type),
|
|
||||||
.sh_flags = @byteSwap(@TypeOf(shdr.sh_flags), shdr.sh_flags),
|
|
||||||
.sh_addr = @byteSwap(@TypeOf(shdr.sh_addr), shdr.sh_addr),
|
|
||||||
.sh_offset = @byteSwap(@TypeOf(shdr.sh_offset), shdr.sh_offset),
|
|
||||||
.sh_size = @byteSwap(@TypeOf(shdr.sh_size), shdr.sh_size),
|
|
||||||
.sh_link = @byteSwap(@TypeOf(shdr.sh_link), shdr.sh_link),
|
|
||||||
.sh_info = @byteSwap(@TypeOf(shdr.sh_info), shdr.sh_info),
|
|
||||||
.sh_addralign = @byteSwap(@TypeOf(shdr.sh_addralign), shdr.sh_addralign),
|
|
||||||
.sh_entsize = @byteSwap(@TypeOf(shdr.sh_entsize), shdr.sh_entsize),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert 32-bit header to 64-bit.
|
|
||||||
return Elf64_Shdr{
|
|
||||||
.sh_name = shdr.sh_name,
|
|
||||||
.sh_type = shdr.sh_type,
|
|
||||||
.sh_flags = shdr.sh_flags,
|
|
||||||
.sh_addr = shdr.sh_addr,
|
|
||||||
.sh_offset = shdr.sh_offset,
|
|
||||||
.sh_size = shdr.sh_size,
|
|
||||||
.sh_link = shdr.sh_link,
|
|
||||||
.sh_info = shdr.sh_info,
|
|
||||||
.sh_addralign = shdr.sh_addralign,
|
|
||||||
.sh_entsize = shdr.sh_entsize,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
|
pub fn int(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
|
||||||
if (is_64) {
|
if (is_64) {
|
||||||
@ -549,28 +562,6 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void {
|
|
||||||
var i: usize = 0;
|
|
||||||
while (i < buf.len) {
|
|
||||||
const len = file.pread(buf[i .. buf.len - i], offset + i) catch |err| switch (err) {
|
|
||||||
error.SystemResources => return error.SystemResources,
|
|
||||||
error.IsDir => return error.UnableToReadElfFile,
|
|
||||||
error.OperationAborted => return error.UnableToReadElfFile,
|
|
||||||
error.BrokenPipe => return error.UnableToReadElfFile,
|
|
||||||
error.Unseekable => return error.UnableToReadElfFile,
|
|
||||||
error.ConnectionResetByPeer => return error.UnableToReadElfFile,
|
|
||||||
error.ConnectionTimedOut => return error.UnableToReadElfFile,
|
|
||||||
error.InputOutput => return error.FileSystem,
|
|
||||||
error.Unexpected => return error.Unexpected,
|
|
||||||
error.WouldBlock => return error.Unexpected,
|
|
||||||
error.NotOpenForReading => return error.Unexpected,
|
|
||||||
error.AccessDenied => return error.Unexpected,
|
|
||||||
};
|
|
||||||
if (len == 0) return error.UnexpectedEndOfFile;
|
|
||||||
i += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const EI_NIDENT = 16;
|
pub const EI_NIDENT = 16;
|
||||||
|
|
||||||
pub const EI_CLASS = 4;
|
pub const EI_CLASS = 4;
|
||||||
|
|||||||
@ -1030,8 +1030,8 @@ pub const TestContext = struct {
|
|||||||
var file = try tmp_dir.openFile(bin_name, .{ .read = true });
|
var file = try tmp_dir.openFile(bin_name, .{ .read = true });
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
const header = try std.elf.readHeader(file);
|
const header = try std.elf.Header.read(&file);
|
||||||
var iterator = header.program_header_iterator(file);
|
var iterator = header.program_header_iterator(&file);
|
||||||
|
|
||||||
var none_loaded = true;
|
var none_loaded = true;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user