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