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