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