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