示例#1
0
void PECOFFLinkingContext::addDllExport(ExportDesc &desc) {
  addInitialUndefinedSymbol(allocate(desc.name));

  // MSVC link.exe silently drops characters after the first atsign.
  // For example, /export:foo@4=bar is equivalent to /export:foo=bar.
  // We do the same thing for compatibility.
  if (!desc.externalName.empty()) {
    StringRef s(desc.externalName);
    size_t pos = s.find('@');
    if (pos != s.npos)
      desc.externalName = s.substr(0, pos);
  }

  // Scan the vector to look for existing entry. It's not very fast,
  // but because the number of exported symbol is usually not that
  // much, it should be okay.
  for (ExportDesc &e : _dllExports) {
    if (e.name != desc.name)
      continue;
    if (!sameExportDesc(e, desc))
      llvm::errs() << "Export symbol '" << desc.name
                   << "' specified more than once.\n";
    return;
  }
  _dllExports.push_back(desc);
}
示例#2
0
bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
    // TODO: if -arch not specified, look at arch of first .o file.

    if (_currentVersion && _outputMachOType != MH_DYLIB) {
        diagnostics << "error: -current_version can only be used with dylibs\n";
        return false;
    }

    if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
        diagnostics
                << "error: -compatibility_version can only be used with dylibs\n";
        return false;
    }

    if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
        diagnostics
                << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
        return false;
    }

    if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
        diagnostics
                << "error: -bundle_loader can only be used with Mach-O bundles\n";
        return false;
    }

    // If -exported_symbols_list used, all exported symbols must be defined.
    if (_exportMode == ExportMode::whiteList) {
        for (const auto &symbol : _exportedSymbols)
            addInitialUndefinedSymbol(symbol.getKey());
    }

    // If -dead_strip, set up initial live symbols.
    if (deadStrip()) {
        // Entry point is live.
        if (outputTypeHasEntry())
            addDeadStripRoot(entrySymbolName());
        // Lazy binding helper is live.
        if (needsStubsPass())
            addDeadStripRoot(binderSymbolName());
        // If using -exported_symbols_list, make all exported symbols live.
        if (_exportMode == ExportMode::whiteList) {
            setGlobalsAreDeadStripRoots(false);
            for (const auto &symbol : _exportedSymbols)
                addDeadStripRoot(symbol.getKey());
        }
    }

    addOutputFileDependency(outputPath());

    return true;
}