-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLD][COFF] Support MinGW constructor and destructor lists on ARM64X #127205
Conversation
Depends on #127203. |
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-lld Author: Jacek Caban (cjacek) ChangesSplit the chunks for EC and native views, inserting headers and tails for both. Full diff: https://github.com/llvm/llvm-project/pull/127205.diff 6 Files Affected:
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index a01c69c709876..3494d1ba0ac02 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -1070,16 +1070,20 @@ void MergeChunk::writeTo(uint8_t *buf) const {
}
// MinGW specific.
-size_t AbsolutePointerChunk::getSize() const { return ctx.config.wordsize; }
+size_t AbsolutePointerChunk::getSize() const {
+ return symtab.ctx.config.wordsize;
+}
void AbsolutePointerChunk::writeTo(uint8_t *buf) const {
- if (ctx.config.is64()) {
+ if (symtab.ctx.config.is64()) {
write64le(buf, value);
} else {
write32le(buf, value);
}
}
+MachineTypes AbsolutePointerChunk::getMachine() const { return symtab.machine; }
+
void ECExportThunkChunk::writeTo(uint8_t *buf) const {
memcpy(buf, ECExportThunkCode, sizeof(ECExportThunkCode));
write32le(buf + 10, target->getRVA() - rva - 14);
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index d6216efdd90bd..06e9aae0e6f6e 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -910,16 +910,17 @@ class PseudoRelocTableChunk : public NonSectionChunk {
// MinGW specific. A Chunk that contains one pointer-sized absolute value.
class AbsolutePointerChunk : public NonSectionChunk {
public:
- AbsolutePointerChunk(COFFLinkerContext &ctx, uint64_t value)
- : value(value), ctx(ctx) {
+ AbsolutePointerChunk(SymbolTable &symtab, uint64_t value)
+ : value(value), symtab(symtab) {
setAlignment(getSize());
}
size_t getSize() const override;
void writeTo(uint8_t *buf) const override;
+ MachineTypes getMachine() const override;
private:
uint64_t value;
- COFFLinkerContext &ctx;
+ SymbolTable &symtab;
};
// Return true if this file has the hotpatch flag set to true in the S_COMPILE3
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 678de915b6cdb..58727c1615769 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -403,6 +403,12 @@ void OutputSection::addContributingPartialSection(PartialSection *sec) {
contribSections.push_back(sec);
}
+void OutputSection::splitECChunks() {
+ llvm::stable_sort(chunks, [=](const Chunk *a, const Chunk *b) {
+ return (a->getMachine() != ARM64) < (b->getMachine() != ARM64);
+ });
+}
+
// Check whether the target address S is in range from a relocation
// of type relType at address P.
bool Writer::isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin,
@@ -1156,6 +1162,11 @@ void Writer::createSections() {
sec->addContributingPartialSection(pSec);
}
+ if (ctx.hybridSymtab) {
+ if (OutputSection *sec = findSection(".CRT"))
+ sec->splitECChunks();
+ }
+
// Finally, move some output sections to the end.
auto sectionOrder = [&](const OutputSection *s) {
// Move DISCARDABLE (or non-memory-mapped) sections to the end of file
@@ -2324,21 +2335,28 @@ void Writer::createRuntimePseudoRelocs() {
// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
// and __DTOR_LIST__ respectively.
void Writer::insertCtorDtorSymbols() {
- AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(ctx, -1);
- AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(ctx, 0);
- AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(ctx, -1);
- AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(ctx, 0);
- ctorsSec->insertChunkAtStart(ctorListHead);
- ctorsSec->addChunk(ctorListEnd);
- dtorsSec->insertChunkAtStart(dtorListHead);
- dtorsSec->addChunk(dtorListEnd);
-
- Symbol *ctorListSym = ctx.symtab.findUnderscore("__CTOR_LIST__");
- Symbol *dtorListSym = ctx.symtab.findUnderscore("__DTOR_LIST__");
- replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
- ctorListHead);
- replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
- dtorListHead);
+ ctx.forEachSymtab([&](SymbolTable &symtab) {
+ AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(symtab, -1);
+ AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(symtab, 0);
+ AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(symtab, -1);
+ AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(symtab, 0);
+ ctorsSec->insertChunkAtStart(ctorListHead);
+ ctorsSec->addChunk(ctorListEnd);
+ dtorsSec->insertChunkAtStart(dtorListHead);
+ dtorsSec->addChunk(dtorListEnd);
+
+ Symbol *ctorListSym = symtab.findUnderscore("__CTOR_LIST__");
+ Symbol *dtorListSym = symtab.findUnderscore("__DTOR_LIST__");
+ replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
+ ctorListHead);
+ replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
+ dtorListHead);
+ });
+
+ if (ctx.hybridSymtab) {
+ ctorsSec->splitECChunks();
+ dtorsSec->splitECChunks();
+ }
}
// Handles /section options to allow users to overwrite
diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h
index 9004bb310d073..7e458b766bae8 100644
--- a/lld/COFF/Writer.h
+++ b/lld/COFF/Writer.h
@@ -50,6 +50,9 @@ class OutputSection {
void writeHeaderTo(uint8_t *buf, bool isDebug);
void addContributingPartialSection(PartialSection *sec);
+ // Sort chunks to split native and EC sections on hybrid targets.
+ void splitECChunks();
+
// Returns the size of this section in an executable memory image.
// This may be smaller than the raw size (the raw size is multiple
// of disk sector size, so there may be padding at end), or may be
diff --git a/lld/test/COFF/arm64x-crt-sec.s b/lld/test/COFF/arm64x-crt-sec.s
new file mode 100644
index 0000000000000..5be70a1845f12
--- /dev/null
+++ b/lld/test/COFF/arm64x-crt-sec.s
@@ -0,0 +1,42 @@
+// REQUIRES: aarch64, x86
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt1-arm64.s -o crt1-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt2-arm64.s -o crt2-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows crt1-arm64ec.s -o crt1-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows crt2-amd64.s -o crt2-amd64.obj
+
+// Check that .CRT chunks are correctly sorted and that EC and native chunks are split.
+
+// RUN: lld-link -out:out.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt2-arm64.obj crt1-arm64ec.obj crt2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out.dll | FileCheck %s
+
+// RUN: lld-link -out:out2.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt1-arm64ec.obj crt2-arm64.obj crt2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out2.dll | FileCheck %s
+
+// RUN: lld-link -out:out3.dll -machine:arm64x -dll -noentry crt2-amd64.obj crt1-arm64ec.obj crt2-arm64.obj crt1-arm64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out3.dll | FileCheck %s
+
+// CHECK: 0x180002000 01000000 00000000 02000000 00000000
+// CHECK-NEXT: 0x180002010 03000000 00000000 11000000 00000000
+// CHECK-NEXT: 0x180002020 12000000 00000000 13000000 00000000
+
+#--- crt1-arm64.s
+ .section .CRT$A,"dr"
+ .xword 1
+ .section .CRT$Z,"dr"
+ .xword 3
+
+#--- crt2-arm64.s
+ .section .CRT$B,"dr"
+ .xword 2
+
+#--- crt1-arm64ec.s
+ .section .CRT$A,"dr"
+ .xword 0x11
+ .section .CRT$Z,"dr"
+ .xword 0x13
+
+#--- crt2-amd64.s
+ .section .CRT$B,"dr"
+ .quad 0x12
diff --git a/lld/test/COFF/arm64x-ctors-sec.s b/lld/test/COFF/arm64x-ctors-sec.s
new file mode 100644
index 0000000000000..283d5f045260d
--- /dev/null
+++ b/lld/test/COFF/arm64x-ctors-sec.s
@@ -0,0 +1,76 @@
+// REQUIRES: aarch64, x86
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor1-arm64.s -o ctor1-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor2-arm64.s -o ctor2-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ctor1-arm64ec.s -o ctor1-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows ctor2-amd64.s -o ctor2-amd64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows test.s -o test-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test-arm64ec.obj
+
+// Check that .ctors and .dtors chunks are correctly sorted and that EC and native chunks are split.
+
+// RUN: lld-link -out:out.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor1-arm64.obj ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out.dll | FileCheck %s
+
+// RUN: lld-link -out:out2.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj ctor2-arm64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out2.dll | FileCheck %s
+
+// RUN: lld-link -out:out3.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out3.dll | FileCheck %s
+
+// CHECK: Hex dump of section '.rdata':
+// CHECK-NEXT: 0x180001000 ffffffff ffffffff 01000000 00000000
+// CHECK-NEXT: 0x180001010 02000000 00000000 03000000 00000000
+// CHECK-NEXT: 0x180001020 00000000 00000000 ffffffff ffffffff
+// CHECK-NEXT: 0x180001030 11000000 00000000 12000000 00000000
+// CHECK-NEXT: 0x180001040 13000000 00000000 00000000 00000000
+// CHECK-NEXT: 0x180001050 ffffffff ffffffff 01010000 00000000
+// CHECK-NEXT: 0x180001060 02010000 00000000 03010000 00000000
+// CHECK-NEXT: 0x180001070 00000000 00000000 ffffffff ffffffff
+// CHECK-NEXT: 0x180001080 11010000 00000000 12010000 00000000
+// CHECK-NEXT: 0x180001090 13010000 00000000 00000000 00000000
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.test':
+// CHECK-NEXT: 0x180003000 00100000 50100000 28100000 78100000
+
+#--- ctor1-arm64.s
+ .section .ctors.1,"drw"
+ .xword 1
+ .section .ctors.3,"drw"
+ .xword 3
+ .section .dtors.1,"drw"
+ .xword 0x101
+ .section .dtors.3,"drw"
+ .xword 0x103
+
+#--- ctor2-arm64.s
+ .section .ctors.2,"drw"
+ .xword 2
+ .section .dtors.2,"drw"
+ .xword 0x102
+
+#--- ctor1-arm64ec.s
+ .section .ctors.1,"drw"
+ .xword 0x11
+ .section .ctors.3,"drw"
+ .xword 0x13
+ .section .dtors.1,"drw"
+ .xword 0x111
+ .section .dtors.3,"drw"
+ .xword 0x113
+
+#--- ctor2-amd64.s
+ .section .ctors.2,"drw"
+ .quad 0x12
+ .section .dtors.2,"drw"
+ .quad 0x112
+
+#--- test.s
+ .section .test
+ .rva __CTOR_LIST__
+ .rva __DTOR_LIST__
+
|
@llvm/pr-subscribers-lld-coff Author: Jacek Caban (cjacek) ChangesSplit the chunks for EC and native views, inserting headers and tails for both. Full diff: https://github.com/llvm/llvm-project/pull/127205.diff 6 Files Affected:
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index a01c69c709876..3494d1ba0ac02 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -1070,16 +1070,20 @@ void MergeChunk::writeTo(uint8_t *buf) const {
}
// MinGW specific.
-size_t AbsolutePointerChunk::getSize() const { return ctx.config.wordsize; }
+size_t AbsolutePointerChunk::getSize() const {
+ return symtab.ctx.config.wordsize;
+}
void AbsolutePointerChunk::writeTo(uint8_t *buf) const {
- if (ctx.config.is64()) {
+ if (symtab.ctx.config.is64()) {
write64le(buf, value);
} else {
write32le(buf, value);
}
}
+MachineTypes AbsolutePointerChunk::getMachine() const { return symtab.machine; }
+
void ECExportThunkChunk::writeTo(uint8_t *buf) const {
memcpy(buf, ECExportThunkCode, sizeof(ECExportThunkCode));
write32le(buf + 10, target->getRVA() - rva - 14);
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index d6216efdd90bd..06e9aae0e6f6e 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -910,16 +910,17 @@ class PseudoRelocTableChunk : public NonSectionChunk {
// MinGW specific. A Chunk that contains one pointer-sized absolute value.
class AbsolutePointerChunk : public NonSectionChunk {
public:
- AbsolutePointerChunk(COFFLinkerContext &ctx, uint64_t value)
- : value(value), ctx(ctx) {
+ AbsolutePointerChunk(SymbolTable &symtab, uint64_t value)
+ : value(value), symtab(symtab) {
setAlignment(getSize());
}
size_t getSize() const override;
void writeTo(uint8_t *buf) const override;
+ MachineTypes getMachine() const override;
private:
uint64_t value;
- COFFLinkerContext &ctx;
+ SymbolTable &symtab;
};
// Return true if this file has the hotpatch flag set to true in the S_COMPILE3
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 678de915b6cdb..58727c1615769 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -403,6 +403,12 @@ void OutputSection::addContributingPartialSection(PartialSection *sec) {
contribSections.push_back(sec);
}
+void OutputSection::splitECChunks() {
+ llvm::stable_sort(chunks, [=](const Chunk *a, const Chunk *b) {
+ return (a->getMachine() != ARM64) < (b->getMachine() != ARM64);
+ });
+}
+
// Check whether the target address S is in range from a relocation
// of type relType at address P.
bool Writer::isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin,
@@ -1156,6 +1162,11 @@ void Writer::createSections() {
sec->addContributingPartialSection(pSec);
}
+ if (ctx.hybridSymtab) {
+ if (OutputSection *sec = findSection(".CRT"))
+ sec->splitECChunks();
+ }
+
// Finally, move some output sections to the end.
auto sectionOrder = [&](const OutputSection *s) {
// Move DISCARDABLE (or non-memory-mapped) sections to the end of file
@@ -2324,21 +2335,28 @@ void Writer::createRuntimePseudoRelocs() {
// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
// and __DTOR_LIST__ respectively.
void Writer::insertCtorDtorSymbols() {
- AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(ctx, -1);
- AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(ctx, 0);
- AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(ctx, -1);
- AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(ctx, 0);
- ctorsSec->insertChunkAtStart(ctorListHead);
- ctorsSec->addChunk(ctorListEnd);
- dtorsSec->insertChunkAtStart(dtorListHead);
- dtorsSec->addChunk(dtorListEnd);
-
- Symbol *ctorListSym = ctx.symtab.findUnderscore("__CTOR_LIST__");
- Symbol *dtorListSym = ctx.symtab.findUnderscore("__DTOR_LIST__");
- replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
- ctorListHead);
- replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
- dtorListHead);
+ ctx.forEachSymtab([&](SymbolTable &symtab) {
+ AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(symtab, -1);
+ AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(symtab, 0);
+ AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(symtab, -1);
+ AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(symtab, 0);
+ ctorsSec->insertChunkAtStart(ctorListHead);
+ ctorsSec->addChunk(ctorListEnd);
+ dtorsSec->insertChunkAtStart(dtorListHead);
+ dtorsSec->addChunk(dtorListEnd);
+
+ Symbol *ctorListSym = symtab.findUnderscore("__CTOR_LIST__");
+ Symbol *dtorListSym = symtab.findUnderscore("__DTOR_LIST__");
+ replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
+ ctorListHead);
+ replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
+ dtorListHead);
+ });
+
+ if (ctx.hybridSymtab) {
+ ctorsSec->splitECChunks();
+ dtorsSec->splitECChunks();
+ }
}
// Handles /section options to allow users to overwrite
diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h
index 9004bb310d073..7e458b766bae8 100644
--- a/lld/COFF/Writer.h
+++ b/lld/COFF/Writer.h
@@ -50,6 +50,9 @@ class OutputSection {
void writeHeaderTo(uint8_t *buf, bool isDebug);
void addContributingPartialSection(PartialSection *sec);
+ // Sort chunks to split native and EC sections on hybrid targets.
+ void splitECChunks();
+
// Returns the size of this section in an executable memory image.
// This may be smaller than the raw size (the raw size is multiple
// of disk sector size, so there may be padding at end), or may be
diff --git a/lld/test/COFF/arm64x-crt-sec.s b/lld/test/COFF/arm64x-crt-sec.s
new file mode 100644
index 0000000000000..5be70a1845f12
--- /dev/null
+++ b/lld/test/COFF/arm64x-crt-sec.s
@@ -0,0 +1,42 @@
+// REQUIRES: aarch64, x86
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt1-arm64.s -o crt1-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows crt2-arm64.s -o crt2-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows crt1-arm64ec.s -o crt1-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows crt2-amd64.s -o crt2-amd64.obj
+
+// Check that .CRT chunks are correctly sorted and that EC and native chunks are split.
+
+// RUN: lld-link -out:out.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt2-arm64.obj crt1-arm64ec.obj crt2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out.dll | FileCheck %s
+
+// RUN: lld-link -out:out2.dll -machine:arm64x -dll -noentry crt1-arm64.obj crt1-arm64ec.obj crt2-arm64.obj crt2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out2.dll | FileCheck %s
+
+// RUN: lld-link -out:out3.dll -machine:arm64x -dll -noentry crt2-amd64.obj crt1-arm64ec.obj crt2-arm64.obj crt1-arm64.obj
+// RUN: llvm-readobj --hex-dump=.CRT out3.dll | FileCheck %s
+
+// CHECK: 0x180002000 01000000 00000000 02000000 00000000
+// CHECK-NEXT: 0x180002010 03000000 00000000 11000000 00000000
+// CHECK-NEXT: 0x180002020 12000000 00000000 13000000 00000000
+
+#--- crt1-arm64.s
+ .section .CRT$A,"dr"
+ .xword 1
+ .section .CRT$Z,"dr"
+ .xword 3
+
+#--- crt2-arm64.s
+ .section .CRT$B,"dr"
+ .xword 2
+
+#--- crt1-arm64ec.s
+ .section .CRT$A,"dr"
+ .xword 0x11
+ .section .CRT$Z,"dr"
+ .xword 0x13
+
+#--- crt2-amd64.s
+ .section .CRT$B,"dr"
+ .quad 0x12
diff --git a/lld/test/COFF/arm64x-ctors-sec.s b/lld/test/COFF/arm64x-ctors-sec.s
new file mode 100644
index 0000000000000..283d5f045260d
--- /dev/null
+++ b/lld/test/COFF/arm64x-ctors-sec.s
@@ -0,0 +1,76 @@
+// REQUIRES: aarch64, x86
+// RUN: split-file %s %t.dir && cd %t.dir
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor1-arm64.s -o ctor1-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor2-arm64.s -o ctor2-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ctor1-arm64ec.s -o ctor1-arm64ec.obj
+// RUN: llvm-mc -filetype=obj -triple=x86_64-windows ctor2-amd64.s -o ctor2-amd64.obj
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows test.s -o test-arm64.obj
+// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test-arm64ec.obj
+
+// Check that .ctors and .dtors chunks are correctly sorted and that EC and native chunks are split.
+
+// RUN: lld-link -out:out.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor1-arm64.obj ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out.dll | FileCheck %s
+
+// RUN: lld-link -out:out2.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj ctor2-arm64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out2.dll | FileCheck %s
+
+// RUN: lld-link -out:out3.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
+// RUN: ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj
+// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out3.dll | FileCheck %s
+
+// CHECK: Hex dump of section '.rdata':
+// CHECK-NEXT: 0x180001000 ffffffff ffffffff 01000000 00000000
+// CHECK-NEXT: 0x180001010 02000000 00000000 03000000 00000000
+// CHECK-NEXT: 0x180001020 00000000 00000000 ffffffff ffffffff
+// CHECK-NEXT: 0x180001030 11000000 00000000 12000000 00000000
+// CHECK-NEXT: 0x180001040 13000000 00000000 00000000 00000000
+// CHECK-NEXT: 0x180001050 ffffffff ffffffff 01010000 00000000
+// CHECK-NEXT: 0x180001060 02010000 00000000 03010000 00000000
+// CHECK-NEXT: 0x180001070 00000000 00000000 ffffffff ffffffff
+// CHECK-NEXT: 0x180001080 11010000 00000000 12010000 00000000
+// CHECK-NEXT: 0x180001090 13010000 00000000 00000000 00000000
+// CHECK-EMPTY:
+// CHECK-NEXT: Hex dump of section '.test':
+// CHECK-NEXT: 0x180003000 00100000 50100000 28100000 78100000
+
+#--- ctor1-arm64.s
+ .section .ctors.1,"drw"
+ .xword 1
+ .section .ctors.3,"drw"
+ .xword 3
+ .section .dtors.1,"drw"
+ .xword 0x101
+ .section .dtors.3,"drw"
+ .xword 0x103
+
+#--- ctor2-arm64.s
+ .section .ctors.2,"drw"
+ .xword 2
+ .section .dtors.2,"drw"
+ .xword 0x102
+
+#--- ctor1-arm64ec.s
+ .section .ctors.1,"drw"
+ .xword 0x11
+ .section .ctors.3,"drw"
+ .xword 0x13
+ .section .dtors.1,"drw"
+ .xword 0x111
+ .section .dtors.3,"drw"
+ .xword 0x113
+
+#--- ctor2-amd64.s
+ .section .ctors.2,"drw"
+ .quad 0x12
+ .section .dtors.2,"drw"
+ .quad 0x112
+
+#--- test.s
+ .section .test
+ .rva __CTOR_LIST__
+ .rva __DTOR_LIST__
+
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Split the chunks for EC and native views, inserting headers and tails for both.
…lvm#127205) Split the chunks for EC and native views, inserting headers and tails for both.
…lvm#127205) Split the chunks for EC and native views, inserting headers and tails for both.
…lvm#127205) Split the chunks for EC and native views, inserting headers and tails for both.
…lvm#127205) Split the chunks for EC and native views, inserting headers and tails for both.
…lvm#127205) Split the chunks for EC and native views, inserting headers and tails for both.
Split the chunks for EC and native views, inserting headers and tails for both.