[lld] r197970 - [PECOFF] Fix /export option in the .drectve section.

Saleem Abdulrasool compnerd at compnerd.org
Thu Dec 26 18:25:39 PST 2013


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 :-).


>
> 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/20131226/8d9fa084/attachment.html>


More information about the llvm-commits mailing list