[Arm64EC] Copy import descriptors to the EC Map#84834
Merged
Merged
Conversation
Member
|
@llvm/pr-subscribers-llvm-binary-utilities Author: Daniel Paoliello (dpaoliello) ChangesAs noted in <#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: This change copies import descriptors from the regular map to the EC map, which fixes this linking error. Full diff: https://github.com/llvm/llvm-project/pull/84834.diff 5 Files Affected:
diff --git a/llvm/include/llvm/Object/COFFImportFile.h b/llvm/include/llvm/Object/COFFImportFile.h
index 402ded0d64fef2..369fd5b8705aed 100644
--- a/llvm/include/llvm/Object/COFFImportFile.h
+++ b/llvm/include/llvm/Object/COFFImportFile.h
@@ -26,6 +26,11 @@
namespace llvm {
namespace object {
+constexpr std::string_view ImportDescriptorPrefix = "__IMPORT_DESCRIPTOR_";
+constexpr std::string_view NullImportDescriptorSymbolName = "__NULL_IMPORT_DESCRIPTOR";
+constexpr std::string_view NullThunkDataPrefix = "\x7f";
+constexpr std::string_view NullThunkDataSuffix = "_NULL_THUNK_DATA";
+
class COFFImportFile : public SymbolicFile {
private:
enum SymbolIndex { ImpSymbol, ThunkSymbol, ECAuxSymbol, ECThunkSymbol };
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index be51093933a87c..fd50779ca9f748 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -677,6 +677,15 @@ static bool isECObject(object::SymbolicFile &Obj) {
return false;
}
+bool isImportDescriptor(const std::string_view Name) {
+ return Name.substr(0, ImportDescriptorPrefix.size()) == ImportDescriptorPrefix ||
+ Name == NullImportDescriptorSymbolName ||
+ (Name.substr(0, NullThunkDataPrefix.size()) == NullThunkDataPrefix &&
+ Name.size() > NullThunkDataSuffix.size() &&
+ Name.substr(Name.size() - NullThunkDataSuffix.size()) ==
+ NullThunkDataSuffix);
+}
+
static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
uint16_t Index,
raw_ostream &SymNames,
@@ -687,8 +696,14 @@ static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
return Ret;
std::map<std::string, uint16_t> *Map = nullptr;
- if (SymMap)
- Map = SymMap->UseECMap && isECObject(*Obj) ? &SymMap->ECMap : &SymMap->Map;
+ bool CopyImportDescriptorToECMap = false;
+ if (SymMap) {
+ bool IsECObject = isECObject(*Obj);
+ Map = SymMap->UseECMap && IsECObject ? &SymMap->ECMap : &SymMap->Map;
+ // If EC is enabled, then the import descriptors are NOT put into EC objects
+ // so we need to copy them to the EC map manually.
+ CopyImportDescriptorToECMap = SymMap->UseECMap && !IsECObject;
+ }
for (const object::BasicSymbolRef &S : Obj->symbols()) {
if (!isArchiveSymbol(S))
@@ -704,6 +719,8 @@ static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
if (Map == &SymMap->Map) {
Ret.push_back(SymNames.tell());
SymNames << Name << '\0';
+ if (CopyImportDescriptorToECMap && isImportDescriptor(Name))
+ SymMap->ECMap[Name] = Index;
}
} else {
Ret.push_back(SymNames.tell());
diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp
index 376dd126baf61a..f2f2b3835e20cb 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -108,7 +108,7 @@ template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {
}
static void writeStringTable(std::vector<uint8_t> &B,
- ArrayRef<const std::string> Strings) {
+ ArrayRef<const std::string_view> Strings) {
// The COFF string table consists of a 4-byte value which is the size of the
// table, including the length field itself. This value is followed by the
// string content itself, which is an array of null-terminated C-style
@@ -171,9 +171,6 @@ static Expected<std::string> replace(StringRef S, StringRef From,
return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();
}
-static const std::string NullImportDescriptorSymbolName =
- "__NULL_IMPORT_DESCRIPTOR";
-
namespace {
// This class constructs various small object files necessary to support linking
// symbols imported from a DLL. The contents are pretty strictly defined and
@@ -192,8 +189,8 @@ class ObjectFactory {
public:
ObjectFactory(StringRef S, MachineTypes M)
: NativeMachine(M), ImportName(S), Library(llvm::sys::path::stem(S)),
- ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()),
- NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {}
+ ImportDescriptorSymbolName((ImportDescriptorPrefix + Library).str()),
+ NullThunkSymbolName((NullThunkDataPrefix + Library + NullThunkDataSuffix).str()) {}
// Creates an Import Descriptor. This is a small object file which contains a
// reference to the terminators and contains the library name (entry) for the
diff --git a/llvm/test/tools/llvm-dlltool/arm64ec.test b/llvm/test/tools/llvm-dlltool/arm64ec.test
index e742a77ff78a52..b03b4eaf7b2d0e 100644
--- a/llvm/test/tools/llvm-dlltool/arm64ec.test
+++ b/llvm/test/tools/llvm-dlltool/arm64ec.test
@@ -12,9 +12,12 @@ ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
ARMAP-EMPTY:
ARMAP-NEXT: Archive EC map
ARMAP-NEXT: #func in test.dll
+ARMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
ARMAP-NEXT: __imp_aux_func in test.dll
ARMAP-NEXT: __imp_func in test.dll
ARMAP-NEXT: func in test.dll
+ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
RUN: llvm-dlltool -m arm64ec -d test.def -N test2.def -l test2.lib
RUN: llvm-nm --print-armap test2.lib | FileCheck --check-prefix=ARMAP2 %s
@@ -28,9 +31,12 @@ ARMAP2-NEXT: test_NULL_THUNK_DATA in test.dll
ARMAP2-EMPTY:
ARMAP2-NEXT: Archive EC map
ARMAP2-NEXT: #func in test.dll
+ARMAP2-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAP2-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
ARMAP2-NEXT: __imp_aux_func in test.dll
ARMAP2-NEXT: __imp_func in test.dll
ARMAP2-NEXT: func in test.dll
+ARMAP2-NEXT: test_NULL_THUNK_DATA in test.dll
RUN: llvm-dlltool -m arm64ec -d test.def --input-native-def test2.def -l test3.lib
RUN: llvm-nm --print-armap test3.lib | FileCheck --check-prefix=ARMAP2 %s
diff --git a/llvm/test/tools/llvm-lib/arm64ec-implib.test b/llvm/test/tools/llvm-lib/arm64ec-implib.test
index 77bdc23589fd25..00eddd2a475268 100644
--- a/llvm/test/tools/llvm-lib/arm64ec-implib.test
+++ b/llvm/test/tools/llvm-lib/arm64ec-implib.test
@@ -16,6 +16,8 @@ ARMAP-NEXT: #funcexp in test.dll
ARMAP-NEXT: #mangledfunc in test.dll
ARMAP-NEXT: ?test_cpp_func@@$$hYAHPEAX@Z in test.dll
ARMAP-NEXT: ?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
ARMAP-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test.dll
ARMAP-NEXT: __imp_aux_?test_cpp_func@@YAHPEAX@Z in test.dll
ARMAP-NEXT: __imp_aux_expname in test.dll
@@ -28,6 +30,7 @@ ARMAP-NEXT: __imp_mangledfunc in test.dll
ARMAP-NEXT: expname in test.dll
ARMAP-NEXT: funcexp in test.dll
ARMAP-NEXT: mangledfunc in test.dll
+ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
RUN: llvm-readobj test.lib | FileCheck -check-prefix=READOBJ %s
@@ -122,6 +125,8 @@ ARMAPX-NEXT: #funcexp in test.dll
ARMAPX-NEXT: #mangledfunc in test.dll
ARMAPX-NEXT: ?test_cpp_func@@$$hYAHPEAX@Z in test.dll
ARMAPX-NEXT: ?test_cpp_func@@YAHPEAX@Z in test.dll
+ARMAPX-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+ARMAPX-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
ARMAPX-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test.dll
ARMAPX-NEXT: __imp_aux_?test_cpp_func@@YAHPEAX@Z in test.dll
ARMAPX-NEXT: __imp_aux_expname in test.dll
@@ -134,6 +139,7 @@ ARMAPX-NEXT: __imp_mangledfunc in test.dll
ARMAPX-NEXT: expname in test.dll
ARMAPX-NEXT: funcexp in test.dll
ARMAPX-NEXT: mangledfunc in test.dll
+ARMAPX-NEXT: test_NULL_THUNK_DATA in test.dll
RUN: llvm-readobj testx.lib | FileCheck -check-prefix=READOBJX %s
@@ -255,6 +261,8 @@ ARMAPX2-NEXT: #funcexp in test2.dll
ARMAPX2-NEXT: #mangledfunc in test2.dll
ARMAPX2-NEXT: ?test_cpp_func@@$$hYAHPEAX@Z in test2.dll
ARMAPX2-NEXT: ?test_cpp_func@@YAHPEAX@Z in test2.dll
+ARMAPX2-NEXT: __IMPORT_DESCRIPTOR_test2 in test2.dll
+ARMAPX2-NEXT: __NULL_IMPORT_DESCRIPTOR in test2.dll
ARMAPX2-NEXT: __imp_?test_cpp_func@@YAHPEAX@Z in test2.dll
ARMAPX2-NEXT: __imp_aux_?test_cpp_func@@YAHPEAX@Z in test2.dll
ARMAPX2-NEXT: __imp_aux_expname in test2.dll
@@ -267,6 +275,7 @@ ARMAPX2-NEXT: __imp_mangledfunc in test2.dll
ARMAPX2-NEXT: expname in test2.dll
ARMAPX2-NEXT: funcexp in test2.dll
ARMAPX2-NEXT: mangledfunc in test2.dll
+ARMAPX2-NEXT: test2_NULL_THUNK_DATA in test2.dll
ARMAPX2: test2.dll:
ARMAPX2: 00000000 T #funcexp
@@ -309,6 +318,8 @@ EXPAS-ARMAP-NEXT: #func1 in test.dll
EXPAS-ARMAP-NEXT: #func2 in test.dll
EXPAS-ARMAP-NEXT: #func3 in test.dll
EXPAS-ARMAP-NEXT: #func4 in test.dll
+EXPAS-ARMAP-NEXT: __IMPORT_DESCRIPTOR_test in test.dll
+EXPAS-ARMAP-NEXT: __NULL_IMPORT_DESCRIPTOR in test.dll
EXPAS-ARMAP-NEXT: __imp_aux_func1 in test.dll
EXPAS-ARMAP-NEXT: __imp_aux_func2 in test.dll
EXPAS-ARMAP-NEXT: __imp_aux_func3 in test.dll
@@ -323,6 +334,7 @@ EXPAS-ARMAP-NEXT: func1 in test.dll
EXPAS-ARMAP-NEXT: func2 in test.dll
EXPAS-ARMAP-NEXT: func3 in test.dll
EXPAS-ARMAP-NEXT: func4 in test.dll
+EXPAS-ARMAP-NEXT: test_NULL_THUNK_DATA in test.dll
EXPAS-READOBJ: File: test.dll
EXPAS-READOBJ-NEXT: Format: COFF-import-file-ARM64EC
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
cjacek
reviewed
Mar 11, 2024
Contributor
efriedma-quic
left a comment
There was a problem hiding this comment.
Generally looks okay, but I'll defer to @cjacek for approval.
dpaoliello
added a commit
to dpaoliello/llvm-project
that referenced
this pull request
Mar 12, 2024
As noted in <llvm#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: ``` bcryptprimitives.lib(bcryptprimitives.dll) : error LNK2001: unresolved external symbol __IMPORT_DESCRIPTOR_bcryptprimitives (EC Symbol) ``` This change copies import descriptors from the regular map to the EC map, which fixes this linking error.
dpaoliello
added a commit
to dpaoliello/llvm-project
that referenced
this pull request
Mar 13, 2024
As noted in <llvm#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: ``` bcryptprimitives.lib(bcryptprimitives.dll) : error LNK2001: unresolved external symbol __IMPORT_DESCRIPTOR_bcryptprimitives (EC Symbol) ``` This change copies import descriptors from the regular map to the EC map, which fixes this linking error.
dpaoliello
added a commit
to dpaoliello/llvm-project
that referenced
this pull request
Mar 13, 2024
As noted in <llvm#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: ``` bcryptprimitives.lib(bcryptprimitives.dll) : error LNK2001: unresolved external symbol __IMPORT_DESCRIPTOR_bcryptprimitives (EC Symbol) ``` This change copies import descriptors from the regular map to the EC map, which fixes this linking error.
dpaoliello
added a commit
to dpaoliello/llvm-project
that referenced
this pull request
Mar 15, 2024
As noted in <llvm#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: ``` bcryptprimitives.lib(bcryptprimitives.dll) : error LNK2001: unresolved external symbol __IMPORT_DESCRIPTOR_bcryptprimitives (EC Symbol) ``` This change copies import descriptors from the regular map to the EC map, which fixes this linking error.
tstellar
pushed a commit
to dpaoliello/llvm-project
that referenced
this pull request
Mar 16, 2024
As noted in <llvm#78537>, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC: ``` bcryptprimitives.lib(bcryptprimitives.dll) : error LNK2001: unresolved external symbol __IMPORT_DESCRIPTOR_bcryptprimitives (EC Symbol) ``` This change copies import descriptors from the regular map to the EC map, which fixes this linking error.
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
As noted in #78537, MSVC places import descriptors in both the EC and regular map - that PR moved the descriptors to ONLY the regular map, however this causes linking errors when linking as Arm64EC:
This change copies import descriptors from the regular map to the EC map, which fixes this linking error.