Defined *Undefined::getWeakAlias() { // A weak alias may be a weak alias to another symbol, so check recursively. for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) if (auto *D = dyn_cast<Defined>(A->repl())) return D; return nullptr; }
void Writer<ELFT>::scanRelocs( InputSectionBase<ELFT> &C, iterator_range<const Elf_Rel_Impl<ELFT, isRela> *> Rels) { typedef Elf_Rel_Impl<ELFT, isRela> RelType; const ObjectFile<ELFT> &File = *C.getFile(); for (const RelType &RI : Rels) { uint32_t SymIndex = RI.getSymbol(Config->Mips64EL); SymbolBody *Body = File.getSymbolBody(SymIndex); uint32_t Type = RI.getType(Config->Mips64EL); if (Target->isTlsLocalDynamicReloc(Type)) { if (Target->isTlsOptimized(Type, nullptr)) continue; if (Out<ELFT>::LocalModuleTlsIndexOffset == uint32_t(-1)) { Out<ELFT>::LocalModuleTlsIndexOffset = Out<ELFT>::Got->addLocalModuleTlsIndex(); Out<ELFT>::RelaDyn->addReloc({&C, &RI}); } continue; } // Set "used" bit for --as-needed. if (Body && Body->isUndefined() && !Body->isWeak()) if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl())) S->File->IsUsed = true; if (Body) Body = Body->repl(); if (Body && Body->isTLS() && Target->isTlsGlobalDynamicReloc(Type)) { if (Target->isTlsOptimized(Type, Body)) continue; if (Body->isInGot()) continue; Out<ELFT>::Got->addDynTlsEntry(Body); Out<ELFT>::RelaDyn->addReloc({&C, &RI}); Out<ELFT>::RelaDyn->addReloc({nullptr, nullptr}); Body->setUsedInDynamicReloc(); continue; } if (Body && Body->isTLS() && !Target->isTlsDynReloc(Type)) continue; bool NeedsGot = false; bool NeedsPlt = false; if (Body) { if (auto *E = dyn_cast<SharedSymbol<ELFT>>(Body)) { if (E->needsCopy()) continue; if (Target->relocNeedsCopy(Type, *Body)) E->OffsetInBSS = 0; } NeedsPlt = Target->relocNeedsPlt(Type, *Body); if (NeedsPlt) { if (Body->isInPlt()) continue; Out<ELFT>::Plt->addEntry(Body); } NeedsGot = Target->relocNeedsGot(Type, *Body); if (NeedsGot) { if (NeedsPlt && Target->supportsLazyRelocations()) { Out<ELFT>::GotPlt->addEntry(Body); } else { if (Body->isInGot()) continue; Out<ELFT>::Got->addEntry(Body); } } } if (Config->EMachine == EM_MIPS && NeedsGot) { // MIPS ABI has special rules to process GOT entries // and doesn't require relocation entries for them. // See "Global Offset Table" in Chapter 5 in the following document // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf Body->setUsedInDynamicReloc(); continue; } bool CBP = canBePreempted(Body, NeedsGot); if (!CBP && (!Config->Shared || Target->isRelRelative(Type))) continue; if (CBP) Body->setUsedInDynamicReloc(); if (NeedsPlt && Target->supportsLazyRelocations()) Out<ELFT>::RelaPlt->addReloc({&C, &RI}); else Out<ELFT>::RelaDyn->addReloc({&C, &RI}); } }
void BitcodeCompiler::add(BitcodeFile &F) { std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(F.MB, Context)); std::vector<GlobalValue *> Keep; unsigned BodyIndex = 0; ArrayRef<SymbolBody *> Bodies = F.getSymbols(); Module &M = Obj->getModule(); if (M.getDataLayoutStr().empty()) fatal("invalid bitcode file: " + F.getName() + " has no datalayout"); // If a symbol appears in @llvm.used, the linker is required // to treat the symbol as there is a reference to the symbol // that it cannot see. Therefore, we can't internalize. SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false); for (const BasicSymbolRef &Sym : Obj->symbols()) { GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); // Ignore module asm symbols. if (!GV) continue; if (GV->hasAppendingLinkage()) { Keep.push_back(GV); continue; } if (BitcodeFile::shouldSkip(Sym)) continue; SymbolBody *B = Bodies[BodyIndex++]; if (!B || &B->repl() != B || !isa<DefinedBitcode>(B)) continue; switch (GV->getLinkage()) { default: break; case llvm::GlobalValue::LinkOnceAnyLinkage: GV->setLinkage(GlobalValue::WeakAnyLinkage); break; case llvm::GlobalValue::LinkOnceODRLinkage: GV->setLinkage(GlobalValue::WeakODRLinkage); break; } // We collect the set of symbols we want to internalize here // and change the linkage after the IRMover executed, i.e. after // we imported the symbols and satisfied undefined references // to it. We can't just change linkage here because otherwise // the IRMover will just rename the symbol. // Shared libraries need to be handled slightly differently. // For now, let's be conservative and just never internalize // symbols when creating a shared library. if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() && !B->MustBeInDynSym) if (!Used.count(GV)) InternalizedSyms.insert(GV->getName()); Keep.push_back(GV); } Mover.move(Obj->takeModule(), Keep, [](GlobalValue &, IRMover::ValueAdder) {}); }