| ... | @@ -346,13 +346,13 @@ const Header = struct { | ... | @@ -346,13 +346,13 @@ const Header = struct { |
| 346 | | 346 | |
| 347 | pub fn readHeader(file: File) !Header { | 347 | pub fn readHeader(file: File) !Header { |
| 348 | var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined; | 348 | var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined; |
| 349 | try in_stream.preadAll(&hdr_buf, 0); | 349 | try preadNoEof(file, &hdr_buf, 0); |
| 350 | const hdr32 = @ptrCast(*elf.Elf32_Ehdr, &hdr_buf); | 350 | const hdr32 = @ptrCast(*Elf32_Ehdr, &hdr_buf); |
| 351 | const hdr64 = @ptrCast(*elf.Elf64_Ehdr, &hdr_buf); | 351 | const hdr64 = @ptrCast(*Elf64_Ehdr, &hdr_buf); |
| 352 | if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; | 352 | if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; |
| 353 | if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion; | 353 | if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion; |
| 354 | | 354 | |
| 355 | const endian = switch (hdr32.e_ident[elf.EI_DATA]) { | 355 | const endian = switch (hdr32.e_ident[EI_DATA]) { |
| 356 | ELFDATA2LSB => .Little, | 356 | ELFDATA2LSB => .Little, |
| 357 | ELFDATA2MSB => .Big, | 357 | ELFDATA2MSB => .Big, |
| 358 | else => return error.InvalidElfEndian, | 358 | else => return error.InvalidElfEndian, |
| ... | @@ -407,10 +407,10 @@ pub fn readAllHeaders(allocator: *mem.Allocator, file: File) !AllHeaders { | ... | @@ -407,10 +407,10 @@ pub fn readAllHeaders(allocator: *mem.Allocator, file: File) !AllHeaders { |
| 407 | // non-matching endian files, we post-process to correct integer endianness and offsets. | 407 | // non-matching endian files, we post-process to correct integer endianness and offsets. |
| 408 | | 408 | |
| 409 | const shdr_buf = std.mem.sliceToBytes(hdrs.section_headers)[0 .. hdrs.header.shentsize * hdrs.header.shnum]; | 409 | const shdr_buf = std.mem.sliceToBytes(hdrs.section_headers)[0 .. hdrs.header.shentsize * hdrs.header.shnum]; |
| 410 | const phdr_buf = std.mem.sliceToBytes(hdrs.section_headers)[0 .. hdrs.header.phentsize * hdrs.header.phnum]; | 410 | const phdr_buf = std.mem.sliceToBytes(hdrs.program_headers)[0 .. hdrs.header.phentsize * hdrs.header.phnum]; |
| 411 | | 411 | |
| 412 | try file.preadAll(phdr_buf, hdrs.header.phoff); | 412 | try preadNoEof(file, shdr_buf, hdrs.header.shoff); |
| 413 | try file.preadAll(shdr_buf, hdrs.header.shoff); | 413 | try preadNoEof(file, phdr_buf, hdrs.header.phoff); |
| 414 | | 414 | |
| 415 | const shdrs32 = @ptrCast([*]Elf32_Shdr, @alignCast(@alignOf(Elf32_Shdr), shdr_buf.ptr))[0..hdrs.header.shnum]; | 415 | const shdrs32 = @ptrCast([*]Elf32_Shdr, @alignCast(@alignOf(Elf32_Shdr), shdr_buf.ptr))[0..hdrs.header.shnum]; |
| 416 | const phdrs32 = @ptrCast([*]Elf32_Phdr, @alignCast(@alignOf(Elf32_Phdr), phdr_buf.ptr))[0..hdrs.header.phnum]; | 416 | const phdrs32 = @ptrCast([*]Elf32_Phdr, @alignCast(@alignOf(Elf32_Phdr), phdr_buf.ptr))[0..hdrs.header.phnum]; |
| ... | @@ -459,6 +459,25 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_ | ... | @@ -459,6 +459,25 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_ |
| 459 | } | 459 | } |
| 460 | } | 460 | } |
| 461 | | 461 | |
| | 462 | fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void { |
| | 463 | var i: u64 = 0; |
| | 464 | while (i < buf.len) { |
| | 465 | const len = file.pread(buf[i .. buf.len - i], offset + i) catch |err| switch (err) { |
| | 466 | error.SystemResources => return error.SystemResources, |
| | 467 | error.IsDir => return error.UnableToReadElfFile, |
| | 468 | error.OperationAborted => return error.UnableToReadElfFile, |
| | 469 | error.BrokenPipe => return error.UnableToReadElfFile, |
| | 470 | error.Unseekable => return error.UnableToReadElfFile, |
| | 471 | error.ConnectionResetByPeer => return error.UnableToReadElfFile, |
| | 472 | error.InputOutput => return error.FileSystem, |
| | 473 | error.Unexpected => return error.Unexpected, |
| | 474 | error.WouldBlock => return error.Unexpected, |
| | 475 | }; |
| | 476 | if (len == 0) return error.UnexpectedEndOfFile; |
| | 477 | i += len; |
| | 478 | } |
| | 479 | } |
| | 480 | |
| 462 | pub const EI_NIDENT = 16; | 481 | pub const EI_NIDENT = 16; |
| 463 | | 482 | |
| 464 | pub const EI_CLASS = 4; | 483 | pub const EI_CLASS = 4; |