//===- SectionSymbolSet.cpp -----------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include #include #include #include #include #include #include #include #include #include using namespace mcld; //===----------------------------------------------------------------------===// // SectionSymbolSet //===----------------------------------------------------------------------===// SectionSymbolSet::SectionSymbolSet() { m_pSectionSymbolMap = new SectHashTableType(16); } SectionSymbolSet::~SectionSymbolSet() { delete m_pSectionSymbolMap; } bool SectionSymbolSet::add(LDSection& pOutSect, NamePool& pNamePool) { // create the resolveInfo for this section symbol llvm::StringRef sym_name = llvm::StringRef(pOutSect.name()); ResolveInfo* sym_info = pNamePool.createSymbol(sym_name, false, ResolveInfo::Section, ResolveInfo::Define, ResolveInfo::Local, 0x0, // size ResolveInfo::Default); // create the output section symbol and set its fragRef to the first fragment // of the section LDSymbol* sym = LDSymbol::Create(*sym_info); sym_info->setSymPtr(sym); // insert the symbol to the Section to Symbol hash map bool exist = false; SectHashTableType::entry_type* entry = m_pSectionSymbolMap->insert(&pOutSect, exist); assert(!exist); entry->setValue(sym); return true; } bool SectionSymbolSet::finalize(LDSection& pOutSect, SymbolTable& pSymTab, bool relocatable) { if (!relocatable && pOutSect.size() == 0) return true; LDSymbol* sym = get(pOutSect); assert(NULL != sym); SectionData* data = NULL; switch (pOutSect.kind()) { case LDFileFormat::Relocation: // Relocation section should not have section symbol. return true; case LDFileFormat::EhFrame: if (EhFrame *ehframe = pOutSect.getEhFrame()) data = ehframe->getSectionData(); break; default: data = pOutSect.getSectionData(); break; } FragmentRef* frag_ref; if (data && !data->empty()) frag_ref = FragmentRef::Create(data->front(), 0x0); else frag_ref = FragmentRef::Null(); sym->setFragmentRef(frag_ref); // push symbol into output symbol table pSymTab.add(*sym); return true; } LDSymbol* SectionSymbolSet::get(const LDSection& pOutSect) { SectHashTableType::iterator entry = m_pSectionSymbolMap->find(&pOutSect); return entry.getEntry()->value(); } const LDSymbol* SectionSymbolSet::get(const LDSection& pOutSect) const { SectHashTableType::iterator entry = m_pSectionSymbolMap->find(&pOutSect); return entry.getEntry()->value(); }