static typename ELFT::uint getSymVA(const SymbolBody &Body, typename ELFT::uint &Addend) { typedef typename ELFT::uint uintX_t; switch (Body.kind()) { case SymbolBody::DefinedSyntheticKind: { auto &D = cast<DefinedSynthetic<ELFT>>(Body); if (D.Value == DefinedSynthetic<ELFT>::SectionEnd) return D.Section.getVA() + D.Section.getSize(); return D.Section.getVA() + D.Value; } case SymbolBody::DefinedRegularKind: { auto &D = cast<DefinedRegular<ELFT>>(Body); InputSectionBase<ELFT> *SC = D.Section; // According to the ELF spec reference to a local symbol from outside // the group are not allowed. Unfortunately .eh_frame breaks that rule // and must be treated specially. For now we just replace the symbol with // 0. if (SC == &InputSection<ELFT>::Discarded) return 0; // This is an absolute symbol. if (!SC) return D.Value; uintX_t Offset = D.Value; if (D.isSection()) { Offset += Addend; Addend = 0; } uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset); if (D.isTls()) return VA - Out<ELFT>::TlsPhdr->p_vaddr; return VA; } case SymbolBody::DefinedCommonKind: return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss; case SymbolBody::SharedKind: { auto &SS = cast<SharedSymbol<ELFT>>(Body); if (!SS.NeedsCopyOrPltAddr) return 0; if (SS.isFunc()) return Body.getPltVA<ELFT>(); return Out<ELFT>::Bss->getVA() + SS.OffsetInBss; } case SymbolBody::UndefinedElfKind: case SymbolBody::UndefinedBitcodeKind: return 0; case SymbolBody::LazyArchiveKind: case SymbolBody::LazyObjectKind: assert(Body.isUsedInRegularObj() && "lazy symbol reached writer"); return 0; case SymbolBody::DefinedBitcodeKind: llvm_unreachable("should have been replaced"); } llvm_unreachable("invalid symbol kind"); }
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) {}); }