bool Loader::readHeaders() { MutexLock lock(program_binary_lock_); hdr_ = new Elf::Ehdr; if(readFromBinary((char*)hdr_, 0, sizeof(Elf::Ehdr))) { debug(LOADER, "Loader::readHeaders: ERROR! The headers could not be load.\n"); return false; } //checking elf-magic-numbers, format (32/64bit) and a few more things if (!Elf::headerCorrect(hdr_)) { debug(LOADER, "Loader::readHeaders: ERROR! The headers are invalid.\n"); return false; } if(sizeof(Elf::Phdr) != hdr_->e_phentsize) { debug(LOADER, "Expected program header size does not match advertised program header size\n"); return false; } phdrs_.resize(hdr_->e_phnum); if(readFromBinary(reinterpret_cast<char*>(&phdrs_[0]), hdr_->e_phoff, hdr_->e_phnum*sizeof(Elf::Phdr))) { return false; } if(!prepareHeaders()) { debug(LOADER, "Loader::readHeaders: ERROR! There are no valid sections in the binary.\n"); return false; } return true; }
void BitmapFont::read(const string& filename) { string filePath = filename; for (auto i = filePath.begin(); i != filePath.end(); ++i) { if (*i == '\\') *i = '/'; } fileName = filePath; auto lastPathSeparator = filePath.find_last_of('/'); if (lastPathSeparator != string::npos) basePath = filePath.substr(0, lastPathSeparator) + "/"; else basePath = ""; #ifdef WIN32 for (auto i = filePath.begin(); i != filePath.end(); ++i) { if (*i == '/') *i = '\\'; } #endif std::ifstream ifs(filePath, std::ios_base::in | std::ios_base::binary); if (!ifs.good()) throw io::FileNotFoundException(filename); string buffer = string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>()); if (isBinaryBmfont(buffer)) readFromBinary(filename, buffer); else if (isXmlBmfont(buffer)) readFromXml(filename, buffer); else if (isTextBmfont(buffer)) readFromText(filename, buffer); else throw io::BadFileFormatException("unknown bitmap font format"); }
void Loader::loadPage(pointer virtual_address) { debug(LOADER, "Loader:loadPage: Request to load the page for address %p.\n", (void*)virtual_address); const pointer virt_page_start_addr = virtual_address & ~(PAGE_SIZE - 1); const pointer virt_page_end_addr = virt_page_start_addr + PAGE_SIZE; bool found_page_content = false; // get a new page for the mapping size_t ppn = PageManager::instance()->allocPPN(); program_binary_lock_.acquire(); // Iterate through all sections and load the ones intersecting into the page. for(ustl::list<Elf::Phdr>::iterator it = phdrs_.begin(); it != phdrs_.end(); it++) { if((*it).p_vaddr < virt_page_end_addr) { if((*it).p_vaddr + (*it).p_filesz > virt_page_start_addr) { const pointer virt_start_addr = ustl::max(virt_page_start_addr, (*it).p_vaddr); const size_t virt_offs_on_page = virt_start_addr - virt_page_start_addr; const l_off_t bin_start_addr = (*it).p_offset + (virt_start_addr - (*it).p_vaddr); const size_t bytes_to_load = ustl::min(virt_page_end_addr, (*it).p_vaddr + (*it).p_filesz) - virt_start_addr; //debug(LOADER, "Loader::loadPage: Loading %d bytes from binary address %p to virtual address %p\n", // bytes_to_load, bin_start_addr, virt_start_addr); if(readFromBinary((char *)ArchMemory::getIdentAddressOfPPN(ppn) + virt_offs_on_page, bin_start_addr, bytes_to_load)) { program_binary_lock_.release(); PageManager::instance()->freePPN(ppn); debug(LOADER, "ERROR! Some parts of the content could not be loaded from the binary.\n"); Syscall::exit(999); } found_page_content = true; } else if((*it).p_vaddr + (*it).p_memsz > virt_page_start_addr) { found_page_content = true; } } } program_binary_lock_.release(); if(!found_page_content) { PageManager::instance()->freePPN(ppn); debug(LOADER, "Loader::loadPage: ERROR! No section refers to the given address.\n"); Syscall::exit(666); } bool page_mapped = arch_memory_.mapPage(virt_page_start_addr / PAGE_SIZE, ppn, true); if (!page_mapped) { debug(LOADER, "Loader::loadPage: The page has been mapped by someone else.\n"); PageManager::instance()->freePPN(ppn); } debug(LOADER, "Loader::loadPage: Load request for address %p has been successfully finished.\n", (void*)virtual_address); }
bool Loader::loadDebugInfoIfAvailable() { assert(!userspace_debug_info_ && "You may not load User Debug Info twice!"); debug(USERTRACE, "loadDebugInfoIfAvailable start\n"); if (sizeof(Elf::Shdr) != hdr_->e_shentsize) { debug(USERTRACE, "Expected section header size does not match advertised section header size\n"); return false; } MutexLock lock(program_binary_lock_); ustl::vector<Elf::Shdr> section_headers; section_headers.resize(hdr_->e_shnum); if (readFromBinary(reinterpret_cast<char*>(§ion_headers[0]), hdr_->e_shoff, hdr_->e_shnum*sizeof(Elf::Shdr))) { debug(USERTRACE, "Failed to load section headers!\n"); return false; } // now that we have loaded the section headers, we want to find and load the section that contains // the section names // in the simple case this section name section is only 0xFF00 bytes long, in that case // loading is simple. we only support this case for now size_t section_name_section = hdr_->e_shstrndx; size_t section_name_size = section_headers[section_name_section].sh_size; ustl::vector<char> section_names(section_name_size); if (readFromBinary(§ion_names[0], section_headers[section_name_section].sh_offset, section_name_size )) { debug(USERTRACE, "Failed to load section name section\n"); return false; } // now that we have names we read through all the sections // and load the two we're interested in char *stab_data=0; char *stabstr_data=0; char* sweb_data=0; size_t stab_data_size=0; size_t sweb_data_size=0; for (Elf::Shdr const §ion: section_headers) { if (section.sh_name) { if (!strcmp(§ion_names[section.sh_name], ".stab")) { debug(USERTRACE, "Found stab section, index is %d\n", section.sh_name); if (stab_data) { debug(USERTRACE, "Already loaded the stab section?, skipping\n"); } else { size_t size = section.sh_size; stab_data = new char[size]; stab_data_size = size; if (readFromBinary(stab_data, section.sh_offset, size)) { debug(USERTRACE, "Failed to load stab section!\n"); delete[] stab_data; stab_data=0; } } } if (!strcmp(§ion_names[section.sh_name], ".stabstr")) { debug(USERTRACE, "Found stabstr section, index is %d\n", section.sh_name); if (stabstr_data) { debug(USERTRACE, "Already loaded the stabstr section?, skipping\n"); } else { size_t size = section.sh_size; stabstr_data = new char[size]; if (readFromBinary(stabstr_data, section.sh_offset, size)) { debug(USERTRACE, "Failed to load stabstr section!\n"); delete[] stabstr_data; stabstr_data=0; } } } if (!strcmp(§ion_names[section.sh_name], ".swebdbg")) { debug(USERTRACE, "Found SWEBDbg Infos\n"); size_t size = section.sh_size; if(size) { sweb_data = new char[size]; sweb_data_size = size; if (readFromBinary(sweb_data, section.sh_offset, size)) { debug(USERTRACE, "Could not read swebdbg section!\n"); delete[] sweb_data; sweb_data = 0; } } else { debug(USERTRACE, "SWEBDbg Infos are empty\n"); return false; } } } } if ((!stab_data || !stabstr_data) && !sweb_data) { delete[] stab_data; delete[] stabstr_data; debug(USERTRACE, "Failed to load necessary debug data!\n"); return false; } if(stab_data) { userspace_debug_info_ = new Stabs2DebugInfo(stab_data, stab_data + stab_data_size, stabstr_data); } else { userspace_debug_info_ = new SWEBDebugInfo(sweb_data, sweb_data + sweb_data_size); } return true; }