| ... | @@ -398,48 +398,123 @@ pub fn readAllHeaders(allocator: *mem.Allocator, file: File) !AllHeaders { | ... | @@ -398,48 +398,123 @@ pub fn readAllHeaders(allocator: *mem.Allocator, file: File) !AllHeaders { |
| 398 | const need_bswap = hdrs.header.endian != std.builtin.endian; | 398 | const need_bswap = hdrs.header.endian != std.builtin.endian; |
| 399 | | 399 | |
| 400 | hdrs.section_headers = try allocator.alloc(Elf64_Shdr, hdrs.header.shnum); | 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 | hdrs.program_headers = try allocator.alloc(Elf64_Phdr, hdrs.header.phnum); | 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 | 406 | // If the ELF file is 64-bit and same-endianness, then all we have to do is |
| 407 | // non-matching endian files, we post-process to correct integer endianness and offsets. | 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]; | 447 | const shdrs_32 = try allocator.alloc(Elf32_Shdr, hdrs.header.shnum); |
| 410 | const phdr_buf = std.mem.sliceAsBytes(hdrs.program_headers)[0 .. hdrs.header.phentsize * hdrs.header.phnum]; | 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 | try preadNoEof(file, shdr_buf, hdrs.header.shoff); | 455 | try preadNoEof(file, shdr_buf, hdrs.header.shoff); |
| 413 | try preadNoEof(file, phdr_buf, hdrs.header.phoff); | 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]; | 458 | if (need_bswap) { |
| 416 | const phdrs32 = @ptrCast([*]Elf32_Phdr, @alignCast(@alignOf(Elf32_Phdr), phdr_buf.ptr))[0..hdrs.header.phnum]; | 459 | for (hdrs.section_headers) |*shdr, i| { |
| 417 | for (hdrs.section_headers) |*shdr, i| { | 460 | const o = shdrs_32[i]; |
| 418 | shdr.* = .{ | 461 | shdr.* = .{ |
| 419 | .sh_name = int(is_64, need_bswap, shdrs32[i].sh_name, shdr.sh_name), | 462 | .sh_name = @byteSwap(@TypeOf(o.sh_name), o.sh_name), |
| 420 | .sh_type = int(is_64, need_bswap, shdrs32[i].sh_type, shdr.sh_type), | 463 | .sh_type = @byteSwap(@TypeOf(o.sh_type), o.sh_type), |
| 421 | .sh_flags = int(is_64, need_bswap, shdrs32[i].sh_flags, shdr.sh_flags), | 464 | .sh_flags = @byteSwap(@TypeOf(o.sh_flags), o.sh_flags), |
| 422 | .sh_addr = int(is_64, need_bswap, shdrs32[i].sh_addr, shdr.sh_addr), | 465 | .sh_addr = @byteSwap(@TypeOf(o.sh_addr), o.sh_addr), |
| 423 | .sh_offset = int(is_64, need_bswap, shdrs32[i].sh_offset, shdr.sh_offset), | 466 | .sh_offset = @byteSwap(@TypeOf(o.sh_offset), o.sh_offset), |
| 424 | .sh_size = int(is_64, need_bswap, shdrs32[i].sh_size, shdr.sh_size), | 467 | .sh_size = @byteSwap(@TypeOf(o.sh_size), o.sh_size), |
| 425 | .sh_link = int(is_64, need_bswap, shdrs32[i].sh_link, shdr.sh_link), | 468 | .sh_link = @byteSwap(@TypeOf(o.sh_link), o.sh_link), |
| 426 | .sh_info = int(is_64, need_bswap, shdrs32[i].sh_info, shdr.sh_info), | 469 | .sh_info = @byteSwap(@TypeOf(o.sh_info), o.sh_info), |
| 427 | .sh_addralign = int(is_64, need_bswap, shdrs32[i].sh_addralign, shdr.sh_addralign), | 470 | .sh_addralign = @byteSwap(@TypeOf(o.sh_addralign), o.sh_addralign), |
| 428 | .sh_entsize = int(is_64, need_bswap, shdrs32[i].sh_entsize, shdr.sh_entsize), | 471 | .sh_entsize = @byteSwap(@TypeOf(o.sh_entsize), o.sh_entsize), |
| 429 | }; | 472 | }; |
| 430 | } | 473 | } |
| 431 | for (hdrs.program_headers) |*phdr, i| { | 474 | for (hdrs.program_headers) |*phdr, i| { |
| 432 | phdr.* = .{ | 475 | const o = phdrs_32[i]; |
| 433 | .p_type = int(is_64, need_bswap, phdrs32[i].p_type, phdr.p_type), | 476 | phdr.* = .{ |
| 434 | .p_offset = int(is_64, need_bswap, phdrs32[i].p_offset, phdr.p_offset), | 477 | .p_type = @byteSwap(@TypeOf(o.p_type), o.p_type), |
| 435 | .p_vaddr = int(is_64, need_bswap, phdrs32[i].p_vaddr, phdr.p_vaddr), | 478 | .p_offset = @byteSwap(@TypeOf(o.p_offset), o.p_offset), |
| 436 | .p_paddr = int(is_64, need_bswap, phdrs32[i].p_paddr, phdr.p_paddr), | 479 | .p_vaddr = @byteSwap(@TypeOf(o.p_vaddr), o.p_vaddr), |
| 437 | .p_filesz = int(is_64, need_bswap, phdrs32[i].p_filesz, phdr.p_filesz), | 480 | .p_paddr = @byteSwap(@TypeOf(o.p_paddr), o.p_paddr), |
| 438 | .p_memsz = int(is_64, need_bswap, phdrs32[i].p_memsz, phdr.p_memsz), | 481 | .p_filesz = @byteSwap(@TypeOf(o.p_filesz), o.p_filesz), |
| 439 | .p_flags = int(is_64, need_bswap, phdrs32[i].p_flags, phdr.p_flags), | 482 | .p_memsz = @byteSwap(@TypeOf(o.p_memsz), o.p_memsz), |
| 440 | .p_align = int(is_64, need_bswap, phdrs32[i].p_align, phdr.p_align), | 483 | .p_flags = @byteSwap(@TypeOf(o.p_flags), o.p_flags), |
| 441 | }; | 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 | return hdrs; | 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,11 +526,15 @@ pub fn int(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_ |
| 451 | return int_64; | 526 | return int_64; |
| 452 | } | 527 | } |
| 453 | } else { | 528 | } else { |
| 454 | if (need_bswap) { | 529 | return int32(need_bswap, int_32, @TypeOf(int_64)); |
| 455 | return @byteSwap(@TypeOf(int_32), int_32); | 530 | } |
| 456 | } else { | 531 | } |
| 457 | return int_32; | 532 | |
| 458 | } | 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 | |