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); }
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; }