| ... | ... | @@ -398,48 +398,123 @@ pub fn readAllHeaders(allocator: *mem.Allocator, file: File) !AllHeaders { |
| 398 | 398 | const need_bswap = hdrs.header.endian != std.builtin.endian; |
| 399 | 399 | |
| 400 | 400 | hdrs.section_headers = try allocator.alloc(Elf64_Shdr, hdrs.header.shnum); |
| 401 | | errdefer hdrs.allocator.free(hdrs.section_headers); |
| 401 | errdefer allocator.free(hdrs.section_headers); |
| 402 | 402 | |
| 403 | 403 | hdrs.program_headers = try allocator.alloc(Elf64_Phdr, hdrs.header.phnum); |
| 404 | | errdefer hdrs.allocator.free(hdrs.program_headers); |
| 404 | errdefer allocator.free(hdrs.program_headers); |
| 405 | 405 | |
| 406 | | // Treat section headers and program headers as byte buffers. For 32-bit ELF and |
| 407 | | // non-matching endian files, we post-process to correct integer endianness and offsets. |
| 406 | // If the ELF file is 64-bit and same-endianness, then all we have to do is |
| 407 | // yeet the bytes into memory. |
| 408 | // If only the endianness is different, they can be simply byte swapped. |
| 409 | if (is_64) { |
| 410 | const shdr_buf = std.mem.sliceAsBytes(hdrs.section_headers); |
| 411 | const phdr_buf = std.mem.sliceAsBytes(hdrs.program_headers); |
| 412 | try preadNoEof(file, shdr_buf, hdrs.header.shoff); |
| 413 | try preadNoEof(file, phdr_buf, hdrs.header.phoff); |
| 414 | |
| 415 | if (need_bswap) { |
| 416 | for (hdrs.section_headers) |*shdr| { |
| 417 | shdr.* = .{ |
| 418 | .sh_name = @byteSwap(@TypeOf(shdr.sh_name), shdr.sh_name), |
| 419 | .sh_type = @byteSwap(@TypeOf(shdr.sh_type), shdr.sh_type), |
| 420 | .sh_flags = @byteSwap(@TypeOf(shdr.sh_flags), shdr.sh_flags), |
| 421 | .sh_addr = @byteSwap(@TypeOf(shdr.sh_addr), shdr.sh_addr), |
| 422 | .sh_offset = @byteSwap(@TypeOf(shdr.sh_offset), shdr.sh_offset), |
| 423 | .sh_size = @byteSwap(@TypeOf(shdr.sh_size), shdr.sh_size), |
| 424 | .sh_link = @byteSwap(@TypeOf(shdr.sh_link), shdr.sh_link), |
| 425 | .sh_info = @byteSwap(@TypeOf(shdr.sh_info), shdr.sh_info), |
| 426 | .sh_addralign = @byteSwap(@TypeOf(shdr.sh_addralign), shdr.sh_addralign), |
| 427 | .sh_entsize = @byteSwap(@TypeOf(shdr.sh_entsize), shdr.sh_entsize), |
| 428 | }; |
| 429 | } |
| 430 | for (hdrs.program_headers) |*phdr| { |
| 431 | phdr.* = .{ |
| 432 | .p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type), |
| 433 | .p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset), |
| 434 | .p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr), |
| 435 | .p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr), |
| 436 | .p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz), |
| 437 | .p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz), |
| 438 | .p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags), |
| 439 | .p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align), |
| 440 | }; |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | return hdrs; |
| 445 | } |
| 408 | 446 | |
| 409 | | const shdr_buf = std.mem.sliceAsBytes(hdrs.section_headers)[0 .. hdrs.header.shentsize * hdrs.header.shnum]; |
| 410 | | const phdr_buf = std.mem.sliceAsBytes(hdrs.program_headers)[0 .. hdrs.header.phentsize * hdrs.header.phnum]; |
| 447 | const shdrs_32 = try allocator.alloc(Elf32_Shdr, hdrs.header.shnum); |
| 448 | defer allocator.free(shdrs_32); |
| 411 | 449 | |
| 450 | const phdrs_32 = try allocator.alloc(Elf32_Phdr, hdrs.header.phnum); |
| 451 | defer allocator.free(phdrs_32); |
| 452 | |
| 453 | const shdr_buf = std.mem.sliceAsBytes(shdrs_32); |
| 454 | const phdr_buf = std.mem.sliceAsBytes(phdrs_32); |
| 412 | 455 | try preadNoEof(file, shdr_buf, hdrs.header.shoff); |
| 413 | 456 | try preadNoEof(file, phdr_buf, hdrs.header.phoff); |
| 414 | 457 | |
| 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]; |
| 417 | | for (hdrs.section_headers) |*shdr, i| { |
| 418 | | shdr.* = .{ |
| 419 | | .sh_name = int(is_64, need_bswap, shdrs32[i].sh_name, shdr.sh_name), |
| 420 | | .sh_type = int(is_64, need_bswap, shdrs32[i].sh_type, shdr.sh_type), |
| 421 | | .sh_flags = int(is_64, need_bswap, shdrs32[i].sh_flags, shdr.sh_flags), |
| 422 | | .sh_addr = int(is_64, need_bswap, shdrs32[i].sh_addr, shdr.sh_addr), |
| 423 | | .sh_offset = int(is_64, need_bswap, shdrs32[i].sh_offset, shdr.sh_offset), |
| 424 | | .sh_size = int(is_64, need_bswap, shdrs32[i].sh_size, shdr.sh_size), |
| 425 | | .sh_link = int(is_64, need_bswap, shdrs32[i].sh_link, shdr.sh_link), |
| 426 | | .sh_info = int(is_64, need_bswap, shdrs32[i].sh_info, shdr.sh_info), |
| 427 | | .sh_addralign = int(is_64, need_bswap, shdrs32[i].sh_addralign, shdr.sh_addralign), |
| 428 | | .sh_entsize = int(is_64, need_bswap, shdrs32[i].sh_entsize, shdr.sh_entsize), |
| 429 | | }; |
| 430 | | } |
| 431 | | for (hdrs.program_headers) |*phdr, i| { |
| 432 | | phdr.* = .{ |
| 433 | | .p_type = int(is_64, need_bswap, phdrs32[i].p_type, phdr.p_type), |
| 434 | | .p_offset = int(is_64, need_bswap, phdrs32[i].p_offset, phdr.p_offset), |
| 435 | | .p_vaddr = int(is_64, need_bswap, phdrs32[i].p_vaddr, phdr.p_vaddr), |
| 436 | | .p_paddr = int(is_64, need_bswap, phdrs32[i].p_paddr, phdr.p_paddr), |
| 437 | | .p_filesz = int(is_64, need_bswap, phdrs32[i].p_filesz, phdr.p_filesz), |
| 438 | | .p_memsz = int(is_64, need_bswap, phdrs32[i].p_memsz, phdr.p_memsz), |
| 439 | | .p_flags = int(is_64, need_bswap, phdrs32[i].p_flags, phdr.p_flags), |
| 440 | | .p_align = int(is_64, need_bswap, phdrs32[i].p_align, phdr.p_align), |
| 441 | | }; |
| 458 | if (need_bswap) { |
| 459 | for (hdrs.section_headers) |*shdr, i| { |
| 460 | const o = shdrs_32[i]; |
| 461 | shdr.* = .{ |
| 462 | .sh_name = @byteSwap(@TypeOf(o.sh_name), o.sh_name), |
| 463 | .sh_type = @byteSwap(@TypeOf(o.sh_type), o.sh_type), |
| 464 | .sh_flags = @byteSwap(@TypeOf(o.sh_flags), o.sh_flags), |
| 465 | .sh_addr = @byteSwap(@TypeOf(o.sh_addr), o.sh_addr), |
| 466 | .sh_offset = @byteSwap(@TypeOf(o.sh_offset), o.sh_offset), |
| 467 | .sh_size = @byteSwap(@TypeOf(o.sh_size), o.sh_size), |
| 468 | .sh_link = @byteSwap(@TypeOf(o.sh_link), o.sh_link), |
| 469 | .sh_info = @byteSwap(@TypeOf(o.sh_info), o.sh_info), |
| 470 | .sh_addralign = @byteSwap(@TypeOf(o.sh_addralign), o.sh_addralign), |
| 471 | .sh_entsize = @byteSwap(@TypeOf(o.sh_entsize), o.sh_entsize), |
| 472 | }; |
| 473 | } |
| 474 | for (hdrs.program_headers) |*phdr, i| { |
| 475 | const o = phdrs_32[i]; |
| 476 | phdr.* = .{ |
| 477 | .p_type = @byteSwap(@TypeOf(o.p_type), o.p_type), |
| 478 | .p_offset = @byteSwap(@TypeOf(o.p_offset), o.p_offset), |
| 479 | .p_vaddr = @byteSwap(@TypeOf(o.p_vaddr), o.p_vaddr), |
| 480 | .p_paddr = @byteSwap(@TypeOf(o.p_paddr), o.p_paddr), |
| 481 | .p_filesz = @byteSwap(@TypeOf(o.p_filesz), o.p_filesz), |
| 482 | .p_memsz = @byteSwap(@TypeOf(o.p_memsz), o.p_memsz), |
| 483 | .p_flags = @byteSwap(@TypeOf(o.p_flags), o.p_flags), |
| 484 | .p_align = @byteSwap(@TypeOf(o.p_align), o.p_align), |
| 485 | }; |
| 486 | } |
| 487 | } else { |
| 488 | for (hdrs.section_headers) |*shdr, i| { |
| 489 | const o = shdrs_32[i]; |
| 490 | shdr.* = .{ |
| 491 | .sh_name = o.sh_name, |
| 492 | .sh_type = o.sh_type, |
| 493 | .sh_flags = o.sh_flags, |
| 494 | .sh_addr = o.sh_addr, |
| 495 | .sh_offset = o.sh_offset, |
| 496 | .sh_size = o.sh_size, |
| 497 | .sh_link = o.sh_link, |
| 498 | .sh_info = o.sh_info, |
| 499 | .sh_addralign = o.sh_addralign, |
| 500 | .sh_entsize = o.sh_entsize, |
| 501 | }; |
| 502 | } |
| 503 | for (hdrs.program_headers) |*phdr, i| { |
| 504 | const o = phdrs_32[i]; |
| 505 | phdr.* = .{ |
| 506 | .p_type = o.p_type, |
| 507 | .p_offset = o.p_offset, |
| 508 | .p_vaddr = o.p_vaddr, |
| 509 | .p_paddr = o.p_paddr, |
| 510 | .p_filesz = o.p_filesz, |
| 511 | .p_memsz = o.p_memsz, |
| 512 | .p_flags = o.p_flags, |
| 513 | .p_align = o.p_align, |
| 514 | }; |
| 515 | } |
| 442 | 516 | } |
| 517 | |
| 443 | 518 | return hdrs; |
| 444 | 519 | } |
| 445 | 520 | |
| ... | ... | @@ -451,11 +526,15 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_ |
| 451 | 526 | return int_64; |
| 452 | 527 | } |
| 453 | 528 | } else { |
| 454 | | if (need_bswap) { |
| 455 | | return @byteSwap(@TypeOf(int_32), int_32); |
| 456 | | } else { |
| 457 | | return int_32; |
| 458 | | } |
| 529 | return int32(need_bswap, int_32, @TypeOf(int_64)); |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | pub fn int32(need_bswap: bool, int_32: var, comptime Int64: var) Int64 { |
| 534 | if (need_bswap) { |
| 535 | return @byteSwap(@TypeOf(int_32), int_32); |
| 536 | } else { |
| 537 | return int_32; |
| 459 | 538 | } |
| 460 | 539 | } |
| 461 | 540 | |