//===- 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