Exemple #1
0
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;
}
Exemple #2
0
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});
  }
}
Exemple #3
0
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) {});
}