const std = @import("std"); const elf = std.elf; const Allocator = std.mem.Allocator; const root = @import("root"); const Block = root.Block; pub fn create_elf(allocator: Allocator, block: Block) ![]u8 { _ = block; const base_addr = 0x10000000; const elf_header: elf.Elf64_Ehdr = .{ .e_ident = elf.MAGIC.* ++ [_]u8{ elf.ELFCLASS64, // EI_CLASS elf.ELFDATA2LSB, // EI_DATA 1, // EI_VERSION @intFromEnum(elf.OSABI.NONE), // EI_OSABI 0, // EI_ABIVERSION } ++ [1]u8{0} ** 7, // EI_PAD .e_type = .EXEC, .e_machine = elf.EM.RISCV, .e_version = 1, .e_entry = base_addr + @sizeOf(elf.Elf64_Ehdr) + @sizeOf(elf.Elf64_Phdr), // we place the code directly after the headers .e_phoff = @sizeOf(elf.Elf64_Ehdr), // we place the program header(s) directly after the elf header .e_shoff = 0, .e_flags = 0, // ? .e_ehsize = @sizeOf(elf.Elf64_Ehdr), .e_phentsize = @sizeOf(elf.Elf64_Phdr), .e_phnum = 1, .e_shentsize = @sizeOf(elf.Elf64_Shdr), .e_shnum = 0, .e_shstrndx = 0, }; const program_header: elf.Elf64_Phdr = .{ .p_type = elf.PT_LOAD, .p_flags = elf.PF_R | elf.PF_X, .p_offset = 0, .p_vaddr = base_addr, .p_paddr = base_addr, .p_filesz = @sizeOf(elf.Elf64_Ehdr) + @sizeOf(elf.Elf64_Phdr) + 40, .p_memsz = @sizeOf(elf.Elf64_Ehdr) + @sizeOf(elf.Elf64_Phdr) + 40, .p_align = 0x1000, }; var output_buffer: std.ArrayList(u8) = .init(allocator); errdefer output_buffer.deinit(); const output = output_buffer.writer(); try output.writeAll(std.mem.asBytes(&elf_header)); try output.writeAll(std.mem.asBytes(&program_header)); for (0..10) |_| try output.writeAll(&std.mem.toBytes(@as(u32, 0x13))); return output_buffer.toOwnedSlice(); }