From 5d215cc76bcac12afbda7b10ec04bbf6c5b47910 Mon Sep 17 00:00:00 2001 From: jacob gw Date: Thu, 4 Mar 2021 16:13:49 -0500 Subject: [PATCH] stage2 Elf linker: fill in bswapAllFields I moved it to std.elf since it could be used there and added test --- lib/std/elf.zig | 43 +++++++++++++++++++++++-------------------- src/link/Elf.zig | 28 ++++++++++++---------------- 2 files changed, 35 insertions(+), 36 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; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index bfef2cd12c..bbbc9e25ed 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1107,7 +1107,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { for (buf) |*phdr, i| { phdr.* = progHeaderTo32(self.program_headers.items[i]); if (foreign_endian) { - bswapAllFields(elf.Elf32_Phdr, phdr); + std.elf.bswapAllFields(elf.Elf32_Phdr, phdr); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); @@ -1119,7 +1119,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { for (buf) |*phdr, i| { phdr.* = self.program_headers.items[i]; if (foreign_endian) { - bswapAllFields(elf.Elf64_Phdr, phdr); + std.elf.bswapAllFields(elf.Elf64_Phdr, phdr); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?); @@ -1196,7 +1196,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { shdr.* = sectHeaderTo32(self.sections.items[i]); log.debug("writing section {}\n", .{shdr.*}); if (foreign_endian) { - bswapAllFields(elf.Elf32_Shdr, shdr); + std.elf.bswapAllFields(elf.Elf32_Shdr, shdr); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); @@ -1209,7 +1209,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { shdr.* = self.sections.items[i]; log.debug("writing section {}\n", .{shdr.*}); if (foreign_endian) { - bswapAllFields(elf.Elf64_Shdr, shdr); + std.elf.bswapAllFields(elf.Elf64_Shdr, shdr); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?); @@ -2787,14 +2787,14 @@ fn writeProgHeader(self: *Elf, index: usize) !void { .p32 => { var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])}; if (foreign_endian) { - bswapAllFields(elf.Elf32_Phdr, &phdr[0]); + std.elf.bswapAllFields(elf.Elf32_Phdr, &phdr[0]); } return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); }, .p64 => { var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]}; if (foreign_endian) { - bswapAllFields(elf.Elf64_Phdr, &phdr[0]); + std.elf.bswapAllFields(elf.Elf64_Phdr, &phdr[0]); } return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset); }, @@ -2808,7 +2808,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void { var shdr: [1]elf.Elf32_Shdr = undefined; shdr[0] = sectHeaderTo32(self.sections.items[index]); if (foreign_endian) { - bswapAllFields(elf.Elf32_Shdr, &shdr[0]); + std.elf.bswapAllFields(elf.Elf32_Shdr, &shdr[0]); } const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr); return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); @@ -2816,7 +2816,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void { .p64 => { var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]}; if (foreign_endian) { - bswapAllFields(elf.Elf64_Shdr, &shdr[0]); + std.elf.bswapAllFields(elf.Elf64_Shdr, &shdr[0]); } const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr); return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset); @@ -2914,7 +2914,7 @@ fn writeSymbol(self: *Elf, index: usize) !void { }, }; if (foreign_endian) { - bswapAllFields(elf.Elf32_Sym, &sym[0]); + std.elf.bswapAllFields(elf.Elf32_Sym, &sym[0]); } const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index; try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); @@ -2922,7 +2922,7 @@ fn writeSymbol(self: *Elf, index: usize) !void { .p64 => { var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]}; if (foreign_endian) { - bswapAllFields(elf.Elf64_Sym, &sym[0]); + std.elf.bswapAllFields(elf.Elf64_Sym, &sym[0]); } const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index; try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off); @@ -2953,7 +2953,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void { .st_shndx = self.global_symbols.items[i].st_shndx, }; if (foreign_endian) { - bswapAllFields(elf.Elf32_Sym, sym); + std.elf.bswapAllFields(elf.Elf32_Sym, sym); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); @@ -2972,7 +2972,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void { .st_shndx = self.global_symbols.items[i].st_shndx, }; if (foreign_endian) { - bswapAllFields(elf.Elf64_Sym, sym); + std.elf.bswapAllFields(elf.Elf64_Sym, sym); } } try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off); @@ -3188,10 +3188,6 @@ fn pwriteDbgInfoNops( try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); } -fn bswapAllFields(comptime S: type, ptr: *S) void { - @panic("TODO implement bswapAllFields"); -} - fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr { return .{ .p_type = phdr.p_type,