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