| ... | ... | @@ -360,45 +360,45 @@ pub const Header = struct { |
| 360 | 360 | .file = file, |
| 361 | 361 | }; |
| 362 | 362 | } |
| 363 | |
| 364 | pub fn parse(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header { |
| 365 | const hdr32 = @ptrCast(*const Elf32_Ehdr, hdr_buf); |
| 366 | const hdr64 = @ptrCast(*const Elf64_Ehdr, hdr_buf); |
| 367 | if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; |
| 368 | if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion; |
| 369 | |
| 370 | const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) { |
| 371 | ELFDATA2LSB => .Little, |
| 372 | ELFDATA2MSB => .Big, |
| 373 | else => return error.InvalidElfEndian, |
| 374 | }; |
| 375 | const need_bswap = endian != std.builtin.endian; |
| 376 | |
| 377 | const is_64 = switch (hdr32.e_ident[EI_CLASS]) { |
| 378 | ELFCLASS32 => false, |
| 379 | ELFCLASS64 => true, |
| 380 | else => return error.InvalidElfClass, |
| 381 | }; |
| 382 | |
| 383 | return @as(Header, .{ |
| 384 | .endian = endian, |
| 385 | .is_64 = is_64, |
| 386 | .entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry), |
| 387 | .phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff), |
| 388 | .shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff), |
| 389 | .phentsize = int(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize), |
| 390 | .phnum = int(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum), |
| 391 | .shentsize = int(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize), |
| 392 | .shnum = int(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum), |
| 393 | .shstrndx = int(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx), |
| 394 | }); |
| 395 | } |
| 363 | 396 | }; |
| 364 | 397 | |
| 365 | 398 | pub fn readHeader(file: File) !Header { |
| 366 | 399 | var hdr_buf: [@sizeOf(Elf64_Ehdr)]u8 align(@alignOf(Elf64_Ehdr)) = undefined; |
| 367 | 400 | try preadNoEof(file, &hdr_buf, 0); |
| 368 | | return parseHeader(hdr_buf); |
| 369 | | } |
| 370 | | |
| 371 | | pub fn parseHeader(hdr_buf: *align(@alignOf(Elf64_Ehdr)) const [@sizeOf(Elf64_Ehdr)]u8) !Header { |
| 372 | | const hdr32 = @ptrCast(*const Elf32_Ehdr, hdr_buf); |
| 373 | | const hdr64 = @ptrCast(*const Elf64_Ehdr, hdr_buf); |
| 374 | | if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; |
| 375 | | if (hdr32.e_ident[EI_VERSION] != 1) return error.InvalidElfVersion; |
| 376 | | |
| 377 | | const endian: std.builtin.Endian = switch (hdr32.e_ident[EI_DATA]) { |
| 378 | | ELFDATA2LSB => .Little, |
| 379 | | ELFDATA2MSB => .Big, |
| 380 | | else => return error.InvalidElfEndian, |
| 381 | | }; |
| 382 | | const need_bswap = endian != std.builtin.endian; |
| 383 | | |
| 384 | | const is_64 = switch (hdr32.e_ident[EI_CLASS]) { |
| 385 | | ELFCLASS32 => false, |
| 386 | | ELFCLASS64 => true, |
| 387 | | else => return error.InvalidElfClass, |
| 388 | | }; |
| 389 | | |
| 390 | | return @as(Header, .{ |
| 391 | | .endian = endian, |
| 392 | | .is_64 = is_64, |
| 393 | | .entry = int(is_64, need_bswap, hdr32.e_entry, hdr64.e_entry), |
| 394 | | .phoff = int(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff), |
| 395 | | .shoff = int(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff), |
| 396 | | .phentsize = int(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize), |
| 397 | | .phnum = int(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum), |
| 398 | | .shentsize = int(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize), |
| 399 | | .shnum = int(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum), |
| 400 | | .shstrndx = int(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx), |
| 401 | | }); |
| 401 | return Header.parse(hdr_buf); |
| 402 | 402 | } |
| 403 | 403 | |
| 404 | 404 | pub const ProgramHeaderIterator = struct { |