| //===- SectionSymbolSet.cpp -----------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "mcld/LD/SectionSymbolSet.h" |
| |
| #include "mcld/Fragment/FragmentRef.h" |
| #include "mcld/LD/EhFrame.h" |
| #include "mcld/LD/LDFileFormat.h" |
| #include "mcld/LD/LDSection.h" |
| #include "mcld/LD/LDSymbol.h" |
| #include "mcld/LD/NamePool.h" |
| #include "mcld/LD/RelocData.h" |
| #include "mcld/LD/ResolveInfo.h" |
| #include "mcld/LD/SectionData.h" |
| |
| 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(sym != NULL); |
| 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(); |
| } |
| |
| } // namespace mcld |