diff options
| author | Giuseppe Cesarano <giuseppecesarano@proton.me> | 2025-08-05 19:00:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-05 10:00:33 -0700 |
| commit | 3914eaf3571949718bcd986ab8129b3c9f39b1d0 (patch) | |
| tree | b48ffac28a4b3d5918a39a0e458c6be325102eee /lib/std/elf.zig | |
| parent | 82961a8c9f66c03b7f1a802d2d47d26bf0af7dca (diff) | |
| download | zig-3914eaf3571949718bcd986ab8129b3c9f39b1d0.tar.gz zig-3914eaf3571949718bcd986ab8129b3c9f39b1d0.zip | |
std.elf: buffer header iterator API (#24691)
Closes #24666.
Diffstat (limited to 'lib/std/elf.zig')
| -rw-r--r-- | lib/std/elf.zig | 130 |
1 files changed, 92 insertions, 38 deletions
diff --git a/lib/std/elf.zig b/lib/std/elf.zig index 2583e83d19..0be6e6d0a2 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -502,6 +502,13 @@ pub const Header = struct { }; } + pub fn iterateProgramHeadersBuffer(h: Header, buf: []const u8) ProgramHeaderBufferIterator { + return .{ + .elf_header = h, + .buf = buf, + }; + } + pub fn iterateSectionHeaders(h: Header, file_reader: *std.fs.File.Reader) SectionHeaderIterator { return .{ .elf_header = h, @@ -509,6 +516,13 @@ pub const Header = struct { }; } + pub fn iterateSectionHeadersBuffer(h: Header, buf: []const u8) SectionHeaderBufferIterator { + return .{ + .elf_header = h, + .buf = buf, + }; + } + pub const ReadError = std.Io.Reader.Error || error{ InvalidElfMagic, InvalidElfVersion, @@ -570,29 +584,48 @@ pub const ProgramHeaderIterator = struct { if (it.index >= it.elf_header.phnum) return null; defer it.index += 1; - if (it.elf_header.is_64) { - const offset = it.elf_header.phoff + @sizeOf(Elf64_Phdr) * it.index; - try it.file_reader.seekTo(offset); - const phdr = try it.file_reader.interface.takeStruct(Elf64_Phdr, it.elf_header.endian); - return phdr; - } - - const offset = it.elf_header.phoff + @sizeOf(Elf32_Phdr) * it.index; + const offset = it.elf_header.phoff + if (it.elf_header.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr) * it.index; try it.file_reader.seekTo(offset); - const phdr = try it.file_reader.interface.takeStruct(Elf32_Phdr, it.elf_header.endian); - return .{ - .p_type = phdr.p_type, - .p_offset = phdr.p_offset, - .p_vaddr = phdr.p_vaddr, - .p_paddr = phdr.p_paddr, - .p_filesz = phdr.p_filesz, - .p_memsz = phdr.p_memsz, - .p_flags = phdr.p_flags, - .p_align = phdr.p_align, - }; + + return takePhdr(&it.file_reader.interface, it.elf_header); + } +}; + +pub const ProgramHeaderBufferIterator = struct { + elf_header: Header, + buf: []const u8, + index: usize = 0, + + pub fn next(it: *ProgramHeaderBufferIterator) !?Elf64_Phdr { + if (it.index >= it.elf_header.phnum) return null; + defer it.index += 1; + + const offset = it.elf_header.phoff + if (it.elf_header.is_64) @sizeOf(Elf64_Phdr) else @sizeOf(Elf32_Phdr) * it.index; + var reader = std.Io.Reader.fixed(it.buf[offset..]); + + return takePhdr(&reader, it.elf_header); } }; +fn takePhdr(reader: *std.io.Reader, elf_header: Header) !?Elf64_Phdr { + if (elf_header.is_64) { + const phdr = try reader.takeStruct(Elf64_Phdr, elf_header.endian); + return phdr; + } + + const phdr = try reader.takeStruct(Elf32_Phdr, elf_header.endian); + return .{ + .p_type = phdr.p_type, + .p_offset = phdr.p_offset, + .p_vaddr = phdr.p_vaddr, + .p_paddr = phdr.p_paddr, + .p_filesz = phdr.p_filesz, + .p_memsz = phdr.p_memsz, + .p_flags = phdr.p_flags, + .p_align = phdr.p_align, + }; +} + pub const SectionHeaderIterator = struct { elf_header: Header, file_reader: *std.fs.File.Reader, @@ -602,29 +635,50 @@ pub const SectionHeaderIterator = struct { if (it.index >= it.elf_header.shnum) return null; defer it.index += 1; - if (it.elf_header.is_64) { - try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf64_Shdr) * it.index); - const shdr = try it.file_reader.interface.takeStruct(Elf64_Shdr, it.elf_header.endian); - return shdr; - } + const offset = it.elf_header.shoff + if (it.elf_header.is_64) @sizeOf(Elf64_Shdr) else @sizeOf(Elf32_Shdr) * it.index; + try it.file_reader.seekTo(offset); - try it.file_reader.seekTo(it.elf_header.shoff + @sizeOf(Elf32_Shdr) * it.index); - const shdr = try it.file_reader.interface.takeStruct(Elf32_Shdr, it.elf_header.endian); - return .{ - .sh_name = shdr.sh_name, - .sh_type = shdr.sh_type, - .sh_flags = shdr.sh_flags, - .sh_addr = shdr.sh_addr, - .sh_offset = shdr.sh_offset, - .sh_size = shdr.sh_size, - .sh_link = shdr.sh_link, - .sh_info = shdr.sh_info, - .sh_addralign = shdr.sh_addralign, - .sh_entsize = shdr.sh_entsize, - }; + return takeShdr(&it.file_reader.interface, it.elf_header); + } +}; + +pub const SectionHeaderBufferIterator = struct { + elf_header: Header, + buf: []const u8, + index: usize = 0, + + pub fn next(it: *SectionHeaderBufferIterator) !?Elf64_Shdr { + if (it.index >= it.elf_header.shnum) return null; + defer it.index += 1; + + const offset = it.elf_header.shoff + if (it.elf_header.is_64) @sizeOf(Elf64_Shdr) else @sizeOf(Elf32_Shdr) * it.index; + var reader = std.Io.Reader.fixed(it.buf[offset..]); + + return takeShdr(&reader, it.elf_header); } }; +fn takeShdr(reader: *std.Io.Reader, elf_header: Header) !?Elf64_Shdr { + if (elf_header.is_64) { + const shdr = try reader.takeStruct(Elf64_Shdr, elf_header.endian); + return shdr; + } + + const shdr = try reader.takeStruct(Elf32_Shdr, elf_header.endian); + return .{ + .sh_name = shdr.sh_name, + .sh_type = shdr.sh_type, + .sh_flags = shdr.sh_flags, + .sh_addr = shdr.sh_addr, + .sh_offset = shdr.sh_offset, + .sh_size = shdr.sh_size, + .sh_link = shdr.sh_link, + .sh_info = shdr.sh_info, + .sh_addralign = shdr.sh_addralign, + .sh_entsize = shdr.sh_entsize, + }; +} + pub const ELFCLASSNONE = 0; pub const ELFCLASS32 = 1; pub const ELFCLASS64 = 2; |
