// This is just a simple elf loader, good enough to load elfs generated by devkitPPC bool ElfReader::LoadIntoMemory() { DEBUG_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); // Should we relocate? bRelocate = (header->e_type != ET_EXEC); if (bRelocate) { PanicAlert("Error: Dolphin doesn't know how to load a relocatable elf."); return false; } INFO_LOG(MASTER_LOG, "%i segments:", header->e_phnum); // Copy segments into ram. for (int i = 0; i < header->e_phnum; i++) { Elf32_Phdr* p = segments + i; INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { u32 writeAddr = p->p_vaddr; const u8* src = GetSegmentPtr(i); u32 srcSize = p->p_filesz; u32 dstSize = p->p_memsz; Memory::CopyToEmu(writeAddr, src, srcSize); if (srcSize < dstSize) Memory::Memset(writeAddr + srcSize, 0, dstSize - srcSize); // zero out bss INFO_LOG(MASTER_LOG, "Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz); } } INFO_LOG(MASTER_LOG, "Done loading."); return true; }
bool ElfReader::LoadInto(u32 vaddr) { DEBUG_LOG(MASTER_LOG,"String section: %i", header->e_shstrndx); // sectionOffsets = new u32[GetNumSections()]; // sectionAddrs = new u32[GetNumSections()]; // Should we relocate? bRelocate = (header->e_type != ET_EXEC); if (bRelocate) { DEBUG_LOG(MASTER_LOG,"Relocatable module"); entryPoint += vaddr; } else { DEBUG_LOG(MASTER_LOG,"Prerelocated executable"); } INFO_LOG(MASTER_LOG,"%i segments:", header->e_phnum); // First pass : Get the bits into RAM u32 segmentVAddr[32]; u32 baseAddress = bRelocate?vaddr:0; for (int i = 0; i < header->e_phnum; i++) { Elf32_Phdr *p = segments + i; INFO_LOG(MASTER_LOG, "Type: %i Vaddr: %08x Filesz: %i Memsz: %i ", p->p_type, p->p_vaddr, p->p_filesz, p->p_memsz); if (p->p_type == PT_LOAD) { segmentVAddr[i] = baseAddress + p->p_vaddr; u32 writeAddr = segmentVAddr[i]; const u8 *src = GetSegmentPtr(i); u8 *dst = Memory::GetPointer(writeAddr); u32 srcSize = p->p_filesz; u32 dstSize = p->p_memsz; u32 *s = (u32*)src; u32 *d = (u32*)dst; for (int j = 0; j < (int)(srcSize + 3) / 4; j++) { *d++ = /*_byteswap_ulong*/(*s++); } if (srcSize < dstSize) { //memset(dst + srcSize, 0, dstSize-srcSize); //zero out bss } INFO_LOG(MASTER_LOG,"Loadable Segment Copied to %08x, size %08x", writeAddr, p->p_memsz); } } /* LOG(MASTER_LOG,"%i sections:", header->e_shnum); for (int i=0; i<GetNumSections(); i++) { Elf32_Shdr *s = §ions[i]; const char *name = GetSectionName(i); u32 writeAddr = s->sh_addr + baseAddress; sectionOffsets[i] = writeAddr - vaddr; sectionAddrs[i] = writeAddr; if (s->sh_flags & SHF_ALLOC) { LOG(MASTER_LOG,"Data Section found: %s Sitting at %08x, size %08x", name, writeAddr, s->sh_size); } else { LOG(MASTER_LOG,"NonData Section found: %s Ignoring (size=%08x) (flags=%08x)", name, s->sh_size, s->sh_flags); } } */ INFO_LOG(MASTER_LOG,"Done loading."); return true; }