diff --git a/src/elf.zig b/src/elf.zig index 0d5ffdc..a0e406e 100644 --- a/src/elf.zig +++ b/src/elf.zig @@ -86,6 +86,7 @@ pub const DolMap = struct { const DolHasBSS = 1; pub fn readELF(file: std.fs.File) !DolMap { + // Create dol map var dolMap = DolMap{ .header = .{ @@ -108,7 +109,8 @@ pub fn readELF(file: std.fs.File) !DolMap { }; // Read header - const header = try file.reader().readStructEndian(ELFHeader, std.builtin.Endian.big); + const reader = file.reader(); + const header = try reader.readStructEndian(ELFHeader, std.builtin.Endian.big); try checkELFHeader(header); @@ -131,7 +133,7 @@ pub fn readELF(file: std.fs.File) !DolMap { try file.seekTo(phoff); for (0..phnum) |_| { - const programHeader = try file.reader().readStructEndian(ELFProgramHeader, std.builtin.Endian.big); + const programHeader = try reader.readStructEndian(ELFProgramHeader, std.builtin.Endian.big); // Skip non-loadable segments if (programHeader.p_type != 1) { @@ -172,7 +174,7 @@ pub fn readELF(file: std.fs.File) !DolMap { // Add as BSS segment of whatever is left between the file and memory sizes // TODO: why?! add_bss(&dolMap, programHeader.p_paddr + programHeader.p_filesz, programHeader.p_memsz - programHeader.p_filesz); - std.debug.print("Found bss segment at 0x{x}\n", .{programHeader.p_paddr + programHeader.p_filesz}); + std.debug.print("Found bss segment (TEXT) at 0x{x}\n", .{programHeader.p_paddr + programHeader.p_filesz}); } std.debug.print("Found text segment at 0x{x}\n", .{programHeader.p_vaddr}); @@ -188,7 +190,7 @@ pub fn readELF(file: std.fs.File) !DolMap { // TODO: ???? if (programHeader.p_filesz == 0) { add_bss(&dolMap, programHeader.p_paddr, programHeader.p_memsz); - std.debug.print("Found bss segment at 0x{x}\n", .{programHeader.p_vaddr}); + std.debug.print("Found bss segment (DATA) at 0x{x}\n", .{programHeader.p_vaddr}); continue; } @@ -225,6 +227,32 @@ fn add_bss(map: *DolMap, addr: u32, size: u32) void { } } +const DOLAlignment = 64; +pub fn alignSegments(map: *DolMap) void { + std.debug.print("Mapping DOL to 64 byte alignment\n", .{}); + var currentPosition = std.mem.alignForward(u32, @sizeOf(DolHeader), DOLAlignment); + + for (0..map.text_cnt) |i| { + std.debug.print(" - Mapping text segment {d} at 0x{x} -> 0x{x}\n", .{ i, map.header.text_addr[i], currentPosition }); + map.header.text_off[i] = currentPosition; + currentPosition = std.mem.alignForward(u32, currentPosition + map.header.text_size[i], DOLAlignment); + } + + for (0..map.data_cnt) |i| { + std.debug.print(" - Mapping data segment {d} at 0x{x} -> 0x{x}\n", .{ i, map.header.data_addr[i], currentPosition }); + map.header.data_off[i] = currentPosition; + currentPosition = std.mem.alignForward(u32, currentPosition + map.header.data_size[i], DOLAlignment); + } + + // Add dummy segments if no TEXT or DATA segments are present + if (map.text_cnt == 0) { + map.header.text_off[0] = std.mem.alignForward(u32, @sizeOf(DolHeader), DOLAlignment); + } + if (map.data_cnt == 0) { + map.header.data_off[0] = std.mem.alignForward(u32, @sizeOf(DolHeader), DOLAlignment); + } +} + fn checkELFHeader(header: ELFHeader) !void { // Check magic if (!std.mem.eql(u8, header.e_ident[0..4], ELFMagic)) { diff --git a/src/main.zig b/src/main.zig index 22c71a3..2977590 100644 --- a/src/main.zig +++ b/src/main.zig @@ -23,5 +23,6 @@ pub fn main() !void { // Read input const input = try std.fs.cwd().openFile(inputPath, .{}); - _ = try elf.readELF(input); + var map = try elf.readELF(input); + elf.alignSegments(&map); }