Skip to content

Commit a92bfaa

Browse files
authored
[LLD][COFF] Support MinGW constructor and destructor lists on ARM64X (#127205)
Split the chunks for EC and native views, inserting headers and tails for both.
1 parent a8b177a commit a92bfaa

File tree

4 files changed

+108
-20
lines changed

4 files changed

+108
-20
lines changed

lld/COFF/Chunks.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -1070,16 +1070,20 @@ void MergeChunk::writeTo(uint8_t *buf) const {
10701070
}
10711071

10721072
// MinGW specific.
1073-
size_t AbsolutePointerChunk::getSize() const { return ctx.config.wordsize; }
1073+
size_t AbsolutePointerChunk::getSize() const {
1074+
return symtab.ctx.config.wordsize;
1075+
}
10741076

10751077
void AbsolutePointerChunk::writeTo(uint8_t *buf) const {
1076-
if (ctx.config.is64()) {
1078+
if (symtab.ctx.config.is64()) {
10771079
write64le(buf, value);
10781080
} else {
10791081
write32le(buf, value);
10801082
}
10811083
}
10821084

1085+
MachineTypes AbsolutePointerChunk::getMachine() const { return symtab.machine; }
1086+
10831087
void ECExportThunkChunk::writeTo(uint8_t *buf) const {
10841088
memcpy(buf, ECExportThunkCode, sizeof(ECExportThunkCode));
10851089
write32le(buf + 10, target->getRVA() - rva - 14);

lld/COFF/Chunks.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -910,16 +910,17 @@ class PseudoRelocTableChunk : public NonSectionChunk {
910910
// MinGW specific. A Chunk that contains one pointer-sized absolute value.
911911
class AbsolutePointerChunk : public NonSectionChunk {
912912
public:
913-
AbsolutePointerChunk(COFFLinkerContext &ctx, uint64_t value)
914-
: value(value), ctx(ctx) {
913+
AbsolutePointerChunk(SymbolTable &symtab, uint64_t value)
914+
: value(value), symtab(symtab) {
915915
setAlignment(getSize());
916916
}
917917
size_t getSize() const override;
918918
void writeTo(uint8_t *buf) const override;
919+
MachineTypes getMachine() const override;
919920

920921
private:
921922
uint64_t value;
922-
COFFLinkerContext &ctx;
923+
SymbolTable &symtab;
923924
};
924925

925926
// Return true if this file has the hotpatch flag set to true in the S_COMPILE3

lld/COFF/Writer.cpp

+22-15
Original file line numberDiff line numberDiff line change
@@ -2335,21 +2335,28 @@ void Writer::createRuntimePseudoRelocs() {
23352335
// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
23362336
// and __DTOR_LIST__ respectively.
23372337
void Writer::insertCtorDtorSymbols() {
2338-
AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(ctx, -1);
2339-
AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(ctx, 0);
2340-
AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(ctx, -1);
2341-
AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(ctx, 0);
2342-
ctorsSec->insertChunkAtStart(ctorListHead);
2343-
ctorsSec->addChunk(ctorListEnd);
2344-
dtorsSec->insertChunkAtStart(dtorListHead);
2345-
dtorsSec->addChunk(dtorListEnd);
2346-
2347-
Symbol *ctorListSym = ctx.symtab.findUnderscore("__CTOR_LIST__");
2348-
Symbol *dtorListSym = ctx.symtab.findUnderscore("__DTOR_LIST__");
2349-
replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
2350-
ctorListHead);
2351-
replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
2352-
dtorListHead);
2338+
ctx.forEachSymtab([&](SymbolTable &symtab) {
2339+
AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(symtab, -1);
2340+
AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(symtab, 0);
2341+
AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(symtab, -1);
2342+
AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(symtab, 0);
2343+
ctorsSec->insertChunkAtStart(ctorListHead);
2344+
ctorsSec->addChunk(ctorListEnd);
2345+
dtorsSec->insertChunkAtStart(dtorListHead);
2346+
dtorsSec->addChunk(dtorListEnd);
2347+
2348+
Symbol *ctorListSym = symtab.findUnderscore("__CTOR_LIST__");
2349+
Symbol *dtorListSym = symtab.findUnderscore("__DTOR_LIST__");
2350+
replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
2351+
ctorListHead);
2352+
replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
2353+
dtorListHead);
2354+
});
2355+
2356+
if (ctx.hybridSymtab) {
2357+
ctorsSec->splitECChunks();
2358+
dtorsSec->splitECChunks();
2359+
}
23532360
}
23542361

23552362
// Handles /section options to allow users to overwrite

lld/test/COFF/arm64x-ctors-sec.s

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// REQUIRES: aarch64, x86
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor1-arm64.s -o ctor1-arm64.obj
5+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows ctor2-arm64.s -o ctor2-arm64.obj
6+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ctor1-arm64ec.s -o ctor1-arm64ec.obj
7+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows ctor2-amd64.s -o ctor2-amd64.obj
8+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows test.s -o test-arm64.obj
9+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test.s -o test-arm64ec.obj
10+
11+
// Check that .ctors and .dtors chunks are correctly sorted and that EC and native chunks are split.
12+
13+
// RUN: lld-link -out:out.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
14+
// RUN: ctor1-arm64.obj ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj
15+
// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out.dll | FileCheck %s
16+
17+
// RUN: lld-link -out:out2.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
18+
// RUN: ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj ctor2-arm64.obj
19+
// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out2.dll | FileCheck %s
20+
21+
// RUN: lld-link -out:out3.dll -machine:arm64x -lldmingw -dll -noentry test-arm64.obj test-arm64ec.obj \
22+
// RUN: ctor2-arm64.obj ctor1-arm64ec.obj ctor2-amd64.obj ctor1-arm64.obj
23+
// RUN: llvm-readobj --hex-dump=.rdata --hex-dump=.test out3.dll | FileCheck %s
24+
25+
// CHECK: Hex dump of section '.rdata':
26+
// CHECK-NEXT: 0x180001000 ffffffff ffffffff 01000000 00000000
27+
// CHECK-NEXT: 0x180001010 02000000 00000000 03000000 00000000
28+
// CHECK-NEXT: 0x180001020 00000000 00000000 ffffffff ffffffff
29+
// CHECK-NEXT: 0x180001030 11000000 00000000 12000000 00000000
30+
// CHECK-NEXT: 0x180001040 13000000 00000000 00000000 00000000
31+
// CHECK-NEXT: 0x180001050 ffffffff ffffffff 01010000 00000000
32+
// CHECK-NEXT: 0x180001060 02010000 00000000 03010000 00000000
33+
// CHECK-NEXT: 0x180001070 00000000 00000000 ffffffff ffffffff
34+
// CHECK-NEXT: 0x180001080 11010000 00000000 12010000 00000000
35+
// CHECK-NEXT: 0x180001090 13010000 00000000 00000000 00000000
36+
// CHECK-EMPTY:
37+
// CHECK-NEXT: Hex dump of section '.test':
38+
// CHECK-NEXT: 0x180003000 00100000 50100000 28100000 78100000
39+
40+
#--- ctor1-arm64.s
41+
.section .ctors.1,"drw"
42+
.xword 1
43+
.section .ctors.3,"drw"
44+
.xword 3
45+
.section .dtors.1,"drw"
46+
.xword 0x101
47+
.section .dtors.3,"drw"
48+
.xword 0x103
49+
50+
#--- ctor2-arm64.s
51+
.section .ctors.2,"drw"
52+
.xword 2
53+
.section .dtors.2,"drw"
54+
.xword 0x102
55+
56+
#--- ctor1-arm64ec.s
57+
.section .ctors.1,"drw"
58+
.xword 0x11
59+
.section .ctors.3,"drw"
60+
.xword 0x13
61+
.section .dtors.1,"drw"
62+
.xword 0x111
63+
.section .dtors.3,"drw"
64+
.xword 0x113
65+
66+
#--- ctor2-amd64.s
67+
.section .ctors.2,"drw"
68+
.quad 0x12
69+
.section .dtors.2,"drw"
70+
.quad 0x112
71+
72+
#--- test.s
73+
.section .test
74+
.rva __CTOR_LIST__
75+
.rva __DTOR_LIST__
76+

0 commit comments

Comments
 (0)