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