| ... | ... | @@ -502,6 +502,13 @@ pub const Header = struct { |
| 502 | 502 | }; |
| 503 | 503 | } |
| 504 | 504 | |
| 505 | pub fn iterateProgramHeadersBuffer(h: Header, buf: []const u8) ProgramHeaderBufferIterator { |
| 506 | return .{ |
| 507 | .elf_header = h, |
| 508 | .buf = buf, |
| 509 | }; |
| 510 | } |
| 511 | |
| 505 | 512 | pub fn iterateSectionHeaders(h: Header, file_reader: *std.fs.File.Reader) SectionHeaderIterator { |
| 506 | 513 | return .{ |
| 507 | 514 | .elf_header = h, |
| ... | ... | @@ -509,6 +516,13 @@ pub const Header = struct { |
| 509 | 516 | }; |
| 510 | 517 | } |
| 511 | 518 | |
| 519 | pub fn iterateSectionHeadersBuffer(h: Header, buf: []const u8) SectionHeaderBufferIterator { |
| 520 | return .{ |
| 521 | .elf_header = h, |
| 522 | .buf = buf, |
| 523 | }; |
| 524 | } |
| 525 | |
| 512 | 526 | pub const ReadError = std.Io.Reader.Error || error{ |
| 513 | 527 | InvalidElfMagic, |
| 514 | 528 | InvalidElfVersion, |
| ... | ... | @@ -570,29 +584,48 @@ pub const ProgramHeaderIterator = struct { |
| 570 | 584 | if (it.index >= it.elf_header.phnum) return null; |
| 571 | 585 | defer it.index += 1; |
| 572 | 586 | |
| 573 | | if (it.elf_header.is_64) { |
| 574 | | const offset = it.elf_header.phoff + @sizeOf(Elf64_Phdr) * it.index; |
| 575 | | try it.file_reader.seekTo(offset); |
| 576 | | const phdr = try it.file_reader.interface.takeStruct(Elf64_Phdr, it.elf_header.endian); |
| 577 | | return phdr; |
| 578 | | } |
| 579 | | |
| 580 | | const offset = it.elf_header.phoff + @sizeOf(Elf32_Phdr) * it.index; |
| 587 | const offset = it.elf_header.phoff + if (it.elf_header.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr) * it.index; |
| 581 | 588 | try it.file_reader.seekTo(offset); |
| 582 | | const phdr = try it.file_reader.interface.takeStruct(Elf32_Phdr, it.elf_header.endian); |
| 583 | | return .{ |
| 584 | | .p_type = phdr.p_type, |
| 585 | | .p_offset = phdr.p_offset, |
| 586 | | .p_vaddr = phdr.p_vaddr, |
| 587 | | .p_paddr = phdr.p_paddr, |
| 588 | | .p_filesz = phdr.p_filesz, |
| 589 | | .p_memsz = phdr.p_memsz, |
| 590 | | .p_flags = phdr.p_flags, |
| 591 | | .p_align = phdr.p_align, |
| 592 | | }; |
| 589 | |
| 590 | return takePhdr(&it.file_reader.interface, it.elf_header); |
| 591 | } |
| 592 | }; |
| 593 | |
| 594 | pub const ProgramHeaderBufferIterator = struct { |
| 595 | elf_header: Header, |
| 596 | buf: []const u8, |
| 597 | index: usize = 0, |
| 598 | |
| 599 | pub fn next(it: *ProgramHeaderBufferIterator) !?Elf64_Phdr { |
| 600 | if (it.index >= it.elf_header.phnum) return null; |
| 601 | defer it.index += 1; |
| 602 | |
| 603 | const offset = it.elf_header.phoff + if (it.elf_header.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr) * it.index; |
| 604 | var reader = std.Io.Reader.fixed(it.buf[offset..]); |
| 605 | |
| 606 | return takePhdr(&reader, it.elf_header); |
| 593 | 607 | } |
| 594 | 608 | }; |
| 595 | 609 | |
| 610 | fn takePhdr(reader: *std.io.Reader, elf_header: Header) !?Elf64_Phdr { |
| 611 | if (elf_header.is_64) { |
| 612 | const phdr = try reader.takeStruct(Elf64_Phdr, elf_header.endian); |
| 613 | return phdr; |
| 614 | } |
| 615 | |
| 616 | const phdr = try reader.takeStruct(Elf32_Phdr, elf_header.endian); |
| 617 | return .{ |
| 618 | .p_type = phdr.p_type, |
| 619 | .p_offset = phdr.p_offset, |
| 620 | .p_vaddr = phdr.p_vaddr, |
| 621 | .p_paddr = phdr.p_paddr, |
| 622 | .p_filesz = phdr.p_filesz, |
| 623 | .p_memsz = phdr.p_memsz, |
| 624 | .p_flags = phdr.p_flags, |
| 625 | .p_align = phdr.p_align, |
| 626 | }; |
| 627 | } |
| 628 | |
| 596 | 629 | pub const SectionHeaderIterator = struct { |
| 597 | 630 | elf_header: Header, |
| 598 | 631 | file_reader: *std.fs.File.Reader, |
| ... | ... | @@ -602,29 +635,50 @@ pub const SectionHeaderIterator = struct { |
| 602 | 635 | if (it.index >= it.elf_header.shnum) return null; |
| 603 | 636 | defer it.index += 1; |
| 604 | 637 | |
| 605 | | if (it.elf_header.is_64) { |
| 606 | | try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf64_Shdr) * it.index); |
| 607 | | const shdr = try it.file_reader.interface.takeStruct(Elf64_Shdr, it.elf_header.endian); |
| 608 | | return shdr; |
| 609 | | } |
| 638 | const offset = it.elf_header.shoff + if (it.elf_header.is_64) @sizeOf(Elf64_Shdr) else @sizeOf(Elf32_Shdr) * it.index; |
| 639 | try it.file_reader.seekTo(offset); |
| 610 | 640 | |
| 611 | | try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf32_Shdr) * it.index); |
| 612 | | const shdr = try it.file_reader.interface.takeStruct(Elf32_Shdr, it.elf_header.endian); |
| 613 | | return .{ |
| 614 | | .sh_name = shdr.sh_name, |
| 615 | | .sh_type = shdr.sh_type, |
| 616 | | .sh_flags = shdr.sh_flags, |
| 617 | | .sh_addr = shdr.sh_addr, |
| 618 | | .sh_offset = shdr.sh_offset, |
| 619 | | .sh_size = shdr.sh_size, |
| 620 | | .sh_link = shdr.sh_link, |
| 621 | | .sh_info = shdr.sh_info, |
| 622 | | .sh_addralign = shdr.sh_addralign, |
| 623 | | .sh_entsize = shdr.sh_entsize, |
| 624 | | }; |
| 641 | return takeShdr(&it.file_reader.interface, it.elf_header); |
| 642 | } |
| 643 | }; |
| 644 | |
| 645 | pub const SectionHeaderBufferIterator = struct { |
| 646 | elf_header: Header, |
| 647 | buf: []const u8, |
| 648 | index: usize = 0, |
| 649 | |
| 650 | pub fn next(it: *SectionHeaderBufferIterator) !?Elf64_Shdr { |
| 651 | if (it.index >= it.elf_header.shnum) return null; |
| 652 | defer it.index += 1; |
| 653 | |
| 654 | const offset = it.elf_header.shoff + if (it.elf_header.is_64) @sizeOf(Elf64_Shdr) else @sizeOf(Elf32_Shdr) * it.index; |
| 655 | var reader = std.Io.Reader.fixed(it.buf[offset..]); |
| 656 | |
| 657 | return takeShdr(&reader, it.elf_header); |
| 625 | 658 | } |
| 626 | 659 | }; |
| 627 | 660 | |
| 661 | fn takeShdr(reader: *std.Io.Reader, elf_header: Header) !?Elf64_Shdr { |
| 662 | if (elf_header.is_64) { |
| 663 | const shdr = try reader.takeStruct(Elf64_Shdr, elf_header.endian); |
| 664 | return shdr; |
| 665 | } |
| 666 | |
| 667 | const shdr = try reader.takeStruct(Elf32_Shdr, elf_header.endian); |
| 668 | return .{ |
| 669 | .sh_name = shdr.sh_name, |
| 670 | .sh_type = shdr.sh_type, |
| 671 | .sh_flags = shdr.sh_flags, |
| 672 | .sh_addr = shdr.sh_addr, |
| 673 | .sh_offset = shdr.sh_offset, |
| 674 | .sh_size = shdr.sh_size, |
| 675 | .sh_link = shdr.sh_link, |
| 676 | .sh_info = shdr.sh_info, |
| 677 | .sh_addralign = shdr.sh_addralign, |
| 678 | .sh_entsize = shdr.sh_entsize, |
| 679 | }; |
| 680 | } |
| 681 | |
| 628 | 682 | pub const ELFCLASSNONE = 0; |
| 629 | 683 | pub const ELFCLASS32 = 1; |
| 630 | 684 | pub const ELFCLASS64 = 2; |