aboutsummaryrefslogtreecommitdiff
path: root/lib/std/elf.zig
diff options
context:
space:
mode:
authorjacob gw <jacoblevgw@gmail.com>2021-03-04 16:13:49 -0500
committerVeikka Tuominen <git@vexu.eu>2021-03-07 23:18:26 +0200
commit5d215cc76bcac12afbda7b10ec04bbf6c5b47910 (patch)
tree90e0accadd021cc11bea3e92ba96a373904843b6 /lib/std/elf.zig
parent0447a2c041a4be843251396e668e074186aa49a2 (diff)
downloadzig-5d215cc76bcac12afbda7b10ec04bbf6c5b47910.tar.gz
zig-5d215cc76bcac12afbda7b10ec04bbf6c5b47910.zip
stage2 Elf linker: fill in bswapAllFields
I moved it to std.elf since it could be used there and added test
Diffstat (limited to 'lib/std/elf.zig')
-rw-r--r--lib/std/elf.zig43
1 files changed, 23 insertions, 20 deletions
diff --git a/lib/std/elf.zig b/lib/std/elf.zig
index e644c6631a..26674288a4 100644
--- a/lib/std/elf.zig
+++ b/lib/std/elf.zig
@@ -422,16 +422,8 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {
if (self.elf_header.endian == std.builtin.endian) return phdr;
// Convert fields to native endianness.
- return Elf64_Phdr{
- .p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
- .p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
- .p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
- .p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
- .p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
- .p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
- .p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
- .p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
- };
+ bswapAllFields(Elf64_Phdr, &phdr);
+ return phdr;
}
var phdr: Elf32_Phdr = undefined;
@@ -442,16 +434,7 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {
// ELF endianness does NOT match native endianness.
if (self.elf_header.endian != std.builtin.endian) {
// Convert fields to native endianness.
- phdr = .{
- .p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
- .p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
- .p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
- .p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
- .p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
- .p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
- .p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
- .p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
- };
+ bswapAllFields(Elf32_Phdr, &phdr);
}
// Convert 32-bit header to 64-bit.
@@ -562,6 +545,26 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
}
}
+pub fn bswapAllFields(comptime S: type, ptr: *S) void {
+ if (@typeInfo(S) != .Struct) @compileError("bswapAllFields expects a struct as the first argument");
+ inline for (std.meta.fields(S)) |f| {
+ @field(ptr, f.name) = @byteSwap(f.field_type, @field(ptr, f.name));
+ }
+}
+test "bswapAllFields" {
+ var s: Elf32_Chdr = .{
+ .ch_type = 0x12341234,
+ .ch_size = 0x56785678,
+ .ch_addralign = 0x12124242,
+ };
+ bswapAllFields(Elf32_Chdr, &s);
+ std.testing.expectEqual(Elf32_Chdr{
+ .ch_type = 0x34123412,
+ .ch_size = 0x78567856,
+ .ch_addralign = 0x42421212,
+ }, s);
+}
+
pub const EI_NIDENT = 16;
pub const EI_CLASS = 4;