void serialize(std::ofstream &file, char ei_class, char ei_data) { // Readjust code offsets for (std::vector<ElfSection *>::iterator c = code.begin(); c != code.end(); c++) (*c)->getShdr().sh_addr += getAddr(); // Apply relocations for (ElfSection *rel = elf->getSection(1); rel != NULL; rel = rel->getNext()) if ((rel->getType() == SHT_REL) || (rel->getType() == SHT_RELA)) { ElfSection *section = rel->getInfo().section; if ((section->getType() == SHT_PROGBITS) && (section->getFlags() & SHF_EXECINSTR)) { if (rel->getType() == SHT_REL) apply_relocations((ElfRel_Section<Elf_Rel> *)rel, section); else apply_relocations((ElfRel_Section<Elf_Rela> *)rel, section); } } ElfSection::serialize(file, ei_class, ei_data); }
bool ElfRelocator::init(const std::wstring& inputName) { relocator = Arch->getElfRelocator(); if (relocator == NULL) { Logger::printError(Logger::Error,L"Object importing not supported for this architecture"); return false; } auto inputFiles = loadArArchive(inputName); if (inputFiles.size() == 0) { Logger::printError(Logger::Error,L"Could not load library"); return false; } for (ArFileEntry& entry: inputFiles) { ElfRelocatorFile file; ElfFile* elf = new ElfFile(); if (elf->load(entry.data,false) == false) { Logger::printError(Logger::Error,L"Could not load object file %s",entry.name); return false; } if (elf->getType() != 1) { Logger::printError(Logger::Error,L"Unexpected ELF type %d in object file %s",elf->getType(),entry.name); return false; } if (elf->getSegmentCount() != 0) { Logger::printError(Logger::Error,L"Unexpected segment count %d in object file %s",elf->getSegmentCount(),entry.name); return false; } // load all relevant sections of this file for (size_t s = 0; s < elf->getSegmentlessSectionCount(); s++) { ElfSection* sec = elf->getSegmentlessSection(s); if (!(sec->getFlags() & SHF_ALLOC)) continue; if (sec->getType() == SHT_PROGBITS || sec->getType() == SHT_NOBITS || sec->getType() == SHT_INIT_ARRAY) { ElfRelocatorSection sectionEntry; sectionEntry.section = sec; sectionEntry.index = s; sectionEntry.relSection = NULL; sectionEntry.label = NULL; // search relocation section for (size_t k = 0; k < elf->getSegmentlessSectionCount(); k++) { ElfSection* relSection = elf->getSegmentlessSection(k); if (relSection->getType() != SHT_REL) continue; if (relSection->getInfo() != s) continue; // got it sectionEntry.relSection = relSection; break; } // keep track of constructor sections if (sec->getName() == ".ctors" || sec->getName() == ".init_array") { ElfRelocatorCtor ctor; ctor.symbolName = Global.symbolTable.getUniqueLabelName(); ctor.size = sec->getSize(); sectionEntry.label = Global.symbolTable.getLabel(ctor.symbolName,-1,-1); sectionEntry.label->setDefined(true); ctors.push_back(ctor); } file.sections.push_back(sectionEntry); } } // init exportable symbols for (int i = 0; i < elf->getSymbolCount(); i++) { Elf32_Sym symbol; bool found = elf->getSymbol(symbol, i); if (ELF32_ST_BIND(symbol.st_info) == STB_GLOBAL && symbol.st_shndx != 0) { ElfRelocatorSymbol symEntry; symEntry.type = ELF32_ST_TYPE(symbol.st_info); symEntry.name = convertUtf8ToWString(elf->getStrTableString(symbol.st_name)); symEntry.relativeAddress = symbol.st_value; symEntry.section = symbol.st_shndx; symEntry.size = symbol.st_size; symEntry.label = NULL; file.symbols.push_back(symEntry); } } file.elf = elf; file.name = entry.name; files.push_back(file); } return true; }