| 263 | } |
| 264 | |
| 265 | std::shared_ptr<CodeSet> ElfReader::LoadInto(Core::System& system, u32 vaddr) { |
| 266 | LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx); |
| 267 | |
| 268 | // Should we relocate? |
| 269 | relocate = (header->e_type != ET_EXEC); |
| 270 | |
| 271 | if (relocate) { |
| 272 | LOG_DEBUG(Loader, "Relocatable module"); |
| 273 | entryPoint += vaddr; |
| 274 | } else { |
| 275 | LOG_DEBUG(Loader, "Prerelocated executable"); |
| 276 | } |
| 277 | LOG_DEBUG(Loader, "{} segments:", header->e_phnum); |
| 278 | |
| 279 | // First pass : Get the bits into RAM |
| 280 | u32 base_addr = relocate ? vaddr : 0; |
| 281 | |
| 282 | u32 total_image_size = 0; |
| 283 | for (unsigned int i = 0; i < header->e_phnum; ++i) { |
| 284 | Elf32_Phdr* p = &segments[i]; |
| 285 | if (p->p_type == PT_LOAD) { |
| 286 | total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF; |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | std::vector<u8> program_image(total_image_size); |
| 291 | std::size_t current_image_position = 0; |
| 292 | |
| 293 | std::shared_ptr<CodeSet> codeset = system.Kernel().CreateCodeSet("", 0); |
| 294 | |
| 295 | for (unsigned int i = 0; i < header->e_phnum; ++i) { |
| 296 | Elf32_Phdr* p = &segments[i]; |
| 297 | LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type, |
| 298 | p->p_vaddr, p->p_filesz, p->p_memsz); |
| 299 | |
| 300 | if (p->p_type == PT_LOAD) { |
| 301 | CodeSet::Segment* codeset_segment; |
| 302 | u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); |
| 303 | if (permission_flags == (PF_R | PF_X)) { |
| 304 | codeset_segment = &codeset->CodeSegment(); |
| 305 | } else if (permission_flags == (PF_R)) { |
| 306 | codeset_segment = &codeset->RODataSegment(); |
| 307 | } else if (permission_flags == (PF_R | PF_W)) { |
| 308 | codeset_segment = &codeset->DataSegment(); |
| 309 | } else { |
| 310 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, |
| 311 | p->p_flags); |
| 312 | continue; |
| 313 | } |
| 314 | |
| 315 | if (codeset_segment->size != 0) { |
| 316 | LOG_ERROR(Loader, |
| 317 | "ELF has more than one segment of the same type. Skipping extra " |
| 318 | "segment (id {})", |
| 319 | i); |
| 320 | continue; |
| 321 | } |
| 322 | |