authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-03-04 16:13:49-05:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-03-07 23:18:26+02:00
log5d215cc76bcac12afbda7b10ec04bbf6c5b47910
tree90e0accadd021cc11bea3e92ba96a373904843b6
parent0447a2c041a4be843251396e668e074186aa49a2

stage2 Elf linker: fill in bswapAllFields

I moved it to std.elf since it could be used there and added test

2 files changed, 35 insertions(+), 36 deletions(-)

lib/std/elf.zig+23-20
...@@ -422,16 +422,8 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {...@@ -422,16 +422,8 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {
422 if (self.elf_header.endian == std.builtin.endian) return phdr;422 if (self.elf_header.endian == std.builtin.endian) return phdr;
423423
424 // Convert fields to native endianness.424 // Convert fields to native endianness.
425 return Elf64_Phdr{425 bswapAllFields(Elf64_Phdr, &phdr);
426 .p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),426 return phdr;
427 .p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
428 .p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
429 .p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
430 .p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
431 .p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
432 .p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
433 .p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
434 };
435 }427 }
436428
437 var phdr: Elf32_Phdr = undefined;429 var phdr: Elf32_Phdr = undefined;
...@@ -442,16 +434,7 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {...@@ -442,16 +434,7 @@ pub fn ProgramHeaderIterator(ParseSource: anytype) type {
442 // ELF endianness does NOT match native endianness.434 // ELF endianness does NOT match native endianness.
443 if (self.elf_header.endian != std.builtin.endian) {435 if (self.elf_header.endian != std.builtin.endian) {
444 // Convert fields to native endianness.436 // Convert fields to native endianness.
445 phdr = .{437 bswapAllFields(Elf32_Phdr, &phdr);
446 .p_type = @byteSwap(@TypeOf(phdr.p_type), phdr.p_type),
447 .p_offset = @byteSwap(@TypeOf(phdr.p_offset), phdr.p_offset),
448 .p_vaddr = @byteSwap(@TypeOf(phdr.p_vaddr), phdr.p_vaddr),
449 .p_paddr = @byteSwap(@TypeOf(phdr.p_paddr), phdr.p_paddr),
450 .p_filesz = @byteSwap(@TypeOf(phdr.p_filesz), phdr.p_filesz),
451 .p_memsz = @byteSwap(@TypeOf(phdr.p_memsz), phdr.p_memsz),
452 .p_flags = @byteSwap(@TypeOf(phdr.p_flags), phdr.p_flags),
453 .p_align = @byteSwap(@TypeOf(phdr.p_align), phdr.p_align),
454 };
455 }438 }
456439
457 // Convert 32-bit header to 64-bit.440 // Convert 32-bit header to 64-bit.
...@@ -562,6 +545,26 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {...@@ -562,6 +545,26 @@ pub fn int32(need_bswap: bool, int_32: anytype, comptime Int64: anytype) Int64 {
562 }545 }
563}546}
564547
548pub fn bswapAllFields(comptime S: type, ptr: *S) void {
549 if (@typeInfo(S) != .Struct) @compileError("bswapAllFields expects a struct as the first argument");
550 inline for (std.meta.fields(S)) |f| {
551 @field(ptr, f.name) = @byteSwap(f.field_type, @field(ptr, f.name));
552 }
553}
554test "bswapAllFields" {
555 var s: Elf32_Chdr = .{
556 .ch_type = 0x12341234,
557 .ch_size = 0x56785678,
558 .ch_addralign = 0x12124242,
559 };
560 bswapAllFields(Elf32_Chdr, &s);
561 std.testing.expectEqual(Elf32_Chdr{
562 .ch_type = 0x34123412,
563 .ch_size = 0x78567856,
564 .ch_addralign = 0x42421212,
565 }, s);
566}
567
565pub const EI_NIDENT = 16;568pub const EI_NIDENT = 16;
566569
567pub const EI_CLASS = 4;570pub const EI_CLASS = 4;
src/link/Elf.zig+12-16
...@@ -1107,7 +1107,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1107,7 +1107,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1107 for (buf) |*phdr, i| {1107 for (buf) |*phdr, i| {
1108 phdr.* = progHeaderTo32(self.program_headers.items[i]);1108 phdr.* = progHeaderTo32(self.program_headers.items[i]);
1109 if (foreign_endian) {1109 if (foreign_endian) {
1110 bswapAllFields(elf.Elf32_Phdr, phdr);1110 std.elf.bswapAllFields(elf.Elf32_Phdr, phdr);
1111 }1111 }
1112 }1112 }
1113 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);1113 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
...@@ -1119,7 +1119,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1119,7 +1119,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1119 for (buf) |*phdr, i| {1119 for (buf) |*phdr, i| {
1120 phdr.* = self.program_headers.items[i];1120 phdr.* = self.program_headers.items[i];
1121 if (foreign_endian) {1121 if (foreign_endian) {
1122 bswapAllFields(elf.Elf64_Phdr, phdr);1122 std.elf.bswapAllFields(elf.Elf64_Phdr, phdr);
1123 }1123 }
1124 }1124 }
1125 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);1125 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.phdr_table_offset.?);
...@@ -1196,7 +1196,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1196,7 +1196,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1196 shdr.* = sectHeaderTo32(self.sections.items[i]);1196 shdr.* = sectHeaderTo32(self.sections.items[i]);
1197 log.debug("writing section {}\n", .{shdr.*});1197 log.debug("writing section {}\n", .{shdr.*});
1198 if (foreign_endian) {1198 if (foreign_endian) {
1199 bswapAllFields(elf.Elf32_Shdr, shdr);1199 std.elf.bswapAllFields(elf.Elf32_Shdr, shdr);
1200 }1200 }
1201 }1201 }
1202 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);1202 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
...@@ -1209,7 +1209,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1209,7 +1209,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1209 shdr.* = self.sections.items[i];1209 shdr.* = self.sections.items[i];
1210 log.debug("writing section {}\n", .{shdr.*});1210 log.debug("writing section {}\n", .{shdr.*});
1211 if (foreign_endian) {1211 if (foreign_endian) {
1212 bswapAllFields(elf.Elf64_Shdr, shdr);1212 std.elf.bswapAllFields(elf.Elf64_Shdr, shdr);
1213 }1213 }
1214 }1214 }
1215 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);1215 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), self.shdr_table_offset.?);
...@@ -2787,14 +2787,14 @@ fn writeProgHeader(self: *Elf, index: usize) !void {...@@ -2787,14 +2787,14 @@ fn writeProgHeader(self: *Elf, index: usize) !void {
2787 .p32 => {2787 .p32 => {
2788 var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])};2788 var phdr = [1]elf.Elf32_Phdr{progHeaderTo32(self.program_headers.items[index])};
2789 if (foreign_endian) {2789 if (foreign_endian) {
2790 bswapAllFields(elf.Elf32_Phdr, &phdr[0]);2790 std.elf.bswapAllFields(elf.Elf32_Phdr, &phdr[0]);
2791 }2791 }
2792 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);2792 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);
2793 },2793 },
2794 .p64 => {2794 .p64 => {
2795 var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]};2795 var phdr = [1]elf.Elf64_Phdr{self.program_headers.items[index]};
2796 if (foreign_endian) {2796 if (foreign_endian) {
2797 bswapAllFields(elf.Elf64_Phdr, &phdr[0]);2797 std.elf.bswapAllFields(elf.Elf64_Phdr, &phdr[0]);
2798 }2798 }
2799 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);2799 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&phdr), offset);
2800 },2800 },
...@@ -2808,7 +2808,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void {...@@ -2808,7 +2808,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void {
2808 var shdr: [1]elf.Elf32_Shdr = undefined;2808 var shdr: [1]elf.Elf32_Shdr = undefined;
2809 shdr[0] = sectHeaderTo32(self.sections.items[index]);2809 shdr[0] = sectHeaderTo32(self.sections.items[index]);
2810 if (foreign_endian) {2810 if (foreign_endian) {
2811 bswapAllFields(elf.Elf32_Shdr, &shdr[0]);2811 std.elf.bswapAllFields(elf.Elf32_Shdr, &shdr[0]);
2812 }2812 }
2813 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr);2813 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf32_Shdr);
2814 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);2814 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);
...@@ -2816,7 +2816,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void {...@@ -2816,7 +2816,7 @@ fn writeSectHeader(self: *Elf, index: usize) !void {
2816 .p64 => {2816 .p64 => {
2817 var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]};2817 var shdr = [1]elf.Elf64_Shdr{self.sections.items[index]};
2818 if (foreign_endian) {2818 if (foreign_endian) {
2819 bswapAllFields(elf.Elf64_Shdr, &shdr[0]);2819 std.elf.bswapAllFields(elf.Elf64_Shdr, &shdr[0]);
2820 }2820 }
2821 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr);2821 const offset = self.shdr_table_offset.? + index * @sizeOf(elf.Elf64_Shdr);
2822 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);2822 return self.base.file.?.pwriteAll(mem.sliceAsBytes(&shdr), offset);
...@@ -2914,7 +2914,7 @@ fn writeSymbol(self: *Elf, index: usize) !void {...@@ -2914,7 +2914,7 @@ fn writeSymbol(self: *Elf, index: usize) !void {
2914 },2914 },
2915 };2915 };
2916 if (foreign_endian) {2916 if (foreign_endian) {
2917 bswapAllFields(elf.Elf32_Sym, &sym[0]);2917 std.elf.bswapAllFields(elf.Elf32_Sym, &sym[0]);
2918 }2918 }
2919 const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;2919 const off = syms_sect.sh_offset + @sizeOf(elf.Elf32_Sym) * index;
2920 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2920 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
...@@ -2922,7 +2922,7 @@ fn writeSymbol(self: *Elf, index: usize) !void {...@@ -2922,7 +2922,7 @@ fn writeSymbol(self: *Elf, index: usize) !void {
2922 .p64 => {2922 .p64 => {
2923 var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};2923 var sym = [1]elf.Elf64_Sym{self.local_symbols.items[index]};
2924 if (foreign_endian) {2924 if (foreign_endian) {
2925 bswapAllFields(elf.Elf64_Sym, &sym[0]);2925 std.elf.bswapAllFields(elf.Elf64_Sym, &sym[0]);
2926 }2926 }
2927 const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;2927 const off = syms_sect.sh_offset + @sizeOf(elf.Elf64_Sym) * index;
2928 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);2928 try self.base.file.?.pwriteAll(mem.sliceAsBytes(sym[0..1]), off);
...@@ -2953,7 +2953,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2953,7 +2953,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
2953 .st_shndx = self.global_symbols.items[i].st_shndx,2953 .st_shndx = self.global_symbols.items[i].st_shndx,
2954 };2954 };
2955 if (foreign_endian) {2955 if (foreign_endian) {
2956 bswapAllFields(elf.Elf32_Sym, sym);2956 std.elf.bswapAllFields(elf.Elf32_Sym, sym);
2957 }2957 }
2958 }2958 }
2959 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);2959 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);
...@@ -2972,7 +2972,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {...@@ -2972,7 +2972,7 @@ fn writeAllGlobalSymbols(self: *Elf) !void {
2972 .st_shndx = self.global_symbols.items[i].st_shndx,2972 .st_shndx = self.global_symbols.items[i].st_shndx,
2973 };2973 };
2974 if (foreign_endian) {2974 if (foreign_endian) {
2975 bswapAllFields(elf.Elf64_Sym, sym);2975 std.elf.bswapAllFields(elf.Elf64_Sym, sym);
2976 }2976 }
2977 }2977 }
2978 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);2978 try self.base.file.?.pwriteAll(mem.sliceAsBytes(buf), global_syms_off);
...@@ -3188,10 +3188,6 @@ fn pwriteDbgInfoNops(...@@ -3188,10 +3188,6 @@ fn pwriteDbgInfoNops(
3188 try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size);3188 try self.base.file.?.pwritevAll(vecs[0..vec_index], offset - prev_padding_size);
3189}3189}
31903190
3191fn bswapAllFields(comptime S: type, ptr: *S) void {
3192 @panic("TODO implement bswapAllFields");
3193}
3194
3195fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {3191fn progHeaderTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {
3196 return .{3192 return .{
3197 .p_type = phdr.p_type,3193 .p_type = phdr.p_type,