| 20 | } |
| 21 | |
| 22 | elf_info_t LoadELFSegments(process_t* proc, void* _elf, uintptr_t base){ |
| 23 | uint8_t* elf = reinterpret_cast<uint8_t*>(_elf); |
| 24 | CPU* cpuLocal = GetCPULocal(); |
| 25 | |
| 26 | elf_info_t elfInfo; |
| 27 | memset(&elfInfo, 0, sizeof(elfInfo)); |
| 28 | |
| 29 | if(!VerifyELF(elf)) return elfInfo; // Invalid ELF Header |
| 30 | |
| 31 | elf64_header_t elfHdr = *(elf64_header_t*)elf; |
| 32 | |
| 33 | elfInfo.entry = base + elfHdr.entry; |
| 34 | elfInfo.phEntrySize = elfHdr.phEntrySize; |
| 35 | elfInfo.phNum = elfHdr.phNum; |
| 36 | |
| 37 | for(uint16_t i = 0; i < elfHdr.phNum; i++){ |
| 38 | elf64_program_header_t elfPHdr = *((elf64_program_header_t*)(elf + elfHdr.phOff + i * elfHdr.phEntrySize)); |
| 39 | |
| 40 | if(elfPHdr.memSize == 0) continue; |
| 41 | for(unsigned j = 0; j < ((elfPHdr.memSize + (elfPHdr.vaddr & 0xFFF) + 0xFFF) >> 12); j++){ |
| 42 | uint64_t phys = Memory::AllocatePhysicalMemoryBlock(); |
| 43 | Memory::MapVirtualMemory4K(phys, base + (elfPHdr.vaddr & ~0xFFFUL) + j * PAGE_SIZE_4K, 1, proc->addressSpace); |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | char* linkPath = nullptr; |
| 48 | |
| 49 | for(int i = 0; i < elfHdr.phNum; i++){ |
| 50 | elf64_program_header_t elfPHdr = *((elf64_program_header_t*)(elf + elfHdr.phOff + i * elfHdr.phEntrySize)); |
| 51 | |
| 52 | if(elfPHdr.type == PT_LOAD && elfPHdr.memSize > 0){ |
| 53 | acquireLock(&cpuLocal->runQueueLock); |
| 54 | asm("cli"); |
| 55 | asm volatile("mov %%rax, %%cr3" :: "a"(proc->addressSpace->pml4Phys)); |
| 56 | memset((void*)(base + elfPHdr.vaddr),0,elfPHdr.memSize); |
| 57 | memcpy((void*)(base + elfPHdr.vaddr),(void*)(elf + elfPHdr.offset), elfPHdr.fileSize); |
| 58 | asm volatile("mov %%rax, %%cr3" :: "a"(Scheduler::GetCurrentProcess()->addressSpace->pml4Phys)); |
| 59 | asm("sti"); |
| 60 | releaseLock(&cpuLocal->runQueueLock); |
| 61 | } else if (elfPHdr.type == PT_PHDR) { |
| 62 | elfInfo.pHdrSegment = base + elfPHdr.vaddr; |
| 63 | } else if(elfPHdr.type == PT_INTERP){ |
| 64 | linkPath = (char*)kmalloc(elfPHdr.fileSize + 1); |
| 65 | strncpy(linkPath, (char*)(elf + elfPHdr.offset), elfPHdr.fileSize); |
| 66 | linkPath[elfPHdr.fileSize] = 0; // Null terminate the path |
| 67 | |
| 68 | elfInfo.linkerPath = linkPath; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | return elfInfo; |
| 73 | } |
no test coverage detected