static void readSymbolTableEntries(Archive& pArchive, MemoryRegion& pMemRegion) { typedef typename SizeTraits<SIZE>::Offset Offset; const Offset* data = reinterpret_cast<const Offset*>(pMemRegion.getBuffer()); // read the number of symbols Offset number = 0; if (llvm::sys::IsLittleEndianHost) number = mcld::bswap<SIZE>(*data); else number = *data; // set up the pointers for file offset and name offset ++data; const char* name = reinterpret_cast<const char*>(data + number); // add the archive symbols for (Offset i = 0; i < number; ++i) { if (llvm::sys::IsLittleEndianHost) pArchive.addSymbol(name, mcld::bswap<SIZE>(*data)); else pArchive.addSymbol(name, *data); name += strlen(name) + 1; ++data; } }
uint64_t Mips64GOT::emit(MemoryRegion& pRegion) { uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer()); uint64_t result = 0; for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { Mips64GOTEntry* got = &(llvm::cast<Mips64GOTEntry>((*it))); *buffer = static_cast<uint64_t>(got->getValue()); result += got->size(); } return result; }
uint64_t X86GNULDBackend::emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const { assert(pRegion.size() && "Size of MemoryRegion is zero!"); const ELFFileFormat* FileFormat = getOutputFormat(); assert(FileFormat && "ELFFileFormat is NULL in X86GNULDBackend::emitSectionData!"); unsigned int EntrySize = 0; uint64_t RegionSize = 0; if (&pSection == &(FileFormat->getPLT())) { assert(m_pPLT && "emitSectionData failed, m_pPLT is NULL!"); unsigned char* buffer = pRegion.getBuffer(); m_pPLT->applyPLT0(); m_pPLT->applyPLT1(); X86PLT::iterator it = m_pPLT->begin(); unsigned int plt0_size = llvm::cast<PLTEntryBase>((*it)).size(); memcpy(buffer, llvm::cast<PLTEntryBase>((*it)).getValue(), plt0_size); RegionSize += plt0_size; ++it; PLTEntryBase* plt1 = 0; X86PLT::iterator ie = m_pPLT->end(); while (it != ie) { plt1 = &(llvm::cast<PLTEntryBase>(*it)); EntrySize = plt1->size(); memcpy(buffer + RegionSize, plt1->getValue(), EntrySize); RegionSize += EntrySize; ++it; } } else if (&pSection == &(FileFormat->getGOT())) { RegionSize += emitGOTSectionData(pRegion); } else if (&pSection == &(FileFormat->getGOTPLT())) { RegionSize += emitGOTPLTSectionData(pRegion, FileFormat); } else { fatal(diag::unrecognized_output_sectoin) << pSection.name() << "*****@*****.**"; } return RegionSize; }
uint64_t ARMGOT::emit(MemoryRegion& pRegion) { uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); ARMGOTEntry* got = NULL; uint64_t result = 0x0; for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { got = &(llvm::cast<ARMGOTEntry>((*it))); *buffer = static_cast<uint32_t>(got->getValue()); result += ARMGOTEntry::EntrySize; } return result; }
uint64_t ARMGOT::emit(MemoryRegion& pRegion) { uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.getBuffer()); GOTEntry* got = 0; unsigned int entry_size = getEntrySize(); uint64_t result = 0x0; for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) { got = &(llvm::cast<GOTEntry>((*it))); *buffer = static_cast<uint32_t>(got->getContent()); result += entry_size; } return result; }
/// isThinArchive bool GNUArchiveReader::isThinArchive(Input& pInput) const { assert(pInput.hasMemArea()); MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), Archive::MAGIC_LEN); const char* str = reinterpret_cast<const char*>(region->getBuffer()); bool result = false; assert(NULL != str); if (isThinArchive(str)) result = true; pInput.memArea()->release(region); return result; }
uint64_t X86_64GNULDBackend::emitGOTSectionData(MemoryRegion& pRegion) const { assert(m_pGOT && "emitGOTSectionData failed, m_pGOT is NULL!"); uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer()); X86_64GOTEntry* got = 0; unsigned int EntrySize = X86_64GOTEntry::EntrySize; uint64_t RegionSize = 0; for (X86_64GOT::iterator it = m_pGOT->begin(), ie = m_pGOT->end(); it != ie; ++it, ++buffer) { got = &(llvm::cast<X86_64GOTEntry>((*it))); *buffer = static_cast<uint64_t>(got->getValue()); RegionSize += EntrySize; } return RegionSize; }
size_t ELFAttribute::emit(MemoryRegion &pRegion) const { // ARM [ABI-addenda], 2.2.3 uint64_t total_size = 0; // Write format-version. char* buffer = reinterpret_cast<char*>(pRegion.getBuffer()); buffer[0] = FormatVersion; total_size += FormatVersionFieldSize; for (llvm::SmallVectorImpl<Subsection*>::const_iterator subsec_it = m_Subsections.begin(), subsec_end = m_Subsections.end(); subsec_it != subsec_end; ++subsec_it) { // Write out subsection. total_size += (*subsec_it)->emit(buffer + total_size); } return total_size; }
uint64_t X86_64GNULDBackend::emitGOTPLTSectionData(MemoryRegion& pRegion, const ELFFileFormat* FileFormat) const { assert(m_pGOTPLT && "emitGOTPLTSectionData failed, m_pGOTPLT is NULL!"); m_pGOTPLT->applyGOT0(FileFormat->getDynamic().addr()); m_pGOTPLT->applyAllGOTPLT(*m_pPLT); uint64_t* buffer = reinterpret_cast<uint64_t*>(pRegion.getBuffer()); X86_64GOTEntry* got = 0; unsigned int EntrySize = X86_64GOTEntry::EntrySize; uint64_t RegionSize = 0; for (X86_64GOTPLT::iterator it = m_pGOTPLT->begin(), ie = m_pGOTPLT->end(); it != ie; ++it, ++buffer) { got = &(llvm::cast<X86_64GOTEntry>((*it))); *buffer = static_cast<uint64_t>(got->getValue()); RegionSize += EntrySize; } return RegionSize; }
bool ScriptReader::readScript(const LinkerConfig& pConfig, ScriptFile& pScriptFile) { bool result = false; std::stringbuf buf; Input& input = pScriptFile.input(); size_t size = input.memArea()->size(); MemoryRegion* region = input.memArea()->request(input.fileOffset(), size); char* str = reinterpret_cast<char*>(region->getBuffer()); buf.pubsetbuf(str, size); std::istream in(&buf); ScriptScanner scanner(&in); ScriptParser parser(pConfig, pScriptFile, scanner, m_GroupReader); result = (0 == parser.parse());; input.memArea()->release(region); return result; }
/// emitSectionData void ELFObjectWriter::emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const { SectionData::const_iterator fragIter, fragEnd = pSD.end(); size_t cur_offset = 0; for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) { size_t size = fragIter->size(); switch(fragIter->getKind()) { case Fragment::Region: { const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter); const uint8_t* from = region_frag.getRegion().start(); memcpy(pRegion.getBuffer(cur_offset), from, size); break; } case Fragment::Alignment: { // TODO: emit values with different sizes (> 1 byte), and emit nops const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); uint64_t count = size / align_frag.getValueSize(); switch (align_frag.getValueSize()) { case 1u: std::memset(pRegion.getBuffer(cur_offset), align_frag.getValue(), count); break; default: llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n"); break; } break; } case Fragment::Fillment: { const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); if (0 == size || 0 == fill_frag.getValueSize() || 0 == fill_frag.size()) { // ignore virtual fillment break; } uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize(); for (uint64_t i = 0; i != num_tiles; ++i) { std::memset(pRegion.getBuffer(cur_offset), fill_frag.getValue(), fill_frag.getValueSize()); } break; } case Fragment::Stub: { const Stub& stub_frag = llvm::cast<Stub>(*fragIter); memcpy(pRegion.getBuffer(cur_offset), stub_frag.getContent(), size); break; } case Fragment::Null: { assert(0x0 == size); break; } case Fragment::Target: llvm::report_fatal_error("Target fragment should not be in a regular section.\n"); break; default: llvm::report_fatal_error("invalid fragment should not be in a regular section.\n"); break; } cur_offset += size; } }