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 
21 namespace mcld {
22 
23 //===----------------------------------------------------------------------===//
24 // SectionSymbolSet
25 //===----------------------------------------------------------------------===//
26 
SectionSymbolSet()27 SectionSymbolSet::SectionSymbolSet() {
28   m_pSectionSymbolMap = new SectHashTableType(16);
29 }
30 
~SectionSymbolSet()31 SectionSymbolSet::~SectionSymbolSet() {
32   delete m_pSectionSymbolMap;
33 }
34 
add(LDSection & pOutSect,NamePool & pNamePool)35 bool 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 
finalize(LDSection & pOutSect,SymbolTable & pSymTab,bool relocatable)61 bool 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 
get(const LDSection & pOutSect)96 LDSymbol* SectionSymbolSet::get(const LDSection& pOutSect) {
97   SectHashTableType::iterator entry = m_pSectionSymbolMap->find(&pOutSect);
98   return entry.getEntry()->value();
99 }
100 
get(const LDSection & pOutSect) const101 const 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