authorgravatar for giuseppecesarano@proton.meGiuseppe Cesarano <giuseppecesarano@proton.me> 2025-08-05 19:00:33+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-08-05 10:00:33-07:00
log3914eaf3571949718bcd986ab8129b3c9f39b1d0
treeb48ffac28a4b3d5918a39a0e458c6be325102eee
parent82961a8c9f66c03b7f1a802d2d47d26bf0af7dca
signaturebadge-check Signed by PGP key B5690EEEBB952194

std.elf: buffer header iterator API (#24691)

Closes #24666.

1 files changed, 92 insertions(+), 38 deletions(-)

lib/std/elf.zig+92-38
...@@ -502,6 +502,13 @@ pub const Header = struct {...@@ -502,6 +502,13 @@ pub const Header = struct {
502 };502 };
503 }503 }
504504
505 pub fn iterateProgramHeadersBuffer(h: Header, buf: []const u8) ProgramHeaderBufferIterator {
506 return .{
507 .elf_header = h,
508 .buf = buf,
509 };
510 }
511
505 pub fn iterateSectionHeaders(h: Header, file_reader: *std.fs.File.Reader) SectionHeaderIterator {512 pub fn iterateSectionHeaders(h: Header, file_reader: *std.fs.File.Reader) SectionHeaderIterator {
506 return .{513 return .{
507 .elf_header = h,514 .elf_header = h,
...@@ -509,6 +516,13 @@ pub const Header = struct {...@@ -509,6 +516,13 @@ pub const Header = struct {
509 };516 };
510 }517 }
511518
519 pub fn iterateSectionHeadersBuffer(h: Header, buf: []const u8) SectionHeaderBufferIterator {
520 return .{
521 .elf_header = h,
522 .buf = buf,
523 };
524 }
525
512 pub const ReadError = std.Io.Reader.Error || error{526 pub const ReadError = std.Io.Reader.Error || error{
513 InvalidElfMagic,527 InvalidElfMagic,
514 InvalidElfVersion,528 InvalidElfVersion,
...@@ -570,29 +584,48 @@ pub const ProgramHeaderIterator = struct {...@@ -570,29 +584,48 @@ pub const ProgramHeaderIterator = struct {
570 if (it.index >= it.elf_header.phnum) return null;584 if (it.index >= it.elf_header.phnum) return null;
571 defer it.index += 1;585 defer it.index += 1;
572586
573 if (it.elf_header.is_64) {587 const offset = it.elf_header.phoff + if (it.elf_header.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr) * it.index;
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;
581 try it.file_reader.seekTo(offset);588 try it.file_reader.seekTo(offset);
582 const phdr = try it.file_reader.interface.takeStruct(Elf32_Phdr, it.elf_header.endian);589
583 return .{590 return takePhdr(&it.file_reader.interface, it.elf_header);
584 .p_type = phdr.p_type,591 }
585 .p_offset = phdr.p_offset,592};
586 .p_vaddr = phdr.p_vaddr,593
587 .p_paddr = phdr.p_paddr,594pub const ProgramHeaderBufferIterator = struct {
588 .p_filesz = phdr.p_filesz,595 elf_header: Header,
589 .p_memsz = phdr.p_memsz,596 buf: []const u8,
590 .p_flags = phdr.p_flags,597 index: usize = 0,
591 .p_align = phdr.p_align,598
592 };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};
595609
610fn 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
596pub const SectionHeaderIterator = struct {629pub const SectionHeaderIterator = struct {
597 elf_header: Header,630 elf_header: Header,
598 file_reader: *std.fs.File.Reader,631 file_reader: *std.fs.File.Reader,
...@@ -602,29 +635,50 @@ pub const SectionHeaderIterator = struct {...@@ -602,29 +635,50 @@ pub const SectionHeaderIterator = struct {
602 if (it.index >= it.elf_header.shnum) return null;635 if (it.index >= it.elf_header.shnum) return null;
603 defer it.index += 1;636 defer it.index += 1;
604637
605 if (it.elf_header.is_64) {638 const offset = it.elf_header.shoff + if (it.elf_header.is_64) @sizeOf(Elf64_Shdr) else @sizeOf(Elf32_Shdr) * it.index;
606 try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf64_Shdr) * it.index);639 try it.file_reader.seekTo(offset);
607 const shdr = try it.file_reader.interface.takeStruct(Elf64_Shdr, it.elf_header.endian);
608 return shdr;
609 }
610640
611 try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf32_Shdr) * it.index);641 return takeShdr(&it.file_reader.interface, it.elf_header);
612 const shdr = try it.file_reader.interface.takeStruct(Elf32_Shdr, it.elf_header.endian);642 }
613 return .{643};
614 .sh_name = shdr.sh_name,644
615 .sh_type = shdr.sh_type,645pub const SectionHeaderBufferIterator = struct {
616 .sh_flags = shdr.sh_flags,646 elf_header: Header,
617 .sh_addr = shdr.sh_addr,647 buf: []const u8,
618 .sh_offset = shdr.sh_offset,648 index: usize = 0,
619 .sh_size = shdr.sh_size,649
620 .sh_link = shdr.sh_link,650 pub fn next(it: *SectionHeaderBufferIterator) !?Elf64_Shdr {
621 .sh_info = shdr.sh_info,651 if (it.index >= it.elf_header.shnum) return null;
622 .sh_addralign = shdr.sh_addralign,652 defer it.index += 1;
623 .sh_entsize = shdr.sh_entsize,653
624 };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};
627660
661fn 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
628pub const ELFCLASSNONE = 0;682pub const ELFCLASSNONE = 0;
629pub const ELFCLASS32 = 1;683pub const ELFCLASS32 = 1;
630pub const ELFCLASS64 = 2;684pub const ELFCLASS64 = 2;