1//===- SectionSymbolSet.cpp -----------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "mcld/LD/SectionSymbolSet.h"
10
11#include "mcld/Fragment/FragmentRef.h"
12#include "mcld/LD/EhFrame.h"
13#include "mcld/LD/LDFileFormat.h"
14#include "mcld/LD/LDSection.h"
15#include "mcld/LD/LDSymbol.h"
16#include "mcld/LD/NamePool.h"
17#include "mcld/LD/RelocData.h"
18#include "mcld/LD/ResolveInfo.h"
19#include "mcld/LD/SectionData.h"
20
21namespace mcld {
22
23//===----------------------------------------------------------------------===//
24// SectionSymbolSet
25//===----------------------------------------------------------------------===//
26
27SectionSymbolSet::SectionSymbolSet() {
28  m_pSectionSymbolMap = new SectHashTableType(16);
29}
30
31SectionSymbolSet::~SectionSymbolSet() {
32  delete m_pSectionSymbolMap;
33}
34
35bool SectionSymbolSet::add(LDSection& pOutSect, NamePool& pNamePool) {
36  // create the resolveInfo for this section symbol
37  llvm::StringRef sym_name = llvm::StringRef(pOutSect.name());
38  ResolveInfo* sym_info = pNamePool.createSymbol(sym_name,
39                                                 false,
40                                                 ResolveInfo::Section,
41                                                 ResolveInfo::Define,
42                                                 ResolveInfo::Local,
43                                                 0x0,  // size
44                                                 ResolveInfo::Default);
45
46  // create the output section symbol and set its fragRef to the first fragment
47  // of the section
48  LDSymbol* sym = LDSymbol::Create(*sym_info);
49  sym_info->setSymPtr(sym);
50
51  // insert the symbol to the Section to Symbol hash map
52  bool exist = false;
53  SectHashTableType::entry_type* entry =
54      m_pSectionSymbolMap->insert(&pOutSect, exist);
55  assert(!exist);
56  entry->setValue(sym);
57
58  return true;
59}
60
61bool SectionSymbolSet::finalize(LDSection& pOutSect,
62                                SymbolTable& pSymTab,
63                                bool relocatable) {
64  if (!relocatable && pOutSect.size() == 0)
65    return true;
66
67  LDSymbol* sym = get(pOutSect);
68  assert(sym != NULL);
69  SectionData* data = NULL;
70  switch (pOutSect.kind()) {
71    case LDFileFormat::Relocation:
72      // Relocation section should not have section symbol.
73      return true;
74
75    case LDFileFormat::EhFrame:
76      if (EhFrame* ehframe = pOutSect.getEhFrame())
77        data = ehframe->getSectionData();
78      break;
79
80    default:
81      data = pOutSect.getSectionData();
82      break;
83  }
84  FragmentRef* frag_ref;
85  if (data && !data->empty())
86    frag_ref = FragmentRef::Create(data->front(), 0x0);
87  else
88    frag_ref = FragmentRef::Null();
89  sym->setFragmentRef(frag_ref);
90  // push symbol into output symbol table
91  pSymTab.add(*sym);
92
93  return true;
94}
95
96LDSymbol* SectionSymbolSet::get(const LDSection& pOutSect) {
97  SectHashTableType::iterator entry = m_pSectionSymbolMap->find(&pOutSect);
98  return entry.getEntry()->value();
99}
100
101const LDSymbol* SectionSymbolSet::get(const LDSection& pOutSect) const {
102  SectHashTableType::iterator entry = m_pSectionSymbolMap->find(&pOutSect);
103  return entry.getEntry()->value();
104}
105
106}  // namespace mcld
107