[lld] r197970 - [PECOFF] Fix /export option in the .drectve section.
Rui Ueyama
ruiu at google.com
Fri Dec 27 01:02:37 PST 2013
On Fri, Dec 27, 2013 at 11:25 AM, Saleem Abdulrasool
<compnerd at compnerd.org>wrote:
> On Thu, Dec 26, 2013 at 11:24 AM, Reid Kleckner <rnk at google.com> wrote:
>
>> This... is ridiculous.
>>
>
> And now, for your pleasure this fancy trick (must be run with CL for x86):
>
> > type magic.cpp
>
> extern "C" int magic(int i) {
> return i + 32;
> }
>
> #pragma comment(linker, "/export:magic")
>
> > cl /nologo /MD magic.cpp /link /DLL /OUT:magic.dll /export:magic
>
> Note that the pragma is incorrect as it doesn't account for the global
> leader prefix, and that the command line is correct because it will be
> prefixed. The linker will then whine and then will actually create the DLL.
>
> Command line arguments take precedence, the duplicated export is fixed up
> as a result of the command line parsing, and you just get a warning that
> you specified the same symbol for exporting multiple times.
>
> Yes, I am a bad person for pointing out this perverse behaviour :-).
>
That sounds really broken to me so I tried that myself, and confirmed
that's (sadly) true! I got a warning for duplicate symbols but DLL creation
succeeded. Thank you so much for pointing this out. :)
>> On Tue, Dec 24, 2013 at 1:15 AM, Rui Ueyama <ruiu at google.com> wrote:
>>
>>> Author: ruiu
>>> Date: Tue Dec 24 03:15:57 2013
>>> New Revision: 197970
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=197970&view=rev
>>> Log:
>>> [PECOFF] Fix /export option in the .drectve section.
>>>
>>> /EXPORT option has slightly different semantics if it appears in the
>>> .drectve
>>> section. This patch implements it.
>>>
>>> Modified:
>>> lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
>>> lld/trunk/lib/Driver/WinLinkDriver.cpp
>>> lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
>>> lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
>>> lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
>>> lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
>>>
>>> Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
>>> +++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Tue Dec 24
>>> 03:15:57 2013
>>> @@ -98,6 +98,7 @@ public:
>>> StringRef searchLibraryFile(StringRef path) const;
>>>
>>> StringRef decorateSymbol(StringRef name) const;
>>> + StringRef undecorateSymbol(StringRef name) const;
>>>
>>> void setEntrySymbolName(StringRef name) {
>>> if (!name.empty())
>>>
>>> Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
>>> +++ lld/trunk/lib/Driver/WinLinkDriver.cpp Tue Dec 24 03:15:57 2013
>>> @@ -892,6 +892,15 @@ WinLinkDriver::parse(int argc, const cha
>>> << inputArg->getValue() << "\n";
>>> return false;
>>> }
>>> +
>>> + // Mangle the symbol name only if it is reading user-supplied
>>> command line
>>> + // arguments. Because the symbol name in the .drectve section is
>>> already
>>> + // mangled by the compiler, we shouldn't add a leading undescore
>>> here.
>>> + // It's odd that the command line option has different semantics
>>> in the
>>> + // .drectve section, but this behavior is needed for
>>> compatibility with
>>> + // MSVC's link.exe.
>>> + if (!isReadingDirectiveSection)
>>> + desc.name = ctx.decorateSymbol(desc.name);
>>> ctx.addDllExport(desc);
>>> break;
>>> }
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp (original)
>>> +++ lld/trunk/lib/ReaderWriter/PECOFF/EdataPass.cpp Tue Dec 24 03:15:57
>>> 2013
>>> @@ -39,7 +39,7 @@ static bool getExportedAtoms(const PECOF
>>> definedAtoms[atom->name()] = atom;
>>>
>>> for (const PECOFFLinkingContext::ExportDesc &desc :
>>> ctx.getDllExports()) {
>>> - auto it = definedAtoms.find(ctx.decorateSymbol(desc.name));
>>> + auto it = definedAtoms.find(desc.name);
>>> if (it == definedAtoms.end()) {
>>> llvm::errs() << "Symbol <" << desc.name
>>> << "> is exported but not defined.\n";
>>> @@ -86,8 +86,8 @@ EdataPass::createNamePointerTable(const
>>>
>>> size_t offset = 0;
>>> for (const TableEntry &e : entries) {
>>> - auto *stringAtom = new (_alloc)
>>> - COFFStringAtom(_file, _stringOrdinal++, ".edata", e.exportName);
>>> + auto *stringAtom = new (_alloc) COFFStringAtom(
>>> + _file, _stringOrdinal++, ".edata",
>>> ctx.undecorateSymbol(e.exportName));
>>> file->addAtom(*stringAtom);
>>> addDir32NBReloc(table, stringAtom, offset);
>>> offset += sizeof(uint32_t);
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
>>> +++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Dec
>>> 24 03:15:57 2013
>>> @@ -219,6 +219,13 @@ StringRef PECOFFLinkingContext::decorate
>>> return allocate(str);
>>> }
>>>
>>> +StringRef PECOFFLinkingContext::undecorateSymbol(StringRef name) const {
>>> + if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386)
>>> + return name;
>>> + assert(name.startswith("_"));
>>> + return name.substr(1);
>>> +}
>>> +
>>> Writer &PECOFFLinkingContext::writer() const { return *_writer; }
>>>
>>>
>>>
>>> Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp (original)
>>> +++ lld/trunk/lib/ReaderWriter/PECOFF/WriterImportLibrary.cpp Tue Dec 24
>>> 03:15:57 2013
>>> @@ -42,7 +42,7 @@ createModuleDefinitionFile(const PECOFFL
>>> << "EXPORTS\n";
>>>
>>> for (const PECOFFLinkingContext::ExportDesc &desc :
>>> ctx.getDllExports()) {
>>> - os << " " << desc.name << " @" << desc.ordinal;
>>> + os << " " << ctx.undecorateSymbol(desc.name) << " @" <<
>>> desc.ordinal;
>>> if (desc.noname)
>>> os << " NONAME";
>>> if (desc.isData)
>>>
>>> Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=197970&r1=197969&r2=197970&view=diff
>>>
>>> ==============================================================================
>>> --- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
>>> +++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Tue Dec 24
>>> 03:15:57 2013
>>> @@ -161,7 +161,7 @@ TEST_F(WinLinkParserTest, Export) {
>>> const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
>>> _context.getDllExports();
>>> EXPECT_TRUE(exports.size() == 1);
>>> - EXPECT_EQ("foo", exports[0].name);
>>> + EXPECT_EQ("_foo", exports[0].name);
>>> EXPECT_EQ(1, exports[0].ordinal);
>>> EXPECT_FALSE(exports[0].noname);
>>> EXPECT_FALSE(exports[0].isData);
>>> @@ -173,11 +173,11 @@ TEST_F(WinLinkParserTest, ExportWithOpti
>>> const std::vector<PECOFFLinkingContext::ExportDesc> &exports =
>>> _context.getDllExports();
>>> EXPECT_TRUE(exports.size() == 2);
>>> - EXPECT_EQ("foo", exports[0].name);
>>> + EXPECT_EQ("_foo", exports[0].name);
>>> EXPECT_EQ(8, exports[0].ordinal);
>>> EXPECT_TRUE(exports[0].noname);
>>> EXPECT_TRUE(exports[0].isData);
>>> - EXPECT_EQ("bar", exports[1].name);
>>> + EXPECT_EQ("_bar", exports[1].name);
>>> EXPECT_EQ(10, exports[1].ordinal);
>>> EXPECT_FALSE(exports[1].noname);
>>> EXPECT_TRUE(exports[1].isData);
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>>
>
>
> --
> Saleem Abdulrasool
> compnerd (at) compnerd (dot) org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131227/f25bce2d/attachment.html>
More information about the llvm-commits
mailing list