add segment aligning for DOL

This commit is contained in:
Hamcha 2024-05-05 14:16:52 +02:00
parent ddf0fa0f69
commit 29a6e5e858
Signed by: hamcha
GPG key ID: 1669C533B8CF6D89
2 changed files with 34 additions and 5 deletions

View file

@ -86,6 +86,7 @@ pub const DolMap = struct {
const DolHasBSS = 1; const DolHasBSS = 1;
pub fn readELF(file: std.fs.File) !DolMap { pub fn readELF(file: std.fs.File) !DolMap {
// Create dol map // Create dol map
var dolMap = DolMap{ var dolMap = DolMap{
.header = .{ .header = .{
@ -108,7 +109,8 @@ pub fn readELF(file: std.fs.File) !DolMap {
}; };
// Read header // 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); try checkELFHeader(header);
@ -131,7 +133,7 @@ pub fn readELF(file: std.fs.File) !DolMap {
try file.seekTo(phoff); try file.seekTo(phoff);
for (0..phnum) |_| { 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 // Skip non-loadable segments
if (programHeader.p_type != 1) { 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 // Add as BSS segment of whatever is left between the file and memory sizes
// TODO: why?! // TODO: why?!
add_bss(&dolMap, programHeader.p_paddr + programHeader.p_filesz, programHeader.p_memsz - programHeader.p_filesz); 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}); 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: ???? // TODO: ????
if (programHeader.p_filesz == 0) { if (programHeader.p_filesz == 0) {
add_bss(&dolMap, programHeader.p_paddr, programHeader.p_memsz); 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; 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 { fn checkELFHeader(header: ELFHeader) !void {
// Check magic // Check magic
if (!std.mem.eql(u8, header.e_ident[0..4], ELFMagic)) { if (!std.mem.eql(u8, header.e_ident[0..4], ELFMagic)) {

View file

@ -23,5 +23,6 @@ pub fn main() !void {
// Read input // Read input
const input = try std.fs.cwd().openFile(inputPath, .{}); const input = try std.fs.cwd().openFile(inputPath, .{});
_ = try elf.readELF(input); var map = try elf.readELF(input);
elf.alignSegments(&map);
} }