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