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 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 //===----------------------------------------------------------------------===//
IRBuilder(Module & pModule,const LinkerConfig & pConfig)111 IRBuilder::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
~IRBuilder()119 IRBuilder::~IRBuilder() {
120 }
121
122 /// 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)123 Input* 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.
ReadInput(const std::string & pName,const sys::fs::Path & pPath)139 Input* 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.
ReadInput(const std::string & pNameSpec)156 Input* 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.
ReadInput(FileHandle & pFileHandle)195 Input* 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.
ReadInput(const std::string & pName,void * pRawMemory,size_t pSize)212 Input* 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
StartGroup()222 bool 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
EndGroup()231 bool IRBuilder::EndGroup() {
232 m_InputBuilder.exitGroup();
233 return true;
234 }
235
WholeArchive()236 void IRBuilder::WholeArchive() {
237 m_InputBuilder.getAttributes().setWholeArchive();
238 }
239
NoWholeArchive()240 void IRBuilder::NoWholeArchive() {
241 m_InputBuilder.getAttributes().unsetWholeArchive();
242 }
243
AsNeeded()244 void IRBuilder::AsNeeded() {
245 m_InputBuilder.getAttributes().setAsNeeded();
246 }
247
NoAsNeeded()248 void IRBuilder::NoAsNeeded() {
249 m_InputBuilder.getAttributes().unsetAsNeeded();
250 }
251
CopyDTNeeded()252 void IRBuilder::CopyDTNeeded() {
253 m_InputBuilder.getAttributes().setAddNeeded();
254 }
255
NoCopyDTNeeded()256 void IRBuilder::NoCopyDTNeeded() {
257 m_InputBuilder.getAttributes().unsetAddNeeded();
258 }
259
AgainstShared()260 void IRBuilder::AgainstShared() {
261 m_InputBuilder.getAttributes().setDynamic();
262 }
263
AgainstStatic()264 void IRBuilder::AgainstStatic() {
265 m_InputBuilder.getAttributes().setStatic();
266 }
267
CreateELFHeader(Input & pInput,const std::string & pName,uint32_t pType,uint32_t pFlag,uint32_t pAlign)268 LDSection* 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.
CreateSectionData(LDSection & pSection)284 SectionData* 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.
CreateRelocData(LDSection & pSection)293 RelocData* 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
CreateEhFrame(LDSection & pSection)302 EhFrame* 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
CreateDebugString(LDSection & pSection)311 DebugString* 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
CreateBSS(LDSection & pSection)320 SectionData* 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.
CreateRegion(Input & pInput,size_t pOffset,size_t pLength)336 Fragment* 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
CreateRegion(void * pMemory,size_t pLength)352 Fragment* 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
AppendFragment(Fragment & pFrag,SectionData & pSD)361 uint64_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.
AppendRelocation(Relocation & pRelocation,RelocData & pRD)369 void IRBuilder::AppendRelocation(Relocation& pRelocation, RelocData& pRD) {
370 pRD.append(pRelocation);
371 }
372
373 /// AppendEhFrame - To append a fragment to EhFrame.
AppendEhFrame(Fragment & pFrag,EhFrame & pEhFrame)374 uint64_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.
AppendEhFrame(EhFrame::FDE & pFDE,EhFrame & pEhFrame)382 uint64_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.
AppendEhFrame(EhFrame::CIE & pCIE,EhFrame & pEhFrame)389 uint64_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
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)397 LDSymbol* 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
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)454 LDSymbol* 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
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)528 LDSymbol* 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.
AddRelocation(LDSection & pSection,Relocation::Type pType,LDSymbol & pSym,uint32_t pOffset,Relocation::Address pAddend)589 Relocation* 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
604 /// AddSymbol - define an output symbol and override it immediately
605 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)606 LDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
607 const llvm::StringRef& pName,
608 ResolveInfo::Type pType,
609 ResolveInfo::Desc pDesc,
610 ResolveInfo::Binding pBinding,
611 ResolveInfo::SizeType pSize,
612 LDSymbol::ValueType pValue,
613 FragmentRef* pFragmentRef,
614 ResolveInfo::Visibility pVisibility) {
615 ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
616 LDSymbol* output_sym = NULL;
617 if (info == NULL) {
618 // the symbol is not in the pool, create a new one.
619 // create a ResolveInfo
620 Resolver::Result result;
621 m_Module.getNamePool().insertSymbol(pName,
622 false,
623 pType,
624 pDesc,
625 pBinding,
626 pSize,
627 pValue,
628 pVisibility,
629 NULL,
630 result);
631 assert(!result.existent);
632
633 // create a output LDSymbol
634 output_sym = LDSymbol::Create(*result.info);
635 result.info->setSymPtr(output_sym);
636
637 if (result.info->shouldForceLocal(m_Config))
638 m_Module.getSymbolTable().forceLocal(*output_sym);
639 else
640 m_Module.getSymbolTable().add(*output_sym);
641 } else {
642 // the symbol is already in the pool, override it
643 ResolveInfo old_info;
644 old_info.override(*info);
645
646 info->setRegular();
647 info->setType(pType);
648 info->setDesc(pDesc);
649 info->setBinding(pBinding);
650 info->setVisibility(pVisibility);
651 info->setIsSymbol(true);
652 info->setSize(pSize);
653
654 output_sym = info->outSymbol();
655 if (output_sym != NULL)
656 m_Module.getSymbolTable().arrange(*output_sym, old_info);
657 else {
658 // create a output LDSymbol
659 output_sym = LDSymbol::Create(*info);
660 info->setSymPtr(output_sym);
661
662 m_Module.getSymbolTable().add(*output_sym);
663 }
664 }
665
666 if (output_sym != NULL) {
667 output_sym->setFragmentRef(pFragmentRef);
668 output_sym->setValue(pValue);
669 }
670
671 return output_sym;
672 }
673
674 /// AddSymbol - define an output symbol and override it immediately
675 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)676 LDSymbol* IRBuilder::AddSymbol<IRBuilder::AsReferred, IRBuilder::Unresolve>(
677 const llvm::StringRef& pName,
678 ResolveInfo::Type pType,
679 ResolveInfo::Desc pDesc,
680 ResolveInfo::Binding pBinding,
681 ResolveInfo::SizeType pSize,
682 LDSymbol::ValueType pValue,
683 FragmentRef* pFragmentRef,
684 ResolveInfo::Visibility pVisibility) {
685 ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
686
687 if (info == NULL || !(info->isUndef() || info->isDyn())) {
688 // only undefined symbol and dynamic symbol can make a reference.
689 return NULL;
690 }
691
692 // the symbol is already in the pool, override it
693 ResolveInfo old_info;
694 old_info.override(*info);
695
696 info->setRegular();
697 info->setType(pType);
698 info->setDesc(pDesc);
699 info->setBinding(pBinding);
700 info->setVisibility(pVisibility);
701 info->setIsSymbol(true);
702 info->setSize(pSize);
703
704 LDSymbol* output_sym = info->outSymbol();
705 if (output_sym != NULL) {
706 output_sym->setFragmentRef(pFragmentRef);
707 output_sym->setValue(pValue);
708 m_Module.getSymbolTable().arrange(*output_sym, old_info);
709 } else {
710 // create a output LDSymbol
711 output_sym = LDSymbol::Create(*info);
712 info->setSymPtr(output_sym);
713
714 m_Module.getSymbolTable().add(*output_sym);
715 }
716
717 return output_sym;
718 }
719
720 /// AddSymbol - define an output symbol and resolve it
721 /// immediately
722 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)723 LDSymbol* IRBuilder::AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
724 const llvm::StringRef& pName,
725 ResolveInfo::Type pType,
726 ResolveInfo::Desc pDesc,
727 ResolveInfo::Binding pBinding,
728 ResolveInfo::SizeType pSize,
729 LDSymbol::ValueType pValue,
730 FragmentRef* pFragmentRef,
731 ResolveInfo::Visibility pVisibility) {
732 // Result is <info, existent, override>
733 Resolver::Result result;
734 ResolveInfo old_info;
735 m_Module.getNamePool().insertSymbol(pName,
736 false,
737 pType,
738 pDesc,
739 pBinding,
740 pSize,
741 pValue,
742 pVisibility,
743 &old_info,
744 result);
745
746 LDSymbol* output_sym = result.info->outSymbol();
747 bool has_output_sym = (output_sym != NULL);
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 <>
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 LDSymbol* 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 ResolveInfo* info = m_Module.getNamePool().findInfo(pName);
783
784 if (info == NULL || !(info->isUndef() || info->isDyn())) {
785 // only undefined symbol and dynamic symbol can make a reference.
786 return NULL;
787 }
788
789 return AddSymbol<Force, Resolve>(
790 pName, pType, pDesc, pBinding, pSize, pValue, pFragmentRef, pVisibility);
791 }
792
793 } // namespace mcld
794