• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- IRBuilder.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/IRBuilder.h"
10 
11 #include "mcld/Fragment/FragmentRef.h"
12 #include "mcld/LinkerScript.h"
13 #include "mcld/LD/DebugString.h"
14 #include "mcld/LD/EhFrame.h"
15 #include "mcld/LD/ELFReader.h"
16 #include "mcld/LD/LDContext.h"
17 #include "mcld/LD/RelocData.h"
18 #include "mcld/LD/SectionData.h"
19 #include "mcld/Object/ObjectBuilder.h"
20 #include "mcld/Support/ELF.h"
21 #include "mcld/Support/MemoryArea.h"
22 #include "mcld/Support/MsgHandling.h"
23 
24 #include <llvm/ADT/StringRef.h>
25 
26 namespace mcld {
27 
28 //===----------------------------------------------------------------------===//
29 // Helper Functions
30 //===----------------------------------------------------------------------===//
GetELFSectionKind(uint32_t pType,const char * pName,uint32_t pFlag)31 LDFileFormat::Kind GetELFSectionKind(uint32_t pType,
32                                      const char* pName,
33                                      uint32_t pFlag) {
34   if (pFlag & llvm::ELF::SHF_EXCLUDE)
35     return LDFileFormat::Exclude;
36 
37   if (pFlag & llvm::ELF::SHF_MASKPROC)
38     return LDFileFormat::Target;
39 
40   // name rules
41   llvm::StringRef name(pName);
42   if (name.startswith(".debug") || name.startswith(".zdebug") ||
43       name.startswith(".line") || name.startswith(".stab")) {
44     if (name.startswith(".debug_str"))
45       return LDFileFormat::DebugString;
46     return LDFileFormat::Debug;
47   }
48   if (name.startswith(".comment"))
49     return LDFileFormat::MetaData;
50   if (name.startswith(".interp") || name.startswith(".dynamic"))
51     return LDFileFormat::Note;
52   if (name.startswith(".eh_frame"))
53     return LDFileFormat::EhFrame;
54   if (name.startswith(".eh_frame_hdr"))
55     return LDFileFormat::EhFrameHdr;
56   if (name.startswith(".gcc_except_table"))
57     return LDFileFormat::GCCExceptTable;
58   if (name.startswith(".note.GNU-stack"))
59     return LDFileFormat::StackNote;
60   if (name.startswith(".gnu.linkonce"))
61     return LDFileFormat::LinkOnce;
62 
63   // type rules
64   switch (pType) {
65     case llvm::ELF::SHT_NULL:
66       return LDFileFormat::Null;
67     case llvm::ELF::SHT_INIT_ARRAY:
68     case llvm::ELF::SHT_FINI_ARRAY:
69     case llvm::ELF::SHT_PREINIT_ARRAY:
70     case llvm::ELF::SHT_PROGBITS: {
71       if ((pFlag & llvm::ELF::SHF_EXECINSTR) != 0)
72         return LDFileFormat::TEXT;
73       else
74         return LDFileFormat::DATA;
75     }
76     case llvm::ELF::SHT_SYMTAB:
77     case llvm::ELF::SHT_DYNSYM:
78     case llvm::ELF::SHT_STRTAB:
79     case llvm::ELF::SHT_HASH:
80     case llvm::ELF::SHT_DYNAMIC:
81     case llvm::ELF::SHT_SYMTAB_SHNDX:
82       return LDFileFormat::NamePool;
83     case llvm::ELF::SHT_RELA:
84     case llvm::ELF::SHT_REL:
85       return LDFileFormat::Relocation;
86     case llvm::ELF::SHT_NOBITS:
87       return LDFileFormat::BSS;
88     case llvm::ELF::SHT_NOTE:
89       return LDFileFormat::Note;
90     case llvm::ELF::SHT_GROUP:
91       return LDFileFormat::Group;
92     case llvm::ELF::SHT_GNU_versym:
93     case llvm::ELF::SHT_GNU_verdef:
94     case llvm::ELF::SHT_GNU_verneed:
95       return LDFileFormat::Version;
96     case llvm::ELF::SHT_SHLIB:
97       return LDFileFormat::Target;
98     default:
99       if ((pType >= llvm::ELF::SHT_LOPROC && pType <= llvm::ELF::SHT_HIPROC) ||
100           (pType >= llvm::ELF::SHT_LOOS && pType <= llvm::ELF::SHT_HIOS) ||
101           (pType >= llvm::ELF::SHT_LOUSER && pType <= llvm::ELF::SHT_HIUSER))
102         return LDFileFormat::Target;
103       fatal(diag::err_unsupported_section) << pName << pType;
104   }
105   return LDFileFormat::MetaData;
106 }
107 
108 //===----------------------------------------------------------------------===//
109 // IRBuilder
110 //===----------------------------------------------------------------------===//
IRBuilder(Module & pModule,const LinkerConfig & pConfig)111 IRBuilder::IRBuilder(Module& pModule, const LinkerConfig& pConfig)
112     : m_Module(pModule), m_Config(pConfig), m_InputBuilder(pConfig) {
113   m_InputBuilder.setCurrentTree(m_Module.getInputTree());
114 
115   // FIXME: where to set up Relocation?
116   Relocation::SetUp(m_Config);
117 }
118 
~IRBuilder()119 IRBuilder::~IRBuilder() {
120 }
121 
122 /// CreateInput - To create an input file and append it to the input tree.
CreateInput(const std::string & pName,const sys::fs::Path & pPath,Input::Type pType)123 Input* IRBuilder::CreateInput(const std::string& pName,
124                               const sys::fs::Path& pPath,
125                               Input::Type pType) {
126   if (Input::Unknown == pType)
127     return ReadInput(pName, pPath);
128 
129   m_InputBuilder.createNode<InputTree::Positional>(pName, pPath, pType);
130   Input* input = *m_InputBuilder.getCurrentNode();
131 
132   if (!input->hasContext())
133     m_InputBuilder.setContext(*input, false);
134 
135   return input;
136 }
137 
138 /// ReadInput - To read an input file and append it to the input tree.
ReadInput(const std::string & pName,const sys::fs::Path & pPath)139 Input* IRBuilder::ReadInput(const std::string& pName,
140                             const sys::fs::Path& pPath) {
141   m_InputBuilder.createNode<InputTree::Positional>(
142       pName, pPath, Input::Unknown);
143   Input* input = *m_InputBuilder.getCurrentNode();
144 
145   if (!input->hasContext())
146     m_InputBuilder.setContext(*input);
147 
148   if (!input->hasMemArea())
149     m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
150                              FileHandle::Permission(FileHandle::System));
151 
152   return input;
153 }
154 
155 /// ReadInput - To read an input file and append it to the input tree.
ReadInput(const std::string & pNameSpec)156 Input* IRBuilder::ReadInput(const std::string& pNameSpec) {
157   const sys::fs::Path* path = NULL;
158   // find out the real path of the namespec.
159   if (m_InputBuilder.getConstraint().isSharedSystem()) {
160     // In the system with shared object support, we can find both archive
161     // and shared object.
162 
163     if (m_InputBuilder.getAttributes().isStatic()) {
164       // with --static, we must search an archive.
165       path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
166     } else {
167       // otherwise, with --Bdynamic, we can find either an archive or a
168       // shared object.
169       path = m_Module.getScript().directories().find(pNameSpec, Input::DynObj);
170     }
171   } else {
172     // In the system without shared object support, we only look for an archive
173     path = m_Module.getScript().directories().find(pNameSpec, Input::Archive);
174   }
175 
176   if (path == NULL) {
177     fatal(diag::err_cannot_find_namespec) << pNameSpec;
178     return NULL;
179   }
180 
181   m_InputBuilder.createNode<InputTree::Positional>(pNameSpec, *path);
182   Input* input = *m_InputBuilder.getCurrentNode();
183 
184   if (!input->hasContext())
185     m_InputBuilder.setContext(*input);
186 
187   if (!input->hasMemArea())
188     m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
189                              FileHandle::Permission(FileHandle::System));
190 
191   return input;
192 }
193 
194 /// ReadInput - To read an input file and append it to the input tree.
ReadInput(FileHandle & pFileHandle)195 Input* IRBuilder::ReadInput(FileHandle& pFileHandle) {
196   m_InputBuilder.createNode<InputTree::Positional>("file handler",
197                                                    pFileHandle.path());
198 
199   Input* input = *m_InputBuilder.getCurrentNode();
200   if (pFileHandle.path().empty()) {
201     m_InputBuilder.setContext(*input, false);
202   } else {
203     m_InputBuilder.setContext(*input, true);
204   }
205   m_InputBuilder.setMemory(*input, FileHandle::OpenMode(FileHandle::ReadOnly),
206                            FileHandle::Permission(FileHandle::System));
207 
208   return input;
209 }
210 
211 /// ReadInput - To read an input file and append it to the input tree.
ReadInput(const std::string & pName,void * pRawMemory,size_t pSize)212 Input* IRBuilder::ReadInput(const std::string& pName,
213                             void* pRawMemory,
214                             size_t pSize) {
215   m_InputBuilder.createNode<InputTree::Positional>(pName, sys::fs::Path("NAN"));
216   Input* input = *m_InputBuilder.getCurrentNode();
217   m_InputBuilder.setContext(*input, false);
218   m_InputBuilder.setMemory(*input, pRawMemory, pSize);
219   return input;
220 }
221 
StartGroup()222 bool IRBuilder::StartGroup() {
223   if (m_InputBuilder.isInGroup()) {
224     fatal(diag::fatal_forbid_nest_group);
225     return false;
226   }
227   m_InputBuilder.enterGroup();
228   return true;
229 }
230 
EndGroup()231 bool IRBuilder::EndGroup() {
232   m_InputBuilder.exitGroup();
233   return true;
234 }
235 
WholeArchive()236 void IRBuilder::WholeArchive() {
237   m_InputBuilder.getAttributes().setWholeArchive();
238 }
239 
NoWholeArchive()240 void IRBuilder::NoWholeArchive() {
241   m_InputBuilder.getAttributes().unsetWholeArchive();
242 }
243 
AsNeeded()244 void IRBuilder::AsNeeded() {
245   m_InputBuilder.getAttributes().setAsNeeded();
246 }
247 
NoAsNeeded()248 void IRBuilder::NoAsNeeded() {
249   m_InputBuilder.getAttributes().unsetAsNeeded();
250 }
251 
CopyDTNeeded()252 void IRBuilder::CopyDTNeeded() {
253   m_InputBuilder.getAttributes().setAddNeeded();
254 }
255 
NoCopyDTNeeded()256 void IRBuilder::NoCopyDTNeeded() {
257   m_InputBuilder.getAttributes().unsetAddNeeded();
258 }
259 
AgainstShared()260 void IRBuilder::AgainstShared() {
261   m_InputBuilder.getAttributes().setDynamic();
262 }
263 
AgainstStatic()264 void IRBuilder::AgainstStatic() {
265   m_InputBuilder.getAttributes().setStatic();
266 }
267 
CreateELFHeader(Input & pInput,const std::string & pName,uint32_t pType,uint32_t pFlag,uint32_t pAlign)268 LDSection* IRBuilder::CreateELFHeader(Input& pInput,
269                                       const std::string& pName,
270                                       uint32_t pType,
271                                       uint32_t pFlag,
272                                       uint32_t pAlign) {
273   // Create section header
274   LDFileFormat::Kind kind = GetELFSectionKind(pType, pName.c_str(), pFlag);
275   LDSection* header = LDSection::Create(pName, kind, pType, pFlag);
276   header->setAlign(pAlign);
277 
278   // Append section header in input
279   pInput.context()->appendSection(*header);
280   return header;
281 }
282 
283 /// CreateSectionData - To create a section data for given pSection.
CreateSectionData(LDSection & pSection)284 SectionData* IRBuilder::CreateSectionData(LDSection& pSection) {
285   assert(!pSection.hasSectionData() && "pSection already has section data.");
286 
287   SectionData* sect_data = SectionData::Create(pSection);
288   pSection.setSectionData(sect_data);
289   return sect_data;
290 }
291 
292 /// CreateRelocData - To create a relocation data for given pSection.
CreateRelocData(LDSection & pSection)293 RelocData* IRBuilder::CreateRelocData(LDSection& pSection) {
294   assert(!pSection.hasRelocData() && "pSection already has relocation data.");
295 
296   RelocData* reloc_data = RelocData::Create(pSection);
297   pSection.setRelocData(reloc_data);
298   return reloc_data;
299 }
300 
301 /// CreateEhFrame - To create a eh_frame for given pSection
CreateEhFrame(LDSection & pSection)302 EhFrame* IRBuilder::CreateEhFrame(LDSection& pSection) {
303   assert(!pSection.hasEhFrame() && "pSection already has eh_frame.");
304 
305   EhFrame* eh_frame = EhFrame::Create(pSection);
306   pSection.setEhFrame(eh_frame);
307   return eh_frame;
308 }
309 
310 /// CreateDebugString - To create a DebugString for given pSection
CreateDebugString(LDSection & pSection)311 DebugString* IRBuilder::CreateDebugString(LDSection& pSection) {
312   assert(!pSection.hasDebugString() && "pSection already has debug_str.");
313 
314   DebugString* debug_str = DebugString::Create(pSection);
315   pSection.setDebugString(debug_str);
316   return debug_str;
317 }
318 
319 /// CreateBSS - To create a bss section for given pSection
CreateBSS(LDSection & pSection)320 SectionData* IRBuilder::CreateBSS(LDSection& pSection) {
321   assert(!pSection.hasSectionData() && "pSection already has section data.");
322   assert((pSection.kind() == LDFileFormat::BSS) &&
323          "pSection is not a BSS section.");
324 
325   SectionData* sect_data = SectionData::Create(pSection);
326   pSection.setSectionData(sect_data);
327 
328   /*  value, valsize, size*/
329   FillFragment* frag = new FillFragment(0x0, 1, pSection.size());
330 
331   ObjectBuilder::AppendFragment(*frag, *sect_data);
332   return sect_data;
333 }
334 
335 /// CreateRegion - To create a region fragment in the input file.
CreateRegion(Input & pInput,size_t pOffset,size_t pLength)336 Fragment* IRBuilder::CreateRegion(Input& pInput,
337                                   size_t pOffset,
338                                   size_t pLength) {
339   if (!pInput.hasMemArea()) {
340     fatal(diag::fatal_cannot_read_input) << pInput.path();
341     return NULL;
342   }
343 
344   if (0 == pLength)
345     return new FillFragment(0x0, 0, 0);
346 
347   llvm::StringRef region = pInput.memArea()->request(pOffset, pLength);
348   return new RegionFragment(region);
349 }
350 
351 /// CreateRegion - To create a region fragment wrapping the given memory
CreateRegion(void * pMemory,size_t pLength)352 Fragment* IRBuilder::CreateRegion(void* pMemory, size_t pLength) {
353   if (0 == pLength)
354     return new FillFragment(0x0, 0, 0);
355 
356   llvm::StringRef region(reinterpret_cast<const char*>(pMemory), pLength);
357   return new RegionFragment(region);
358 }
359 
360 /// AppendFragment - To append pFrag to the given SectionData pSD
AppendFragment(Fragment & pFrag,SectionData & pSD)361 uint64_t IRBuilder::AppendFragment(Fragment& pFrag, SectionData& pSD) {
362   uint64_t size =
363       ObjectBuilder::AppendFragment(pFrag, pSD, pSD.getSection().align());
364   pSD.getSection().setSize(pSD.getSection().size() + size);
365   return size;
366 }
367 
368 /// AppendRelocation - To append an relocation to the given RelocData pRD.
AppendRelocation(Relocation & pRelocation,RelocData & pRD)369 void IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD) {
370   pRD.append(pRelocation);
371 }
372 
373 /// AppendEhFrame - To append a fragment to EhFrame.
AppendEhFrame(Fragment & pFrag,EhFrame & pEhFrame)374 uint64_t IRBuilder::AppendEhFrame(Fragment& pFrag, EhFrame& pEhFrame) {
375   uint64_t size = ObjectBuilder::AppendFragment(
376       pFrag, *pEhFrame.getSectionData(), pEhFrame.getSection().align());
377   pEhFrame.getSection().setSize(pEhFrame.getSection().size() + size);
378   return size;
379 }
380 
381 /// AppendEhFrame - To append a FDE to the given EhFrame pEhFram.
AppendEhFrame(EhFrame::FDE & pFDE,EhFrame & pEhFrame)382 uint64_t IRBuilder::AppendEhFrame(EhFrame::FDE& pFDE, EhFrame& pEhFrame) {
383   pEhFrame.addFDE(pFDE);
384   pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pFDE.size());
385   return pFDE.size();
386 }
387 
388 /// AppendEhFrame - To append a CIE to the given EhFrame pEhFram.
AppendEhFrame(EhFrame::CIE & pCIE,EhFrame & pEhFrame)389 uint64_t IRBuilder::AppendEhFrame(EhFrame::CIE& pCIE, EhFrame& pEhFrame) {
390   pEhFrame.addCIE(pCIE);
391   pEhFrame.getSection().setSize(pEhFrame.getSection().size() + pCIE.size());
392   return pCIE.size();
393 }
394 
395 /// AddSymbol - To add a symbol in the input file and resolve the symbol
396 /// immediately
AddSymbol(Input & pInput,const std::string & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBind,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,LDSection * pSection,ResolveInfo::Visibility pVis)397 LDSymbol* IRBuilder::AddSymbol(Input& pInput,
398                                const std::string& pName,
399                                ResolveInfo::Type pType,
400                                ResolveInfo::Desc pDesc,
401                                ResolveInfo::Binding pBind,
402                                ResolveInfo::SizeType pSize,
403                                LDSymbol::ValueType pValue,
404                                LDSection* pSection,
405                                ResolveInfo::Visibility pVis) {
406   // rename symbols
407   std::string name = pName;
408   if (!m_Module.getScript().renameMap().empty() &&
409       ResolveInfo::Undefined == pDesc) {
410     // If the renameMap is not empty, some symbols should be renamed.
411     // --wrap and --portable defines the symbol rename map.
412     const LinkerScript& script = m_Module.getScript();
413     LinkerScript::SymbolRenameMap::const_iterator renameSym =
414         script.renameMap().find(pName);
415     if (script.renameMap().end() != renameSym)
416       name = renameSym.getEntry()->value();
417   }
418 
419   // Fix up the visibility if object has no export set.
420   if (pInput.noExport() && (pDesc != ResolveInfo::Undefined)) {
421     if ((pVis == ResolveInfo::Default) || (pVis == ResolveInfo::Protected)) {
422       pVis = ResolveInfo::Hidden;
423     }
424   }
425 
426   switch (pInput.type()) {
427     case Input::Object: {
428       FragmentRef* frag = NULL;
429       if (pSection == NULL || ResolveInfo::Undefined == pDesc ||
430           ResolveInfo::Common == pDesc || ResolveInfo::Absolute == pBind ||
431           LDFileFormat::Ignore == pSection->kind() ||
432           LDFileFormat::Group == pSection->kind())
433         frag = FragmentRef::Null();
434       else
435         frag = FragmentRef::Create(*pSection, pValue);
436 
437       LDSymbol* input_sym = addSymbolFromObject(
438           name, pType, pDesc, pBind, pSize, pValue, frag, pVis);
439       pInput.context()->addSymbol(input_sym);
440       return input_sym;
441     }
442     case Input::DynObj: {
443       return addSymbolFromDynObj(
444           pInput, name, pType, pDesc, pBind, pSize, pValue, pVis);
445     }
446     default: {
447       return NULL;
448       break;
449     }
450   }
451   return NULL;
452 }
453 
addSymbolFromObject(const std::string & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,FragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)454 LDSymbol* IRBuilder::addSymbolFromObject(const std::string& pName,
455                                          ResolveInfo::Type pType,
456                                          ResolveInfo::Desc pDesc,
457                                          ResolveInfo::Binding pBinding,
458                                          ResolveInfo::SizeType pSize,
459                                          LDSymbol::ValueType pValue,
460                                          FragmentRef* pFragmentRef,
461                                          ResolveInfo::Visibility pVisibility) {
462   // Step 1. calculate a Resolver::Result
463   // resolved_result is a triple <resolved_info, existent, override>
464   Resolver::Result resolved_result;
465   ResolveInfo old_info;  // used for arrange output symbols
466 
467   if (pBinding == ResolveInfo::Local) {
468     // if the symbol is a local symbol, create a LDSymbol for input, but do not
469     // resolve them.
470     resolved_result.info = m_Module.getNamePool().createSymbol(
471         pName, false, pType, pDesc, pBinding, pSize, pVisibility);
472 
473     // No matter if there is a symbol with the same name, insert the symbol
474     // into output symbol table. So, we let the existent false.
475     resolved_result.existent = false;
476     resolved_result.overriden = true;
477   } else {
478     // if the symbol is not local, insert and resolve it immediately
479     m_Module.getNamePool().insertSymbol(pName,
480                                         false,
481                                         pType,
482                                         pDesc,
483                                         pBinding,
484                                         pSize,
485                                         pValue,
486                                         pVisibility,
487                                         &old_info,
488                                         resolved_result);
489   }
490 
491   // the return ResolveInfo should not NULL
492   assert(resolved_result.info != NULL);
493 
494   /// Step 2. create an input LDSymbol.
495   // create a LDSymbol for the input file.
496   LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
497   input_sym->setFragmentRef(pFragmentRef);
498   input_sym->setValue(pValue);
499 
500   // Step 3. Set up corresponding output LDSymbol
501   LDSymbol* output_sym = resolved_result.info->outSymbol();
502   bool has_output_sym = (output_sym != NULL);
503   if (!resolved_result.existent || !has_output_sym) {
504     // it is a new symbol, the output_sym should be NULL.
505     assert(output_sym == NULL);
506 
507     if (pType == ResolveInfo::Section) {
508       // if it is a section symbol, its output LDSymbol is the input LDSymbol.
509       output_sym = input_sym;
510     } else {
511       // if it is a new symbol, create a LDSymbol for the output
512       output_sym = LDSymbol::Create(*resolved_result.info);
513     }
514     resolved_result.info->setSymPtr(output_sym);
515   }
516 
517   if (resolved_result.overriden || !has_output_sym) {
518     // symbol can be overriden only if it exists.
519     assert(output_sym != NULL);
520 
521     // should override output LDSymbol
522     output_sym->setFragmentRef(pFragmentRef);
523     output_sym->setValue(pValue);
524   }
525   return input_sym;
526 }
527 
addSymbolFromDynObj(Input & pInput,const std::string & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,ResolveInfo::Visibility pVisibility)528 LDSymbol* IRBuilder::addSymbolFromDynObj(Input& pInput,
529                                          const std::string& pName,
530                                          ResolveInfo::Type pType,
531                                          ResolveInfo::Desc pDesc,
532                                          ResolveInfo::Binding pBinding,
533                                          ResolveInfo::SizeType pSize,
534                                          LDSymbol::ValueType pValue,
535                                          ResolveInfo::Visibility pVisibility) {
536   // We don't need sections of dynamic objects. So we ignore section symbols.
537   if (pType == ResolveInfo::Section)
538     return NULL;
539 
540   // ignore symbols with local binding or that have internal or hidden
541   // visibility
542   if (pBinding == ResolveInfo::Local || pVisibility == ResolveInfo::Internal ||
543       pVisibility == ResolveInfo::Hidden)
544     return NULL;
545 
546   // A protected symbol in a shared library must be treated as a
547   // normal symbol when viewed from outside the shared library.
548   if (pVisibility == ResolveInfo::Protected)
549     pVisibility = ResolveInfo::Default;
550 
551   // insert symbol and resolve it immediately
552   // resolved_result is a triple <resolved_info, existent, override>
553   Resolver::Result resolved_result;
554   m_Module.getNamePool().insertSymbol(pName,
555                                       true,
556                                       pType,
557                                       pDesc,
558                                       pBinding,
559                                       pSize,
560                                       pValue,
561                                       pVisibility,
562                                       NULL,
563                                       resolved_result);
564 
565   // the return ResolveInfo should not NULL
566   assert(resolved_result.info != NULL);
567 
568   if (resolved_result.overriden || !resolved_result.existent)
569     pInput.setNeeded();
570 
571   // create a LDSymbol for the input file.
572   LDSymbol* input_sym = LDSymbol::Create(*resolved_result.info);
573   input_sym->setFragmentRef(FragmentRef::Null());
574   input_sym->setValue(pValue);
575 
576   // this symbol is seen in a dynamic object, set the InDyn flag
577   resolved_result.info->setInDyn();
578 
579   if (!resolved_result.existent) {
580     // we get a new symbol, leave it as NULL
581     resolved_result.info->setSymPtr(NULL);
582   }
583   return input_sym;
584 }
585 
586 /// AddRelocation - add a relocation entry
587 ///
588 /// All symbols should be read and resolved before calling this function.
AddRelocation(LDSection & pSection,Relocation::Type pType,LDSymbol & pSym,uint32_t pOffset,Relocation::Address pAddend)589 Relocation* IRBuilder::AddRelocation(LDSection& pSection,
590                                      Relocation::Type pType,
591                                      LDSymbol& pSym,
592                                      uint32_t pOffset,
593                                      Relocation::Address pAddend) {
594   FragmentRef* frag_ref = FragmentRef::Create(*pSection.getLink(), pOffset);
595 
596   Relocation* relocation = Relocation::Create(pType, *frag_ref, pAddend);
597 
598   relocation->setSymInfo(pSym.resolveInfo());
599   pSection.getRelocData()->append(*relocation);
600 
601   return relocation;
602 }
603 
CreateLocalSymbol(FragmentRef & pFragRef)604 ResolveInfo* IRBuilder::CreateLocalSymbol(FragmentRef& pFragRef) {
605   // Create and add symbol to the name pool.
606   ResolveInfo* resolveInfo =
607       m_Module.getNamePool().createSymbol(/* pName */"",
608                                           /* pIsDyn */false,
609                                           ResolveInfo::Section,
610                                           ResolveInfo::Define,
611                                           ResolveInfo::Local,
612                                           /* pSize */0,
613                                           ResolveInfo::Hidden);
614   if (resolveInfo == nullptr) {
615     return nullptr;
616   }
617 
618   // Create input symbol.
619   LDSymbol* inputSym = LDSymbol::Create(*resolveInfo);
620   if (inputSym == nullptr) {
621     return nullptr;
622   }
623 
624   inputSym->setFragmentRef(FragmentRef::Create(*pFragRef.frag(),
625                                                pFragRef.offset()));
626   inputSym->setValue(/* pValue */0);
627 
628   // The output symbol is simply an alias to the input symbol.
629   resolveInfo->setSymPtr(inputSym);
630 
631   return resolveInfo;
632 }
633 
634 /// AddSymbol - define an output symbol and override it immediately
635 template <>
AddSymbol(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,FragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)636 LDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
637     const llvm::StringRef& pName,
638     ResolveInfo::Type pType,
639     ResolveInfo::Desc pDesc,
640     ResolveInfo::Binding pBinding,
641     ResolveInfo::SizeType pSize,
642     LDSymbol::ValueType pValue,
643     FragmentRef* pFragmentRef,
644     ResolveInfo::Visibility pVisibility) {
645   ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
646   LDSymbol* output_sym = NULL;
647   if (info == NULL) {
648     // the symbol is not in the pool, create a new one.
649     // create a ResolveInfo
650     Resolver::Result result;
651     m_Module.getNamePool().insertSymbol(pName,
652                                         false,
653                                         pType,
654                                         pDesc,
655                                         pBinding,
656                                         pSize,
657                                         pValue,
658                                         pVisibility,
659                                         NULL,
660                                         result);
661     assert(!result.existent);
662 
663     // create a output LDSymbol
664     output_sym = LDSymbol::Create(*result.info);
665     result.info->setSymPtr(output_sym);
666 
667     if (result.info->shouldForceLocal(m_Config))
668       m_Module.getSymbolTable().forceLocal(*output_sym);
669     else
670       m_Module.getSymbolTable().add(*output_sym);
671   } else {
672     // the symbol is already in the pool, override it
673     ResolveInfo old_info;
674     old_info.override(*info);
675 
676     info->setRegular();
677     info->setType(pType);
678     info->setDesc(pDesc);
679     info->setBinding(pBinding);
680     info->setVisibility(pVisibility);
681     info->setIsSymbol(true);
682     info->setSize(pSize);
683 
684     output_sym = info->outSymbol();
685     if (output_sym != NULL)
686       m_Module.getSymbolTable().arrange(*output_sym, old_info);
687     else {
688       // create a output LDSymbol
689       output_sym = LDSymbol::Create(*info);
690       info->setSymPtr(output_sym);
691 
692       m_Module.getSymbolTable().add(*output_sym);
693     }
694   }
695 
696   if (output_sym != NULL) {
697     output_sym->setFragmentRef(pFragmentRef);
698     output_sym->setValue(pValue);
699   }
700 
701   return output_sym;
702 }
703 
704 /// AddSymbol - define an output symbol and override it immediately
705 template <>
AddSymbol(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,FragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)706 LDSymbol* IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
707     const llvm::StringRef& pName,
708     ResolveInfo::Type pType,
709     ResolveInfo::Desc pDesc,
710     ResolveInfo::Binding pBinding,
711     ResolveInfo::SizeType pSize,
712     LDSymbol::ValueType pValue,
713     FragmentRef* pFragmentRef,
714     ResolveInfo::Visibility pVisibility) {
715   ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
716 
717   if (info == NULL || !(info->isUndef() || info->isDyn())) {
718     // only undefined symbol and dynamic symbol can make a reference.
719     return NULL;
720   }
721 
722   // the symbol is already in the pool, override it
723   ResolveInfo old_info;
724   old_info.override(*info);
725 
726   info->setRegular();
727   info->setType(pType);
728   info->setDesc(pDesc);
729   info->setBinding(pBinding);
730   info->setVisibility(pVisibility);
731   info->setIsSymbol(true);
732   info->setSize(pSize);
733 
734   LDSymbol* output_sym = info->outSymbol();
735   if (output_sym != NULL) {
736     output_sym->setFragmentRef(pFragmentRef);
737     output_sym->setValue(pValue);
738     m_Module.getSymbolTable().arrange(*output_sym, old_info);
739   } else {
740     // create a output LDSymbol
741     output_sym = LDSymbol::Create(*info);
742     info->setSymPtr(output_sym);
743 
744     m_Module.getSymbolTable().add(*output_sym);
745   }
746 
747   return output_sym;
748 }
749 
750 /// AddSymbol - define an output symbol and resolve it
751 /// immediately
752 template <>
AddSymbol(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,FragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)753 LDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
754     const llvm::StringRef& pName,
755     ResolveInfo::Type pType,
756     ResolveInfo::Desc pDesc,
757     ResolveInfo::Binding pBinding,
758     ResolveInfo::SizeType pSize,
759     LDSymbol::ValueType pValue,
760     FragmentRef* pFragmentRef,
761     ResolveInfo::Visibility pVisibility) {
762   // Result is <info, existent, override>
763   Resolver::Result result;
764   ResolveInfo old_info;
765   m_Module.getNamePool().insertSymbol(pName,
766                                       false,
767                                       pType,
768                                       pDesc,
769                                       pBinding,
770                                       pSize,
771                                       pValue,
772                                       pVisibility,
773                                       &old_info,
774                                       result);
775 
776   LDSymbol* output_sym = result.info->outSymbol();
777   bool has_output_sym = (output_sym != NULL);
778 
779   if (!result.existent || !has_output_sym) {
780     output_sym = LDSymbol::Create(*result.info);
781     result.info->setSymPtr(output_sym);
782   }
783 
784   if (result.overriden || !has_output_sym) {
785     output_sym->setFragmentRef(pFragmentRef);
786     output_sym->setValue(pValue);
787   }
788 
789   // After symbol resolution, the visibility is changed to the most restrict.
790   // arrange the output position
791   if (result.info->shouldForceLocal(m_Config))
792     m_Module.getSymbolTable().forceLocal(*output_sym);
793   else if (has_output_sym)
794     m_Module.getSymbolTable().arrange(*output_sym, old_info);
795   else
796     m_Module.getSymbolTable().add(*output_sym);
797 
798   return output_sym;
799 }
800 
801 /// defineSymbol - define an output symbol and resolve it immediately.
802 template <>
AddSymbol(const llvm::StringRef & pName,ResolveInfo::Type pType,ResolveInfo::Desc pDesc,ResolveInfo::Binding pBinding,ResolveInfo::SizeType pSize,LDSymbol::ValueType pValue,FragmentRef * pFragmentRef,ResolveInfo::Visibility pVisibility)803 LDSymbol* IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Resolve>(
804     const llvm::StringRef& pName,
805     ResolveInfo::Type pType,
806     ResolveInfo::Desc pDesc,
807     ResolveInfo::Binding pBinding,
808     ResolveInfo::SizeType pSize,
809     LDSymbol::ValueType pValue,
810     FragmentRef* pFragmentRef,
811     ResolveInfo::Visibility pVisibility) {
812   ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
813 
814   if (info == NULL || !(info->isUndef() || info->isDyn())) {
815     // only undefined symbol and dynamic symbol can make a reference.
816     return NULL;
817   }
818 
819   return AddSymbol<Force, Resolve>(
820       pName, pType, pDesc, pBinding, pSize, pValue, pFragmentRef, pVisibility);
821 }
822 
823 }  // namespace mcld
824