static bool getExportedAtoms(PECOFFLinkingContext &ctx, MutableFile *file, std::vector<TableEntry> &ret) { std::map<StringRef, const DefinedAtom *> definedAtoms; for (const DefinedAtom *atom : file->defined()) definedAtoms[atom->name()] = atom; for (PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) { auto it = definedAtoms.find(desc.getRealName()); if (it == definedAtoms.end()) { llvm::errs() << "Symbol <" << desc.name << "> is exported but not defined.\n"; return false; } const DefinedAtom *atom = it->second; // One can export a symbol with a different name than the symbol // name used in DLL. If such name is specified, use it in the // .edata section. ret.push_back(TableEntry(ctx.undecorateSymbol(desc.getExternalName()), desc.ordinal, atom, desc.noname)); } std::sort(ret.begin(), ret.end(), [](const TableEntry &a, const TableEntry &b) { return a.exportName.compare(b.exportName) < 0; }); return true; }
static void assignOrdinals(PECOFFLinkingContext &ctx) { std::set<PECOFFLinkingContext::ExportDesc> exports; int maxOrdinal = -1; for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) maxOrdinal = std::max(maxOrdinal, desc.ordinal); int nextOrdinal = (maxOrdinal == -1) ? 1 : (maxOrdinal + 1); for (PECOFFLinkingContext::ExportDesc desc : ctx.getDllExports()) { if (desc.ordinal == -1) desc.ordinal = nextOrdinal++; exports.insert(desc); } ctx.getDllExports().swap(exports); }
// dedupExports removes duplicate export entries. If two exports are // referring the same symbol, they are considered duplicates. // This could happen if the same symbol name is specified as an argument // to /export more than once, or an unmangled and mangled name of the // same symbol are given to /export. In the latter case, we choose // unmangled (shorter) name. static void dedupExports(PECOFFLinkingContext &ctx) { std::vector<ExportDesc> &exports = ctx.getDllExports(); // Pass 1: find duplicate entries std::set<const ExportDesc *> dup; std::map<StringRef, ExportDesc *> map; for (ExportDesc &exp : exports) { if (!exp.externalName.empty()) continue; StringRef symbol = exp.getRealName(); auto it = map.find(symbol); if (it == map.end()) { map[symbol] = &exp; } else if (symbol.size() < it->second->getRealName().size()) { map[symbol] = &exp; dup.insert(it->second); } else { dup.insert(&exp); } } // Pass 2: remove duplicate entries auto pred = [&](const ExportDesc &exp) { return dup.count(&exp) == 1; }; exports.erase(std::remove_if(exports.begin(), exports.end(), pred), exports.end()); }
static void assignOrdinals(PECOFFLinkingContext &ctx) { std::vector<ExportDesc> &exports = ctx.getDllExports(); int maxOrdinal = -1; for (ExportDesc &desc : exports) maxOrdinal = std::max(maxOrdinal, desc.ordinal); std::sort(exports.begin(), exports.end(), [](const ExportDesc &a, const ExportDesc &b) { return a.getExternalName().compare(b.getExternalName()) < 0; }); int nextOrdinal = (maxOrdinal == -1) ? 1 : (maxOrdinal + 1); for (ExportDesc &desc : exports) if (desc.ordinal == -1) desc.ordinal = nextOrdinal++; }
static bool getExportedAtoms(const PECOFFLinkingContext &ctx, MutableFile *file, std::vector<TableEntry> &ret) { std::map<StringRef, const DefinedAtom *> definedAtoms; for (const DefinedAtom *atom : file->defined()) definedAtoms[atom->name()] = atom; for (const PECOFFLinkingContext::ExportDesc &desc : ctx.getDllExports()) { auto it = definedAtoms.find(desc.name); if (it == definedAtoms.end()) { llvm::errs() << "Symbol <" << desc.name << "> is exported but not defined.\n"; return false; } const DefinedAtom *atom = it->second; ret.push_back(TableEntry(desc.name, desc.ordinal, atom, desc.noname)); } std::sort(ret.begin(), ret.end(), compare); return true; }