From abc227be822401334a3afe622ad73d50436e7313 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sat, 14 Dec 2013 04:32:29 +0000 Subject: [PATCH] [PECOFF] Export undecorated symbols from DLL. Symbol names exported from a DLL should be undecorated, not prefixed by an underscore ones. llvm-svn: 197307 --- .../lld/ReaderWriter/PECOFFLinkingContext.h | 12 ++---------- lld/lib/ReaderWriter/PECOFF/EdataPass.cpp | 9 +++++---- lld/lib/ReaderWriter/PECOFF/EdataPass.h | 3 ++- .../PECOFF/PECOFFLinkingContext.cpp | 18 ++++++++++++++++++ lld/test/pecoff/export.test | 6 +++--- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h index d5aa5079ea01..8edd8199ab02 100644 --- a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h @@ -99,16 +99,8 @@ public: StringRef searchLibraryFile(StringRef path) const; - /// Returns the decorated name of the given symbol name. On 32-bit x86, it - /// adds "_" at the beginning of the string. On other architectures, the - /// return value is the same as the argument. - StringRef decorateSymbol(StringRef name) const { - if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) - return name; - std::string str = "_"; - str.append(name); - return allocate(str); - } + StringRef decorateSymbol(StringRef name) const; + StringRef undecorateSymbol(StringRef name) const; void setEntrySymbolName(StringRef name) { if (!name.empty()) diff --git a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp index c38657a44229..410c21bb7094 100644 --- a/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp +++ b/lld/lib/ReaderWriter/PECOFF/EdataPass.cpp @@ -62,15 +62,16 @@ EdataPass::createAddressTable(const std::vector &atoms) { } edata::EdataAtom * -EdataPass::createNamePointerTable(const std::vector &atoms, +EdataPass::createNamePointerTable(const PECOFFLinkingContext &ctx, + const std::vector &atoms, MutableFile *file) { EdataAtom *table = new (_alloc) EdataAtom(_file, sizeof(uint32_t) * atoms.size()); size_t offset = 0; for (const DefinedAtom *atom : atoms) { - COFFStringAtom *stringAtom = new (_alloc) - COFFStringAtom(_file, _stringOrdinal++, ".edata", atom->name()); + auto *stringAtom = new (_alloc) COFFStringAtom( + _file, _stringOrdinal++, ".edata", ctx.undecorateSymbol(atom->name())); file->addAtom(*stringAtom); addDir32NBReloc(table, stringAtom, offset); offset += sizeof(uint32_t); @@ -121,7 +122,7 @@ void EdataPass::perform(std::unique_ptr &file) { addDir32NBReloc(table, addressTable, offsetof(export_directory_table_entry, ExportAddressTableRVA)); - EdataAtom *namePointerTable = createNamePointerTable(atoms, file.get()); + EdataAtom *namePointerTable = createNamePointerTable(_ctx, atoms, file.get()); file->addAtom(*namePointerTable); addDir32NBReloc(table, namePointerTable, offsetof(export_directory_table_entry, NamePointerRVA)); diff --git a/lld/lib/ReaderWriter/PECOFF/EdataPass.h b/lld/lib/ReaderWriter/PECOFF/EdataPass.h index 7533a286febe..eb23703c0222 100644 --- a/lld/lib/ReaderWriter/PECOFF/EdataPass.h +++ b/lld/lib/ReaderWriter/PECOFF/EdataPass.h @@ -66,7 +66,8 @@ private: edata::EdataAtom * createAddressTable(const std::vector &atoms); edata::EdataAtom * - createNamePointerTable(const std::vector &atoms, + createNamePointerTable(const PECOFFLinkingContext &ctx, + const std::vector &atoms, MutableFile *file); edata::EdataAtom * createOrdinalTable(const std::vector &atoms); diff --git a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp index ceeda806268f..0835dfb69d2f 100644 --- a/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp @@ -183,6 +183,24 @@ StringRef PECOFFLinkingContext::searchLibraryFile(StringRef filename) const { return filename; } +/// Returns the decorated name of the given symbol name. On 32-bit x86, it +/// adds "_" at the beginning of the string. On other architectures, the +/// return value is the same as the argument. +StringRef PECOFFLinkingContext::decorateSymbol(StringRef name) const { + if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) + return name; + std::string str = "_"; + str.append(name); + 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; } ErrorOr diff --git a/lld/test/pecoff/export.test b/lld/test/pecoff/export.test index 429bffe55408..eeefb8a0fe7e 100644 --- a/lld/test/pecoff/export.test +++ b/lld/test/pecoff/export.test @@ -8,7 +8,7 @@ CHECK: Contents of section .edata: CHECK-NEXT: 1000 00000000 {{........}} 00000000 3c100000 CHECK-NEXT: 1010 01000000 02000000 02000000 28100000 CHECK-NEXT: 1020 30100000 38100000 08200000 10200000 -CHECK-NEXT: 1030 50100000 5b100000 00000100 6578706f +CHECK-NEXT: 1030 50100000 5a100000 00000100 6578706f CHECK-NEXT: 1040 72742e74 6573742e 746d702e 646c6c00 -CHECK-NEXT: 1050 5f657870 6f727466 6e31005f 6578706f -CHECK-NEXT: 1060 7274666e 3200 +CHECK-NEXT: 1050 6578706f 7274666e 31006578 706f7274 +CHECK-NEXT: 1060 666e3200 -- GitLab