//===- 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/LD/LDSection.h>
#include <mcld/LD/RelocData.h>
#include <mcld/LD/SectionData.h>
#include <mcld/LD/EhFrame.h>
#include <mcld/LD/ResolveInfo.h>
#include <mcld/LD/LDSymbol.h>
#include <mcld/LD/NamePool.h>
#include <mcld/Fragment/FragmentRef.h>
#include <mcld/LD/LDFileFormat.h>
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)
{
if (0x0 == pOutSect.size())
return true;
LDSymbol* sym = get(pOutSect);
assert(NULL != sym);
FragmentRef* frag_ref = NULL;
switch (pOutSect.kind()) {
case LDFileFormat::Relocation:
// Relocation section should not have section symbol.
return true;
case LDFileFormat::EhFrame:
frag_ref = FragmentRef::Create(
pOutSect.getEhFrame()->getSectionData().front(), 0x0);
break;
default:
frag_ref = FragmentRef::Create(pOutSect.getSectionData()->front(), 0x0);
break;
}
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();
}