| 44 | } // anonymous |
| 45 | |
| 46 | ByteBuf build_elf_core(const PhysicalLayer& phys, |
| 47 | const x86_64::PageTable& user_pt, |
| 48 | const Process& p, |
| 49 | const std::vector<Vma>& vmas, |
| 50 | u64 max_bytes) |
| 51 | { |
| 52 | (void)phys; (void)p; |
| 53 | |
| 54 | // Filter to readable, non-empty VMAs and clip total size to max_bytes. |
| 55 | struct Plan { const Vma* v; u64 filesz; }; |
| 56 | std::vector<Plan> plan; |
| 57 | plan.reserve(vmas.size()); |
| 58 | u64 total_data = 0; |
| 59 | for (auto& v : vmas) { |
| 60 | if (!v.readable()) continue; |
| 61 | u64 sz = v.size(); |
| 62 | if (sz == 0) continue; |
| 63 | u64 take = std::min<u64>(sz, max_bytes > total_data ? max_bytes - total_data : 0); |
| 64 | if (take == 0) break; |
| 65 | plan.push_back({ &v, take }); |
| 66 | total_data += take; |
| 67 | } |
| 68 | |
| 69 | // Layout: [Ehdr][N × Phdr][segment data...] |
| 70 | std::size_t hdr_size = sizeof(Elf64_Ehdr) + plan.size() * sizeof(Elf64_Phdr); |
| 71 | // Align segment data to page boundary |
| 72 | std::size_t data_start = (hdr_size + 0xFFF) & ~std::size_t(0xFFF); |
| 73 | |
| 74 | ByteBuf out(data_start + total_data, 0); |
| 75 | |
| 76 | Elf64_Ehdr eh{}; |
| 77 | std::memcpy(eh.e_ident, "\x7f""ELF", 4); |
| 78 | eh.e_ident[4] = 2; // ELFCLASS64 |
| 79 | eh.e_ident[5] = 1; // ELFDATA2LSB |
| 80 | eh.e_ident[6] = 1; // EV_CURRENT |
| 81 | eh.e_type = ET_CORE; |
| 82 | eh.e_machine = EM_X86_64; |
| 83 | eh.e_version = 1; |
| 84 | eh.e_phoff = sizeof(Elf64_Ehdr); |
| 85 | eh.e_ehsize = sizeof(Elf64_Ehdr); |
| 86 | eh.e_phentsize = sizeof(Elf64_Phdr); |
| 87 | eh.e_phnum = static_cast<u16>(plan.size()); |
| 88 | std::memcpy(out.data(), &eh, sizeof(eh)); |
| 89 | |
| 90 | u64 file_off = data_start; |
| 91 | Elf64_Phdr* phdrs = reinterpret_cast<Elf64_Phdr*>(out.data() + sizeof(Elf64_Ehdr)); |
| 92 | for (std::size_t i = 0; i < plan.size(); ++i) { |
| 93 | const Vma& v = *plan[i].v; |
| 94 | u64 take = plan[i].filesz; |
| 95 | Elf64_Phdr& ph = phdrs[i]; |
| 96 | std::memset(&ph, 0, sizeof(ph)); |
| 97 | ph.p_type = PT_LOAD; |
| 98 | ph.p_flags = (v.executable() ? PF_X : 0) | |
| 99 | (v.writable() ? PF_W : 0) | |
| 100 | (v.readable() ? PF_R : 0); |
| 101 | ph.p_offset = file_off; |
| 102 | ph.p_vaddr = v.vm_start; |
| 103 | ph.p_paddr = 0; |