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