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