Ejemplo n.º 1
0
static bool useExistingDest(GlobalValue &SGV, GlobalValue *DGV,
                            bool ShouldLink) {
  if (!DGV)
    return false;

  if (SGV.isDeclaration())
    return true;

  if (DGV->isDeclarationForLinker() && !SGV.isDeclarationForLinker())
    return false;

  if (ShouldLink)
    return false;

  return true;
}
Ejemplo n.º 2
0
static std::unique_ptr<Module>
getModuleForFile(LLVMContext &Context, claimed_file &F,
                 ld_plugin_input_file &Info, raw_fd_ostream *ApiFile,
                 StringSet<> &Internalize, StringSet<> &Maybe) {

  if (get_symbols(F.handle, F.syms.size(), F.syms.data()) != LDPS_OK)
    message(LDPL_FATAL, "Failed to get symbol information");

  const void *View;
  if (get_view(F.handle, &View) != LDPS_OK)
    message(LDPL_FATAL, "Failed to get a view of file");

  MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize),
                            Info.name);
  ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
      object::IRObjectFile::create(BufferRef, Context);

  if (std::error_code EC = ObjOrErr.getError())
    message(LDPL_FATAL, "Could not read bitcode from file : %s",
            EC.message().c_str());

  object::IRObjectFile &Obj = **ObjOrErr;

  Module &M = Obj.getModule();

  M.materializeMetadata();
  UpgradeDebugInfo(M);

  SmallPtrSet<GlobalValue *, 8> Used;
  collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);

  DenseSet<GlobalValue *> Drop;
  std::vector<GlobalAlias *> KeptAliases;

  unsigned SymNum = 0;
  for (auto &ObjSym : Obj.symbols()) {
    if (shouldSkip(ObjSym.getFlags()))
      continue;
    ld_plugin_symbol &Sym = F.syms[SymNum];
    ++SymNum;

    ld_plugin_symbol_resolution Resolution =
        (ld_plugin_symbol_resolution)Sym.resolution;

    if (options::generate_api_file)
      *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n';

    GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl());
    if (!GV) {
      freeSymName(Sym);
      continue; // Asm symbol.
    }

    if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) {
      // Common linkage is special. There is no single symbol that wins the
      // resolution. Instead we have to collect the maximum alignment and size.
      // The IR linker does that for us if we just pass it every common GV.
      // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we
      // internalize once the IR linker has done its job.
      freeSymName(Sym);
      continue;
    }

    switch (Resolution) {
    case LDPR_UNKNOWN:
      llvm_unreachable("Unexpected resolution");

    case LDPR_RESOLVED_IR:
    case LDPR_RESOLVED_EXEC:
    case LDPR_RESOLVED_DYN:
      assert(GV->isDeclarationForLinker());
      break;

    case LDPR_UNDEF:
      if (!GV->isDeclarationForLinker()) {
        assert(GV->hasComdat());
        Drop.insert(GV);
      }
      break;

    case LDPR_PREVAILING_DEF_IRONLY: {
      keepGlobalValue(*GV, KeptAliases);
      if (!Used.count(GV)) {
        // Since we use the regular lib/Linker, we cannot just internalize GV
        // now or it will not be copied to the merged module. Instead we force
        // it to be copied and then internalize it.
        Internalize.insert(GV->getName());
      }
      break;
    }

    case LDPR_PREVAILING_DEF:
      keepGlobalValue(*GV, KeptAliases);
      break;

    case LDPR_PREEMPTED_IR:
      // Gold might have selected a linkonce_odr and preempted a weak_odr.
      // In that case we have to make sure we don't end up internalizing it.
      if (!GV->isDiscardableIfUnused())
        Maybe.erase(GV->getName());

      // fall-through
    case LDPR_PREEMPTED_REG:
      Drop.insert(GV);
      break;

    case LDPR_PREVAILING_DEF_IRONLY_EXP: {
      // We can only check for address uses after we merge the modules. The
      // reason is that this GV might have a copy in another module
      // and in that module the address might be significant, but that
      // copy will be LDPR_PREEMPTED_IR.
      if (GV->hasLinkOnceODRLinkage())
        Maybe.insert(GV->getName());
      keepGlobalValue(*GV, KeptAliases);
      break;
    }
    }

    freeSymName(Sym);
  }

  ValueToValueMapTy VM;
  LocalValueMaterializer Materializer(Drop);
  for (GlobalAlias *GA : KeptAliases) {
    // Gold told us to keep GA. It is possible that a GV usied in the aliasee
    // expression is being dropped. If that is the case, that GV must be copied.
    Constant *Aliasee = GA->getAliasee();
    Constant *Replacement = mapConstantToLocalCopy(Aliasee, VM, &Materializer);
    GA->setAliasee(Replacement);
  }

  for (auto *GV : Drop)
    drop(*GV);

  return Obj.takeModule();
}
Ejemplo n.º 3
0
static void internalize(GlobalValue &GV) {
  if (GV.isDeclarationForLinker())
    return; // We get here if there is a matching asm definition.
  if (!GV.hasLocalLinkage())
    GV.setLinkage(GlobalValue::InternalLinkage);
}
Ejemplo n.º 4
0
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
                                        const GlobalValue &Dest,
                                        const GlobalValue &Src) {

  // Should we unconditionally use the Src?
  if (shouldOverrideFromSrc()) {
    LinkFromSrc = true;
    return false;
  }

  // We always have to add Src if it has appending linkage.
  if (Src.hasAppendingLinkage()) {
    // Should have prevented importing for appending linkage in linkIfNeeded.
    assert(!isPerformingImport());
    LinkFromSrc = true;
    return false;
  }

  if (isPerformingImport()) {
    // LinkFromSrc iff this is a global requested for importing.
    LinkFromSrc = GlobalsToImport->count(&Src);
    return false;
  }

  bool SrcIsDeclaration = Src.isDeclarationForLinker();
  bool DestIsDeclaration = Dest.isDeclarationForLinker();

  if (SrcIsDeclaration) {
    // If Src is external or if both Src & Dest are external..  Just link the
    // external globals, we aren't adding anything.
    if (Src.hasDLLImportStorageClass()) {
      // If one of GVs is marked as DLLImport, result should be dllimport'ed.
      LinkFromSrc = DestIsDeclaration;
      return false;
    }
    // If the Dest is weak, use the source linkage.
    if (Dest.hasExternalWeakLinkage()) {
      LinkFromSrc = true;
      return false;
    }
    // Link an available_externally over a declaration.
    LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration();
    return false;
  }

  if (DestIsDeclaration) {
    // If Dest is external but Src is not:
    LinkFromSrc = true;
    return false;
  }

  if (Src.hasCommonLinkage()) {
    if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) {
      LinkFromSrc = true;
      return false;
    }

    if (!Dest.hasCommonLinkage()) {
      LinkFromSrc = false;
      return false;
    }

    const DataLayout &DL = Dest.getParent()->getDataLayout();
    uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType());
    uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType());
    LinkFromSrc = SrcSize > DestSize;
    return false;
  }

  if (Src.isWeakForLinker()) {
    assert(!Dest.hasExternalWeakLinkage());
    assert(!Dest.hasAvailableExternallyLinkage());

    if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) {
      LinkFromSrc = true;
      return false;
    }

    LinkFromSrc = false;
    return false;
  }

  if (Dest.isWeakForLinker()) {
    assert(Src.hasExternalLinkage());
    LinkFromSrc = true;
    return false;
  }

  assert(!Src.hasExternalWeakLinkage());
  assert(!Dest.hasExternalWeakLinkage());
  assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
         "Unexpected linkage type!");
  return emitError("Linking globals named '" + Src.getName() +
                   "': symbol multiply defined!");
}
Ejemplo n.º 5
0
static std::unique_ptr<Module>
getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
                 ld_plugin_input_file &Info, raw_fd_ostream *ApiFile,
                 StringSet<> &Internalize, StringSet<> &Maybe,
                 std::vector<GlobalValue *> &Keep,
                 StringMap<unsigned> &Realign) {
  MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize),
                            Info.name);
  ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
      object::IRObjectFile::create(BufferRef, Context);

  if (std::error_code EC = ObjOrErr.getError())
    message(LDPL_FATAL, "Could not read bitcode from file : %s",
            EC.message().c_str());

  object::IRObjectFile &Obj = **ObjOrErr;

  Module &M = Obj.getModule();

  M.materializeMetadata();
  UpgradeDebugInfo(M);

  SmallPtrSet<GlobalValue *, 8> Used;
  collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);

  unsigned SymNum = 0;
  for (auto &ObjSym : Obj.symbols()) {
    GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl());
    if (GV && GV->hasAppendingLinkage())
      Keep.push_back(GV);

    if (shouldSkip(ObjSym.getFlags()))
      continue;
    ld_plugin_symbol &Sym = F.syms[SymNum];
    ++SymNum;

    ld_plugin_symbol_resolution Resolution =
        (ld_plugin_symbol_resolution)Sym.resolution;

    if (options::generate_api_file)
      *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n';

    if (!GV) {
      freeSymName(Sym);
      continue; // Asm symbol.
    }

    ResolutionInfo &Res = ResInfo[Sym.name];
    if (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP && !Res.IsLinkonceOdr)
      Resolution = LDPR_PREVAILING_DEF;

    // In ThinLTO mode change all prevailing resolutions to LDPR_PREVAILING_DEF.
    // For ThinLTO the IR files are compiled through the backend independently,
    // so we need to ensure that any prevailing linkonce copy will be emitted
    // into the object file by making it weak. Additionally, we can skip the
    // IRONLY handling for internalization, which isn't performed in ThinLTO
    // mode currently anyway.
    if (options::thinlto && (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP ||
                             Resolution == LDPR_PREVAILING_DEF_IRONLY))
      Resolution = LDPR_PREVAILING_DEF;

    GV->setUnnamedAddr(Res.UnnamedAddr);
    GV->setVisibility(Res.Visibility);

    // Override gold's resolution for common symbols. We want the largest
    // one to win.
    if (GV->hasCommonLinkage()) {
      if (Resolution == LDPR_PREVAILING_DEF_IRONLY)
        Res.CommonInternal = true;

      if (Resolution == LDPR_PREVAILING_DEF_IRONLY ||
          Resolution == LDPR_PREVAILING_DEF)
        Res.UseCommon = true;

      const DataLayout &DL = GV->getParent()->getDataLayout();
      uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
      unsigned Align = GV->getAlignment();

      if (Res.UseCommon && Size >= Res.CommonSize) {
        // Take GV.
        if (Res.CommonInternal)
          Resolution = LDPR_PREVAILING_DEF_IRONLY;
        else
          Resolution = LDPR_PREVAILING_DEF;
        cast<GlobalVariable>(GV)->setAlignment(
            std::max(Res.CommonAlign, Align));
      } else {
        // Do not take GV, it's smaller than what we already have in the
        // combined module.
        Resolution = LDPR_PREEMPTED_IR;
        if (Align > Res.CommonAlign)
          // Need to raise the alignment though.
          Realign[Sym.name] = Align;
      }

      Res.CommonSize = std::max(Res.CommonSize, Size);
      Res.CommonAlign = std::max(Res.CommonAlign, Align);
    }

    switch (Resolution) {
    case LDPR_UNKNOWN:
      llvm_unreachable("Unexpected resolution");

    case LDPR_RESOLVED_IR:
    case LDPR_RESOLVED_EXEC:
    case LDPR_RESOLVED_DYN:
    case LDPR_PREEMPTED_IR:
    case LDPR_PREEMPTED_REG:
      break;

    case LDPR_UNDEF:
      if (!GV->isDeclarationForLinker())
        assert(GV->hasComdat());
      break;

    case LDPR_PREVAILING_DEF_IRONLY: {
      Keep.push_back(GV);
      // The IR linker has to be able to map this value to a declaration,
      // so we can only internalize after linking.
      if (!Used.count(GV))
        Internalize.insert(GV->getName());
      break;
    }

    case LDPR_PREVAILING_DEF:
      Keep.push_back(GV);
      // There is a non IR use, so we have to force optimizations to keep this.
      switch (GV->getLinkage()) {
      default:
        break;
      case GlobalValue::LinkOnceAnyLinkage:
        GV->setLinkage(GlobalValue::WeakAnyLinkage);
        break;
      case GlobalValue::LinkOnceODRLinkage:
        GV->setLinkage(GlobalValue::WeakODRLinkage);
        break;
      }
      break;

    case LDPR_PREVAILING_DEF_IRONLY_EXP: {
      // We can only check for address uses after we merge the modules. The
      // reason is that this GV might have a copy in another module
      // and in that module the address might be significant, but that
      // copy will be LDPR_PREEMPTED_IR.
      Maybe.insert(GV->getName());
      Keep.push_back(GV);
      break;
    }
    }

    freeSymName(Sym);
  }

  return Obj.takeModule();
}
Ejemplo n.º 6
0
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
                                        const GlobalValue &Dest,
                                        const GlobalValue &Src) {

    // Should we unconditionally use the Src?
    if (shouldOverrideFromSrc()) {
        LinkFromSrc = true;
        return false;
    }

    // We always have to add Src if it has appending linkage.
    if (Src.hasAppendingLinkage()) {
        // Should have prevented importing for appending linkage in linkIfNeeded.
        assert(!isPerformingImport());
        LinkFromSrc = true;
        return false;
    }

    bool SrcIsDeclaration = Src.isDeclarationForLinker();
    bool DestIsDeclaration = Dest.isDeclarationForLinker();

    if (isPerformingImport()) {
        if (isa<Function>(&Src)) {
            // For functions, LinkFromSrc iff this is a function requested
            // for importing. For variables, decide below normally.
            LinkFromSrc = GlobalsToImport->count(&Src);
            return false;
        }

        // Check if this is an alias with an already existing definition
        // in Dest, which must have come from a prior importing pass from
        // the same Src module. Unlike imported function and variable
        // definitions, which are imported as available_externally and are
        // not definitions for the linker, that is not a valid linkage for
        // imported aliases which must be definitions. Simply use the existing
        // Dest copy.
        if (isa<GlobalAlias>(&Src) && !DestIsDeclaration) {
            assert(isa<GlobalAlias>(&Dest));
            LinkFromSrc = false;
            return false;
        }
    }

    if (SrcIsDeclaration) {
        // If Src is external or if both Src & Dest are external..  Just link the
        // external globals, we aren't adding anything.
        if (Src.hasDLLImportStorageClass()) {
            // If one of GVs is marked as DLLImport, result should be dllimport'ed.
            LinkFromSrc = DestIsDeclaration;
            return false;
        }
        // If the Dest is weak, use the source linkage.
        if (Dest.hasExternalWeakLinkage()) {
            LinkFromSrc = true;
            return false;
        }
        // Link an available_externally over a declaration.
        LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration();
        return false;
    }

    if (DestIsDeclaration) {
        // If Dest is external but Src is not:
        LinkFromSrc = true;
        return false;
    }

    if (Src.hasCommonLinkage()) {
        if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) {
            LinkFromSrc = true;
            return false;
        }

        if (!Dest.hasCommonLinkage()) {
            LinkFromSrc = false;
            return false;
        }

        const DataLayout &DL = Dest.getParent()->getDataLayout();
        uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType());
        uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType());
        LinkFromSrc = SrcSize > DestSize;
        return false;
    }

    if (Src.isWeakForLinker()) {
        assert(!Dest.hasExternalWeakLinkage());
        assert(!Dest.hasAvailableExternallyLinkage());

        if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) {
            LinkFromSrc = true;
            return false;
        }

        LinkFromSrc = false;
        return false;
    }

    if (Dest.isWeakForLinker()) {
        assert(Src.hasExternalLinkage());
        LinkFromSrc = true;
        return false;
    }

    assert(!Src.hasExternalWeakLinkage());
    assert(!Dest.hasExternalWeakLinkage());
    assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
           "Unexpected linkage type!");
    return emitError("Linking globals named '" + Src.getName() +
                     "': symbol multiply defined!");
}