From d31cf6065f4c096cf703ea32f84fa843b44a978b Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 3 Dec 2014 04:34:20 +0000 Subject: [PATCH] [PECOFF] Fix a bug in /export option handler. /export option can be given multiple times to specify multiple symbols to be exported. /export accepts both decorated and undecorated name. If you give both undecorated and decorated name of the same symbol to /export, they are resolved to the same symbol. In this case, we need to de-duplicate the exported names, so that we don't have duplicated items in the export symbol table in a DLL. We remove duplicate items from a vector. The bug was there. Because we had pointers pointing to elements of the vector, after an item is removed, they would point wrong elements. This patch is to remove these pointers. Added a test for that case. llvm-svn: 223200 --- lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h | 17 ++++++++++------- lld/test/pecoff/export.test | 2 ++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h index 409dd64..4feaec6 100644 --- a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h +++ b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h @@ -250,18 +250,16 @@ public: : VirtualArchiveLibraryFile(""), _syms(syms), _ctx(const_cast(&ctx)) { for (PECOFFLinkingContext::ExportDesc &desc : _ctx->getDllExports()) - _exportedSyms[desc.name] = &desc; + _exportedSyms.insert(desc.name); } const File *find(StringRef sym, bool dataSymbolOnly) const override { typedef PECOFFLinkingContext::ExportDesc ExportDesc; - auto it = _exportedSyms.find(sym); - if (it == _exportedSyms.end()) + if (_exportedSyms.count(sym) == 0) return nullptr; std::string replace; if (!findDecoratedSymbol(_ctx, _syms.get(), sym.str(), replace)) return nullptr; - ExportDesc *desc = it->second; // We found a decorated symbol. There may be another symbol that // has the same decorated name. If that's the case, we remove the @@ -273,10 +271,15 @@ public: if (isFound != exp.end()) { exp.erase( std::remove_if(exp.begin(), exp.end(), - [&](ExportDesc &e) { return &e == desc; }), + [&](ExportDesc &e) { return e.name == sym; }), exp.end()); } else { - it->second->name = replace; + for (ExportDesc &e : exp) { + if (e.name == sym) { + e.name = replace; + break; + } + } if (_ctx->deadStrip()) _ctx->addDeadStripRoot(_ctx->allocate(replace)); } @@ -285,7 +288,7 @@ public: } private: - std::map _exportedSyms; + std::set _exportedSyms; std::shared_ptr _syms; mutable llvm::BumpPtrAllocator _alloc; mutable PECOFFLinkingContext *_ctx; diff --git a/lld/test/pecoff/export.test b/lld/test/pecoff/export.test index cbe8960..dd73c41 100644 --- a/lld/test/pecoff/export.test +++ b/lld/test/pecoff/export.test @@ -62,6 +62,7 @@ CHECK6: Ordinal RVA Name CHECK6-NEXT: 1 0x2010 ?exportfn8@@YAXXZ # RUN: lld -flavor link /out:%t6.dll /dll /entry:init \ +# RUN: /export:exportfn7 /export:exportfn7@8 \ # RUN: /export:exportfn8 /export:exportfn8 /export:exportfn3 -- %t.obj # RUN: llvm-objdump -p %t6.dll | FileCheck -check-prefix=DUP %s @@ -70,6 +71,7 @@ DUP: DLL name: export.test.tmp6.dll DUP: Ordinal RVA Name DUP-NEXT: 1 0x2010 ?exportfn8@@YAXXZ DUP-NEXT: 2 0x2010 exportfn3@256 +DUP-NEXT: 3 0x2010 exportfn7@8 DUP-NOT: ?exportfn8@@YAXXZ DUP-NOT: exportfn3@256 -- 2.7.4