[lld] [LLD][COFF] Process all ARM64EC import symbols in getSymbols (PR #109118)
Jacek Caban via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 18 02:50:05 PDT 2024
https://github.com/cjacek created https://github.com/llvm/llvm-project/pull/109118
None
>From 4beffdd8de68f764a0d86bac2be6bb7db5ae196a Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 17 Sep 2024 23:45:44 +0200
Subject: [PATCH 1/3] [LLD][COFF] Store __imp_ symbols as Defined in InputFile
---
lld/COFF/InputFiles.h | 4 ++--
lld/COFF/MapFile.cpp | 3 +--
lld/COFF/SymbolTable.cpp | 6 +++---
lld/COFF/SymbolTable.h | 4 ++--
4 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h
index 5fa93f57ef9e3a..a20b097cbe04af 100644
--- a/lld/COFF/InputFiles.h
+++ b/lld/COFF/InputFiles.h
@@ -349,7 +349,7 @@ class ImportFile : public InputFile {
MachineTypes getMachineType() const override;
DefinedImportData *impSym = nullptr;
- Symbol *thunkSym = nullptr;
+ Defined *thunkSym = nullptr;
ImportThunkChunkARM64EC *impchkThunk = nullptr;
std::string dllName;
@@ -365,7 +365,7 @@ class ImportFile : public InputFile {
// Auxiliary IAT symbols and chunks on ARM64EC.
DefinedImportData *impECSym = nullptr;
Chunk *auxLocation = nullptr;
- Symbol *auxThunkSym = nullptr;
+ Defined *auxThunkSym = nullptr;
DefinedImportData *auxImpCopySym = nullptr;
Chunk *auxCopyLocation = nullptr;
diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp
index 52e9ce996f2390..69842ced284cbd 100644
--- a/lld/COFF/MapFile.cpp
+++ b/lld/COFF/MapFile.cpp
@@ -128,8 +128,7 @@ static void getSymbols(const COFFLinkerContext &ctx,
if (!file->thunkSym->isLive())
continue;
- if (auto *thunkSym = dyn_cast<Defined>(file->thunkSym))
- syms.push_back(thunkSym);
+ syms.push_back(thunkSym);
if (auto *impSym = dyn_cast_or_null<Defined>(file->impSym))
syms.push_back(impSym);
diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index efea16ccbbfea0..fc169ec211a9fe 100644
--- a/lld/COFF/SymbolTable.cpp
+++ b/lld/COFF/SymbolTable.cpp
@@ -815,13 +815,13 @@ DefinedImportData *SymbolTable::addImportData(StringRef n, ImportFile *f,
return nullptr;
}
-Symbol *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
- ImportThunkChunk *chunk) {
+Defined *SymbolTable::addImportThunk(StringRef name, DefinedImportData *id,
+ ImportThunkChunk *chunk) {
auto [s, wasInserted] = insert(name, nullptr);
s->isUsedInRegularObj = true;
if (wasInserted || isa<Undefined>(s) || s->isLazy()) {
replaceSymbol<DefinedImportThunk>(s, ctx, name, id, chunk);
- return s;
+ return cast<Defined>(s);
}
reportDuplicate(s, id->file);
diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index bf97cf442039e0..e3f674b8098f8b 100644
--- a/lld/COFF/SymbolTable.h
+++ b/lld/COFF/SymbolTable.h
@@ -105,8 +105,8 @@ class SymbolTable {
CommonChunk *c = nullptr);
DefinedImportData *addImportData(StringRef n, ImportFile *f,
Chunk *&location);
- Symbol *addImportThunk(StringRef name, DefinedImportData *s,
- ImportThunkChunk *chunk);
+ Defined *addImportThunk(StringRef name, DefinedImportData *s,
+ ImportThunkChunk *chunk);
void addLibcall(StringRef name);
void addEntryThunk(Symbol *from, Symbol *to);
void addExitThunk(Symbol *from, Symbol *to);
>From 22125606aac91300557769db2a8ce0ca6c24af80 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Wed, 18 Sep 2024 00:00:34 +0200
Subject: [PATCH 2/3] [LLD][COFF] Process all live import symbols in
getSymbols()
The current logic assumes that the import file is pulled by object files,
and the loop for import files only needs to handle cases where the __imp_
symbol is implicitly pulled by an import thunk. This is fragile, as the
symbol may also be pulled through other means, such as the -export argument
in tests. Additionally, this logic is insufficient for ARM64EC, which
exposes multiple symbols through an import file, and referencing any one
of them causes all of them to be defined.
With this change, import symbols are added to syms more often, but we
ensure that output symbols remain unique later in the process.
---
lld/COFF/MapFile.cpp | 13 +++----------
lld/test/COFF/export-imp.test | 11 +++++++++++
2 files changed, 14 insertions(+), 10 deletions(-)
create mode 100644 lld/test/COFF/export-imp.test
diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp
index 69842ced284cbd..b9ef32da113c4f 100644
--- a/lld/COFF/MapFile.cpp
+++ b/lld/COFF/MapFile.cpp
@@ -122,16 +122,9 @@ static void getSymbols(const COFFLinkerContext &ctx,
if (!file->live)
continue;
- if (!file->thunkSym)
- continue;
-
- if (!file->thunkSym->isLive())
- continue;
-
- syms.push_back(thunkSym);
-
- if (auto *impSym = dyn_cast_or_null<Defined>(file->impSym))
- syms.push_back(impSym);
+ syms.push_back(file->impSym);
+ if (file->thunkSym && file->thunkSym->isLive())
+ syms.push_back(file->thunkSym);
}
sortUniqueSymbols(syms, ctx.config.imageBase);
diff --git a/lld/test/COFF/export-imp.test b/lld/test/COFF/export-imp.test
new file mode 100644
index 00000000000000..db71ef74641639
--- /dev/null
+++ b/lld/test/COFF/export-imp.test
@@ -0,0 +1,11 @@
+; REQUIRES: x86
+
+; RUN: llvm-lib -machine:amd64 -out:%t.imp.lib -def:%s
+; RUN: lld-link -machine:amd64 -out:%t.dll %t.imp.lib -dll -noentry -export:__imp_func,DATA -map
+
+; FileCheck %s < %t.imp.map
+; CHECK: 0001:00000098 __imp_func 0000000180001098 export-imp-thunk.test.tmp.imp:imp.dll
+
+LIBRARY imp.dll
+EXPORTS
+ func
>From e4819ca92e71b98bc0e5b21e038f8138255fc7c3 Mon Sep 17 00:00:00 2001
From: Jacek Caban <jacek at codeweavers.com>
Date: Tue, 17 Sep 2024 23:25:45 +0200
Subject: [PATCH 3/3] [LLD][COFF] Process all ARM64EC import symbols in
getSymbols
---
lld/COFF/Chunks.h | 3 ++-
lld/COFF/InputFiles.cpp | 3 ++-
lld/COFF/MapFile.cpp | 8 ++++++++
lld/test/COFF/arm64ec-import.test | 28 +++++++++++++++++++++++++---
4 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 24d7c37de7f3b0..0a35046fc5143e 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -624,7 +624,8 @@ class ImportThunkChunkARM64EC : public ImportThunkChunk {
MachineTypes getMachine() const override { return ARM64EC; }
void writeTo(uint8_t *buf) const override;
- Defined *exitThunk;
+ Defined *exitThunk = nullptr;
+ Defined *sym = nullptr;
private:
ImportFile *file;
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index d9184b04735e83..b19275abebc3ac 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -1126,7 +1126,8 @@ void ImportFile::parse() {
StringRef impChkName = saver().save("__impchk_" + name);
impchkThunk = make<ImportThunkChunkARM64EC>(this);
- ctx.symtab.addImportThunk(impChkName, impSym, impchkThunk);
+ impchkThunk->sym =
+ ctx.symtab.addImportThunk(impChkName, impSym, impchkThunk);
ctx.driver.pullArm64ECIcallHelper();
}
}
diff --git a/lld/COFF/MapFile.cpp b/lld/COFF/MapFile.cpp
index b9ef32da113c4f..8f7c228f5d3b1c 100644
--- a/lld/COFF/MapFile.cpp
+++ b/lld/COFF/MapFile.cpp
@@ -125,6 +125,14 @@ static void getSymbols(const COFFLinkerContext &ctx,
syms.push_back(file->impSym);
if (file->thunkSym && file->thunkSym->isLive())
syms.push_back(file->thunkSym);
+ if (file->auxThunkSym && file->auxThunkSym->isLive())
+ syms.push_back(file->auxThunkSym);
+ if (file->impchkThunk)
+ syms.push_back(file->impchkThunk->sym);
+ if (file->impECSym)
+ syms.push_back(file->impECSym);
+ if (file->auxImpCopySym)
+ syms.push_back(file->auxImpCopySym);
}
sortUniqueSymbols(syms, ctx.config.imageBase);
diff --git a/lld/test/COFF/arm64ec-import.test b/lld/test/COFF/arm64ec-import.test
index 92d7f5517bd426..08ff31ce1a8f3b 100644
--- a/lld/test/COFF/arm64ec-import.test
+++ b/lld/test/COFF/arm64ec-import.test
@@ -12,15 +12,15 @@ RUN: llvm-lib -machine:x64 -def:test.def -out:test-x86_64.lib
Link using ARM64EC import library:
RUN: lld-link -machine:arm64ec -dll -noentry -out:out.dll loadconfig-arm64ec.obj icall.obj hybmp.obj \
-RUN: test.obj test-arm64ec.lib test2-arm64ec.lib
+RUN: test.obj test-arm64ec.lib test2-arm64ec.lib -map
Link using x86_64 import library:
RUN: lld-link -machine:arm64ec -dll -noentry -out:out2.dll loadconfig-arm64ec.obj icall.obj hybmp.obj \
-RUN: test.obj test-x86_64.lib test2-arm64ec.lib
+RUN: test.obj test-x86_64.lib test2-arm64ec.lib -map
Link using x86_64 object file:
RUN: lld-link -machine:arm64ec -dll -noentry -out:out3.dll loadconfig-arm64ec.obj icall.obj hybmp.obj \
-RUN: test-x86_64.obj test-arm64ec.lib test2-arm64ec.lib
+RUN: test-x86_64.obj test-arm64ec.lib test2-arm64ec.lib -map
RUN: llvm-readobj --coff-imports out.dll | FileCheck --check-prefix=IMPORTS %s
RUN: llvm-readobj --coff-imports out2.dll | FileCheck --check-prefix=IMPORTS %s
@@ -87,6 +87,28 @@ TESTSEC-X64-NEXT: 0x180007010 08300000 00500000 10300000 20300000
TESTSEC-X64-NEXT: 0x180007020 14100000 28100000 00200000 08100000
TESTSEC-X64-NEXT: 0x180007030 3c100000 a0420000
+RUN: FileCheck --check-prefix=MAP %s < out.map
+RUN: FileCheck --check-prefix=MAP %s < out2.map
+RUN: FileCheck --check-prefix=MAP %s < out3.map
+MAP: 0001:00000008 #func 0000000180001008 test{{.*}}:test.dll
+MAP-NEXT: 0001:00000014 __impchk_func 0000000180001014 test{{.*}}:test.dll
+MAP-NEXT: 0001:00000028 __impchk_func2 0000000180001028 test{{.*}}:test.dll
+MAP-NEXT: 0001:0000003c #t2func 000000018000103c test2{{.*}}:test2.dll
+MAP-NEXT: 0001:00000048 __impchk_t2func 0000000180001048 test2{{.*}}:test2.dll
+MAP: 0001:00001000 func 0000000180002000 test{{.*}}:test.dll
+MAP-NEXT: 0002:00000000 __imp_data 0000000180003000 test{{.*}}:test.dll
+MAP-NEXT: 0002:00000008 __imp_aux_func 0000000180003008 test{{.*}}:test.dll
+MAP-NEXT: 0002:00000010 __imp_aux_func2 0000000180003010 test{{.*}}:test.dll
+MAP-NEXT: 0002:00000020 __imp_aux_t2func 0000000180003020 test2{{.*}}:test2.dll
+MAP: 0002:00001298 __auximpcopy_data 0000000180004298 test{{.*}}:test.dll
+MAP-NEXT: 0002:000012a0 __auximpcopy_func 00000001800042a0 test{{.*}}:test.dll
+MAP-NEXT: 0002:000012a8 __auximpcopy_func2 00000001800042a8 test{{.*}}:test.dll
+MAP-NEXT: 0002:000012b8 __auximpcopy_t2func 00000001800042b8 test2{{.*}}:test2.dll
+MAP: 0002:00002000 __imp_aux_data 0000000180005000 test{{.*}}:test.dll
+MAP-NEXT: 0002:00002008 __imp_func 0000000180005008 test{{.*}}:test.dll
+MAP-NEXT: 0002:00002010 __imp_func2 0000000180005010 test{{.*}}:test.dll
+MAP-NEXT: 0002:00002020 __imp_t2func 0000000180005020 test2{{.*}}:test2.dll
+
RUN: llvm-readobj --headers out.dll | FileCheck -check-prefix=HEADERS %s
RUN: llvm-readobj --headers out2.dll | FileCheck -check-prefix=HEADERS %s
RUN: llvm-readobj --headers out3.dll | FileCheck -check-prefix=HEADERS %s
More information about the llvm-commits
mailing list