From 875301b2c457dab401bd89dc01a734e1985373a9 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 22 Oct 2014 00:05:30 +0000 Subject: [PATCH] [PECOFF] Do not write duplicate directives to .def file. This is a follow-up patch for r220333. r220333 renames exported symbols. That raised another issue; if we have both decorated and undecorated names for the same symbol, we'll end up have two duplicate exported symbol entries. This is a fix for that issue by removing duplciate entries. llvm-svn: 220350 --- .../PECOFF/LinkerGeneratedSymbolFile.h | 25 +++++++++++++++++++--- lld/test/pecoff/Inputs/export.obj.yaml | 4 ++-- lld/test/pecoff/export.test | 15 +++++++------ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h index a42673c..2e0f4e4 100644 --- a/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h +++ b/lld/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h @@ -12,6 +12,7 @@ #include "lld/Core/Simple.h" #include "lld/ReaderWriter/PECOFFLinkingContext.h" #include "llvm/Support/Allocator.h" +#include #include using llvm::COFF::WindowsSubsystem; @@ -253,15 +254,33 @@ public: } const File *find(StringRef sym, bool dataSymbolOnly) const override { + typedef PECOFFLinkingContext::ExportDesc ExportDesc; auto it = _exportedSyms.find(sym); if (it == _exportedSyms.end()) return nullptr; std::string replace; if (!findDecoratedSymbol(_ctx, _syms.get(), sym.str(), replace)) return nullptr; - it->second->name = replace; - if (_ctx->deadStrip()) - _ctx->addDeadStripRoot(_ctx->allocate(replace)); + 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 + // duplicate item. + std::vector &exp = _ctx->getDllExports(); + auto isFound = std::find_if( + exp.begin(), exp.end(), + [&](ExportDesc &e) { return e.getExternalName().equals(replace); }); + if (isFound != exp.end()) { + exp.erase( + std::remove_if(exp.begin(), exp.end(), + [&](ExportDesc &e) { return &e == desc; }), + exp.end()); + } else { + it->second->name = replace; + if (_ctx->deadStrip()) + _ctx->addDeadStripRoot(_ctx->allocate(replace)); + } + return new (_alloc) impl::SymbolRenameFile(sym, replace); } diff --git a/lld/test/pecoff/Inputs/export.obj.yaml b/lld/test/pecoff/Inputs/export.obj.yaml index 5959906..fa92cd0 100644 --- a/lld/test/pecoff/Inputs/export.obj.yaml +++ b/lld/test/pecoff/Inputs/export.obj.yaml @@ -10,7 +10,7 @@ sections: - Name: .drectve Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] Alignment: 2147483648 - SectionData: 2f6578706f72743a6578706f7274666e334032353600 # /export:exportfn3@256 + SectionData: 2f6578706f72743a5f6578706f7274666e334032353600 # /export:_exportfn3@256 symbols: - Name: .text Value: 0 @@ -42,7 +42,7 @@ symbols: SimpleType: IMAGE_SYM_TYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL StorageClass: IMAGE_SYM_CLASS_EXTERNAL - - Name: exportfn3@256 + - Name: _exportfn3@256 Value: 16 SectionNumber: 1 SimpleType: IMAGE_SYM_TYPE_NULL diff --git a/lld/test/pecoff/export.test b/lld/test/pecoff/export.test index 53ae007..3791bdb 100644 --- a/lld/test/pecoff/export.test +++ b/lld/test/pecoff/export.test @@ -39,8 +39,8 @@ CHECK4: DLL name: export.test.tmp4.dll CHECK4: Ordinal RVA Name CHECK4-NEXT: 5 0x2008 exportfn1 CHECK4-NEXT: 6 0x2010 exportfn2 -CHECK4-NEXT: 7 0x2010 exportfn5 -CHECK4-NEXT: 8 0x2010 exportfn3@256 +CHECK4-NEXT: 7 0x2010 exportfn3@256 +CHECK4-NEXT: 8 0x2010 exportfn5 # RUN: lld -flavor link /out:%t5.dll /dll /entry:init \ # RUN: /export:exportfn7 -- %t.obj @@ -49,7 +49,8 @@ CHECK4-NEXT: 8 0x2010 exportfn3@256 CHECK5: Export Table: CHECK5: DLL name: export.test.tmp5.dll CHECK5: Ordinal RVA Name -CHECK5-NEXT: 1 0x2010 exportfn7 +CHECK5-NEXT: 1 0x2010 exportfn3@256 +CHECK5-NEXT: 2 0x2010 exportfn7 # RUN: lld -flavor link /out:%t6.dll /dll /entry:init \ # RUN: /export:exportfn8 -- %t.obj @@ -61,14 +62,16 @@ CHECK6: Ordinal RVA Name CHECK6-NEXT: 1 0x2010 ?exportfn8@@YAXXZ # RUN: lld -flavor link /out:%t6.dll /dll /entry:init \ -# RUN: /export:exportfn8 /export:exportfn8 -- %t.obj +# RUN: /export:exportfn8 /export:exportfn8 /export:exportfn3 -- %t.obj # RUN: llvm-objdump -p %t6.dll | FileCheck -check-prefix=DUP %s DUP: Export Table: DUP: DLL name: export.test.tmp6.dll DUP: Ordinal RVA Name -DUP: 1 0x2010 ?exportfn8@@YAXXZ -DUP-NOT: 1 0x2010 ?exportfn8@@YAXXZ +DUP-NEXT: 1 0x2010 ?exportfn8@@YAXXZ +DUP-NEXT: 2 0x2010 exportfn3@256 +DUP-NOT: ?exportfn8@@YAXXZ +DUP-NOT: exportfn3@256 # RUN: yaml2obj %p/Inputs/export.obj.yaml > %t.obj # -- 2.7.4