diff --git a/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h b/lld/include/lld/ReaderWriter/PECOFFLinkingContext.h index d5aa5079ea01757bade1dad7af766bb8ab2d22aa..8edd8199ab0282c8e6133a4efe72cd4e5389bbd2 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 c38657a442292ddce98268e5169e20fd49b76e54..410c21bb70940bd11b593e83a011c8a951430c6a 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 7533a286febe378759800beca867f0f826b2c8ee..eb23703c0222d474c4b0907e7c2e543aba1f059b 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 ceeda806268fb56afd695a488c20bd13630a72a2..0835dfb69d2f3ee04999513c7b35ae7b1e40ea01 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 429bffe554089401eb89df5d3b33be6b317e7ce9..eeefb8a0fe7eeb4d9b3fe8b84d2f3b42b388deff 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