Skip to content

Commit 1121037

Browse files
committed
[LLD][COFF] Introduce hybrid symbol table for EC input files on ARM64X
On hybrid ARM64X targets, ARM64 and ARM64EC input files operate in separate namespaces and cannot reference each other. This change introduces separate SymbolTable instances and associates each InputFile with the appropriate table to reflect this behavior.
1 parent d3c4857 commit 1121037

File tree

10 files changed

+150
-68
lines changed

10 files changed

+150
-68
lines changed

lld/COFF/COFFLinkerContext.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ class COFFLinkerContext : public CommonLinkerContext {
3232
SymbolTable symtab;
3333
COFFOptTable optTable;
3434

35+
// A hybrid ARM64EC symbol table on ARM64X target.
36+
std::optional<SymbolTable> hybridSymtab;
37+
38+
// Pointer to the ARM64EC symbol table: either symtab for an ARM64EC target or
39+
// hybridSymtab for an ARM64X target.
40+
SymbolTable *symtabEC = nullptr;
41+
42+
// Returns the appropriate symbol table for the specified machine type.
43+
SymbolTable &getSymtab(llvm::COFF::MachineTypes machine) {
44+
if (hybridSymtab && (machine == ARM64EC || machine == AMD64))
45+
return *hybridSymtab;
46+
return symtab;
47+
}
48+
49+
// Invoke the specified callback for each symbol table.
50+
void forEachSymtab(std::function<void(SymbolTable &symtab)> f) {
51+
f(symtab);
52+
if (hybridSymtab)
53+
f(*hybridSymtab);
54+
}
55+
3556
std::vector<ObjFile *> objFileInstances;
3657
std::map<std::string, PDBInputFile *> pdbInputFileInstances;
3758
std::vector<ImportFile *> importFileInstances;

lld/COFF/Driver.cpp

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,17 @@ void LinkerDriver::setMachine(MachineTypes machine) {
596596
assert(machine != IMAGE_FILE_MACHINE_UNKNOWN);
597597

598598
ctx.config.machine = machine;
599-
ctx.symtab.machine = machine;
599+
600+
if (machine != ARM64X) {
601+
ctx.symtab.machine = machine;
602+
if (machine == ARM64EC)
603+
ctx.symtabEC = &ctx.symtab;
604+
} else {
605+
ctx.symtab.machine = ARM64;
606+
ctx.hybridSymtab.emplace(ctx, ARM64EC);
607+
ctx.symtabEC = &*ctx.hybridSymtab;
608+
}
609+
600610
addWinSysRootLibSearchPaths();
601611
}
602612

@@ -2519,54 +2529,56 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
25192529
if (config->imageBase == uint64_t(-1))
25202530
config->imageBase = getDefaultImageBase();
25212531

2522-
ctx.symtab.addSynthetic(mangle("__ImageBase"), nullptr);
2523-
if (config->machine == I386) {
2524-
ctx.symtab.addAbsolute("___safe_se_handler_table", 0);
2525-
ctx.symtab.addAbsolute("___safe_se_handler_count", 0);
2526-
}
2527-
2528-
ctx.symtab.addAbsolute(mangle("__guard_fids_count"), 0);
2529-
ctx.symtab.addAbsolute(mangle("__guard_fids_table"), 0);
2530-
ctx.symtab.addAbsolute(mangle("__guard_flags"), 0);
2531-
ctx.symtab.addAbsolute(mangle("__guard_iat_count"), 0);
2532-
ctx.symtab.addAbsolute(mangle("__guard_iat_table"), 0);
2533-
ctx.symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
2534-
ctx.symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
2535-
// Needed for MSVC 2017 15.5 CRT.
2536-
ctx.symtab.addAbsolute(mangle("__enclave_config"), 0);
2537-
// Needed for MSVC 2019 16.8 CRT.
2538-
ctx.symtab.addAbsolute(mangle("__guard_eh_cont_count"), 0);
2539-
ctx.symtab.addAbsolute(mangle("__guard_eh_cont_table"), 0);
2540-
2541-
if (isArm64EC(config->machine)) {
2542-
ctx.symtab.addAbsolute("__arm64x_extra_rfe_table", 0);
2543-
ctx.symtab.addAbsolute("__arm64x_extra_rfe_table_size", 0);
2544-
ctx.symtab.addAbsolute("__arm64x_redirection_metadata", 0);
2545-
ctx.symtab.addAbsolute("__arm64x_redirection_metadata_count", 0);
2546-
ctx.symtab.addAbsolute("__hybrid_auxiliary_delayload_iat_copy", 0);
2547-
ctx.symtab.addAbsolute("__hybrid_auxiliary_delayload_iat", 0);
2548-
ctx.symtab.addAbsolute("__hybrid_auxiliary_iat", 0);
2549-
ctx.symtab.addAbsolute("__hybrid_auxiliary_iat_copy", 0);
2550-
ctx.symtab.addAbsolute("__hybrid_code_map", 0);
2551-
ctx.symtab.addAbsolute("__hybrid_code_map_count", 0);
2552-
ctx.symtab.addAbsolute("__hybrid_image_info_bitfield", 0);
2553-
ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points", 0);
2554-
ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points_count", 0);
2555-
ctx.symtab.addSynthetic("__guard_check_icall_a64n_fptr", nullptr);
2556-
ctx.symtab.addSynthetic("__arm64x_native_entrypoint", nullptr);
2557-
}
2558-
2559-
if (config->pseudoRelocs) {
2560-
ctx.symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
2561-
ctx.symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
2562-
}
2563-
if (config->mingw) {
2564-
ctx.symtab.addAbsolute(mangle("__CTOR_LIST__"), 0);
2565-
ctx.symtab.addAbsolute(mangle("__DTOR_LIST__"), 0);
2566-
}
2567-
if (config->debug || config->buildIDHash != BuildIDHash::None)
2568-
if (ctx.symtab.findUnderscore("__buildid"))
2569-
ctx.symtab.addUndefined(mangle("__buildid"));
2532+
ctx.forEachSymtab([&](SymbolTable &symtab) {
2533+
symtab.addSynthetic(mangle("__ImageBase"), nullptr);
2534+
if (symtab.machine == I386) {
2535+
symtab.addAbsolute("___safe_se_handler_table", 0);
2536+
symtab.addAbsolute("___safe_se_handler_count", 0);
2537+
}
2538+
2539+
symtab.addAbsolute(mangle("__guard_fids_count"), 0);
2540+
symtab.addAbsolute(mangle("__guard_fids_table"), 0);
2541+
symtab.addAbsolute(mangle("__guard_flags"), 0);
2542+
symtab.addAbsolute(mangle("__guard_iat_count"), 0);
2543+
symtab.addAbsolute(mangle("__guard_iat_table"), 0);
2544+
symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
2545+
symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
2546+
// Needed for MSVC 2017 15.5 CRT.
2547+
symtab.addAbsolute(mangle("__enclave_config"), 0);
2548+
// Needed for MSVC 2019 16.8 CRT.
2549+
symtab.addAbsolute(mangle("__guard_eh_cont_count"), 0);
2550+
symtab.addAbsolute(mangle("__guard_eh_cont_table"), 0);
2551+
2552+
if (isArm64EC(ctx.config.machine)) {
2553+
symtab.addAbsolute("__arm64x_extra_rfe_table", 0);
2554+
symtab.addAbsolute("__arm64x_extra_rfe_table_size", 0);
2555+
symtab.addAbsolute("__arm64x_redirection_metadata", 0);
2556+
symtab.addAbsolute("__arm64x_redirection_metadata_count", 0);
2557+
symtab.addAbsolute("__hybrid_auxiliary_delayload_iat_copy", 0);
2558+
symtab.addAbsolute("__hybrid_auxiliary_delayload_iat", 0);
2559+
symtab.addAbsolute("__hybrid_auxiliary_iat", 0);
2560+
symtab.addAbsolute("__hybrid_auxiliary_iat_copy", 0);
2561+
symtab.addAbsolute("__hybrid_code_map", 0);
2562+
symtab.addAbsolute("__hybrid_code_map_count", 0);
2563+
symtab.addAbsolute("__hybrid_image_info_bitfield", 0);
2564+
symtab.addAbsolute("__x64_code_ranges_to_entry_points", 0);
2565+
symtab.addAbsolute("__x64_code_ranges_to_entry_points_count", 0);
2566+
symtab.addSynthetic("__guard_check_icall_a64n_fptr", nullptr);
2567+
symtab.addSynthetic("__arm64x_native_entrypoint", nullptr);
2568+
}
2569+
2570+
if (config->pseudoRelocs) {
2571+
symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST__"), 0);
2572+
symtab.addAbsolute(mangle("__RUNTIME_PSEUDO_RELOC_LIST_END__"), 0);
2573+
}
2574+
if (config->mingw) {
2575+
symtab.addAbsolute(mangle("__CTOR_LIST__"), 0);
2576+
symtab.addAbsolute(mangle("__DTOR_LIST__"), 0);
2577+
}
2578+
if (config->debug || config->buildIDHash != BuildIDHash::None)
2579+
if (symtab.findUnderscore("__buildid"))
2580+
symtab.addUndefined(mangle("__buildid"));
2581+
});
25702582

25712583
// This code may add new undefined symbols to the link, which may enqueue more
25722584
// symbol resolution tasks, so we need to continue executing tasks until we
@@ -2809,7 +2821,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
28092821
if (auto *arg = args.getLastArg(OPT_print_symbol_order))
28102822
config->printSymbolOrder = arg->getValue();
28112823

2812-
ctx.symtab.initializeECThunks();
2824+
if (ctx.symtabEC)
2825+
ctx.symtabEC->initializeECThunks();
28132826

28142827
// Identify unreferenced COMDAT sections.
28152828
if (config->doGC) {

lld/COFF/InputFiles.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ void ArchiveFile::parse() {
114114
file = CHECK(Archive::create(mb), this);
115115

116116
// Try to read symbols from ECSYMBOLS section on ARM64EC.
117-
if (isArm64EC(ctx.config.machine)) {
117+
if (ctx.symtabEC) {
118118
iterator_range<Archive::symbol_iterator> symbols =
119119
CHECK(file->ec_symbols(), this);
120120
if (!symbols.empty()) {
121121
for (const Archive::Symbol &sym : symbols)
122-
ctx.symtab.addLazyArchive(this, sym);
122+
ctx.symtabEC->addLazyArchive(this, sym);
123123

124124
// Read both EC and native symbols on ARM64X.
125-
if (ctx.config.machine != ARM64X)
125+
if (!ctx.hybridSymtab)
126126
return;
127127
}
128128
}
@@ -163,7 +163,7 @@ lld::coff::getArchiveMembers(COFFLinkerContext &ctx, Archive *file) {
163163
}
164164

165165
ObjFile::ObjFile(COFFLinkerContext &ctx, MemoryBufferRef m, bool lazy)
166-
: InputFile(ctx.symtab, ObjectKind, m, lazy) {}
166+
: InputFile(ctx.getSymtab(getMachineType(m)), ObjectKind, m, lazy) {}
167167

168168
void ObjFile::parseLazy() {
169169
// Native object file.
@@ -806,10 +806,12 @@ std::optional<Symbol *> ObjFile::createDefined(
806806
return createRegular(sym);
807807
}
808808

809-
MachineTypes ObjFile::getMachineType() const {
810-
if (coffObj)
811-
return static_cast<MachineTypes>(coffObj->getMachine());
812-
return IMAGE_FILE_MACHINE_UNKNOWN;
809+
MachineTypes ObjFile::getMachineType(MemoryBufferRef mb) {
810+
// Extract the machine type directly from the COFF header, as it's the first
811+
// 16-bit field.
812+
uint16_t machine =
813+
*reinterpret_cast<const ulittle16_t *>(mb.getBufferStart());
814+
return MachineTypes(machine);
813815
}
814816

815817
ArrayRef<uint8_t> ObjFile::getDebugSection(StringRef secName) {

lld/COFF/InputFiles.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ class ObjFile : public InputFile {
141141
static bool classof(const InputFile *f) { return f->kind() == ObjectKind; }
142142
void parse() override;
143143
void parseLazy();
144-
MachineTypes getMachineType() const override;
144+
MachineTypes getMachineType() const override { return getMachineType(mb); }
145+
static MachineTypes getMachineType(MemoryBufferRef mb);
145146
ArrayRef<Chunk *> getChunks() { return chunks; }
146147
ArrayRef<SectionChunk *> getDebugChunks() { return debugChunks; }
147148
ArrayRef<SectionChunk *> getSXDataChunks() { return sxDataChunks; }

lld/COFF/SymbolTable.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class Symbol;
4747
// There is one add* function per symbol type.
4848
class SymbolTable {
4949
public:
50-
SymbolTable(COFFLinkerContext &c) : ctx(c) {}
50+
SymbolTable(COFFLinkerContext &c,
51+
llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN)
52+
: ctx(c), machine(machine) {}
5153

5254
void addFile(InputFile *file);
5355

@@ -120,7 +122,7 @@ class SymbolTable {
120122
uint32_t newSectionOffset = 0);
121123

122124
COFFLinkerContext &ctx;
123-
llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
125+
llvm::COFF::MachineTypes machine;
124126

125127
bool isEC() const { return machine == ARM64EC; }
126128

lld/test/COFF/arm64ec-codemap.test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ RUN: llvm-mc -filetype=obj -triple=arm64ec-windows data-sec2.s -o data-sec2.obj
99
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows empty-sec.s -o arm64ec-empty-sec.obj
1010
RUN: llvm-mc -filetype=obj -triple=x86_64-windows x86_64-func-sym.s -o x86_64-func-sym.obj
1111
RUN: llvm-mc -filetype=obj -triple=x86_64-windows empty-sec.s -o x86_64-empty-sec.obj
12+
RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64.obj
1213
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
1314

1415
Link ARM64EC DLL and verify that the code is arranged as expected.
@@ -51,7 +52,7 @@ RUN: llvm-readobj --coff-load-config test2.dll | FileCheck -check-prefix=CODEMAP
5152
RUN: llvm-objdump -d test2.dll | FileCheck -check-prefix=DISASM %s
5253

5354
RUN: lld-link -out:testx.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \
54-
RUN: x86_64-func-sym.obj loadconfig-arm64ec.obj -dll -noentry
55+
RUN: x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
5556

5657
Adding empty chunks does not affect code map ranges.
5758

lld/test/COFF/arm64ec-entry-thunk.s

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ thunk:
2727
.rva func
2828

2929
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadcfg.obj
30+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64ec.s -o native-loadcfg.obj
3031
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows test-simple.s -o test-simple.obj
3132
// RUN: lld-link -machine:arm64ec -dll -noentry -out:out-simple.dll loadcfg.obj test-simple.obj
3233
// RUN: llvm-objdump -d out-simple.dll | FileCheck --check-prefix=DISASM %s
@@ -43,7 +44,7 @@ thunk:
4344
// RUN: llvm-readobj --sections out-simple.dll | FileCheck --check-prefix=HYBMP %s
4445
// HYBMP-NOT: .hybmp
4546

46-
// RUN: lld-link -machine:arm64x -dll -noentry -out:out-simplex.dll loadcfg.obj test-simple.obj
47+
// RUN: lld-link -machine:arm64x -dll -noentry -out:out-simplex.dll native-loadcfg.obj loadcfg.obj test-simple.obj
4748
// RUN: llvm-objdump -d out-simplex.dll | FileCheck --check-prefix=DISASM %s
4849

4950
#--- test-split-func.s

lld/test/COFF/arm64ec-lib.test

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ref-alias.s -o ref-alias.obj
1111
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows ref-thunk.s -o ref-thunk.obj
1212
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows func.s -o func.obj
1313
RUN: llvm-mc -filetype=obj -triple=x86_64-windows func-x86_64.s -o func-x86_64.obj
14+
RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64.obj
1415
RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
1516

1617
RUN: llvm-lib -machine:arm64ec -out:sym-arm64ec.lib sym-arm64ec.obj nsym-aarch64.obj
@@ -26,7 +27,8 @@ Verify that a symbol can be referenced from a regular archive map when ECSYMBOLS
2627
RUN: lld-link -machine:arm64ec -dll -noentry -out:test2.dll symref-arm64ec.obj sym-x86_64.lib loadconfig-arm64ec.obj
2728

2829
Verify that both native and EC symbols can be referenced in a hybrid target.
29-
RUN: lld-link -machine:arm64x -dll -noentry -out:test3.dll symref-arm64ec.obj nsymref-aarch64.obj sym-arm64ec.lib loadconfig-arm64ec.obj
30+
RUN: lld-link -machine:arm64x -dll -noentry -out:test3.dll symref-arm64ec.obj nsymref-aarch64.obj sym-arm64ec.lib \
31+
RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj
3032

3133
Ensure that an EC symbol is not resolved using a regular symbol map.
3234
RUN: not lld-link -machine:arm64ec -dll -noentry -out:test-err.dll nsymref-arm64ec.obj sym-arm64ec.lib loadconfig-arm64ec.obj 2>&1 |\

lld/test/COFF/arm64ec-range-thunks.s

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# RUN: llvm-mc -filetype=obj -triple=aarch64-windows native-funcs.s -o funcs-aarch64.obj
66
# RUN: llvm-mc -filetype=obj -triple=x86_64-windows space.s -o space-x86_64.obj
77
# RUN: llvm-mc -filetype=obj -triple=aarch64-windows space.s -o space-aarch64.obj
8+
# RUN: llvm-mc -filetype=obj -triple=aarch64-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64.obj
89
# RUN: llvm-mc -filetype=obj -triple=arm64ec-windows %S/Inputs/loadconfig-arm64ec.s -o loadconfig-arm64ec.obj
910

1011

@@ -59,8 +60,8 @@
5960

6061
# A similar test using a hybrid binary and native placeholder chunks.
6162

62-
# RUN: lld-link -machine:arm64x -noentry -dll funcs-arm64ec.obj space-aarch64.obj loadconfig-arm64ec.obj -out:testx.dll \
63-
# RUN: -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
63+
# RUN: lld-link -machine:arm64x -noentry -dll funcs-arm64ec.obj space-aarch64.obj loadconfig-arm64.obj loadconfig-arm64ec.obj \
64+
# RUN: -out:testx.dll -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
6465
# RUN: llvm-objdump -d testx.dll | FileCheck --check-prefix=DISASM %s
6566

6667
# RUN: llvm-readobj --coff-load-config testx.dll | FileCheck --check-prefix=LOADCFGX %s
@@ -74,8 +75,8 @@
7475

7576
# Test a hybrid ARM64X binary which requires range extension thunks for both native and EC relocations.
7677

77-
# RUN: lld-link -machine:arm64x -noentry -dll funcs-arm64ec.obj funcs-aarch64.obj loadconfig-arm64ec.obj -out:testx2.dll \
78-
# RUN: -verbose 2>&1 | FileCheck -check-prefix=VERBOSEX %s
78+
# RUN: lld-link -machine:arm64x -noentry -dll funcs-arm64ec.obj funcs-aarch64.obj loadconfig-arm64.obj loadconfig-arm64ec.obj \
79+
# RUN: -out:testx2.dll -verbose 2>&1 | FileCheck -check-prefix=VERBOSEX %s
7980
# VERBOSEX: Added 5 thunks with margin {{.*}} in 1 passes
8081

8182
# RUN: llvm-objdump -d testx2.dll | FileCheck --check-prefix=DISASMX %s

lld/test/COFF/arm64x-symtab.s

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// REQUIRES: aarch64, x86
2+
// RUN: split-file %s %t.dir && cd %t.dir
3+
4+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows sym.s -o sym-aarch64.obj
5+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows sym.s -o sym-arm64ec.obj
6+
// RUN: llvm-mc -filetype=obj -triple=x86_64-windows sym.s -o sym-x86_64.obj
7+
// RUN: llvm-mc -filetype=obj -triple=aarch64-windows symref.s -o symref-aarch64.obj
8+
// RUN: llvm-mc -filetype=obj -triple=arm64ec-windows symref.s -o symref-arm64ec.obj
9+
// RUN: llvm-lib -machine:arm64x -out:sym.lib sym-aarch64.obj sym-arm64ec.obj
10+
11+
// Check that native object files can't reference EC symbols.
12+
13+
// RUN: not lld-link -machine:arm64x -dll -noentry -out:err1.dll symref-aarch64.obj sym-arm64ec.obj \
14+
// RUN: 2>&1 | FileCheck --check-prefix=UNDEF %s
15+
// UNDEF: lld-link: error: undefined symbol: sym
16+
// UNDEF-NEXT: >>> referenced by symref-aarch64.obj:(.data)
17+
18+
// RUN: not lld-link -machine:arm64x -dll -noentry -out:err2.dll symref-aarch64.obj sym-x86_64.obj \
19+
// RUN: 2>&1 | FileCheck --check-prefix=UNDEF %s
20+
21+
// Check that ARM64X target can have the same symbol names in both native and EC namespaces.
22+
23+
// RUN: lld-link -machine:arm64x -dll -noentry -out:out.dll symref-aarch64.obj sym-aarch64.obj \
24+
// RUN: symref-arm64ec.obj sym-x86_64.obj
25+
26+
// Check that ARM64X target can reference both native and EC symbols from an archive.
27+
28+
// RUN: lld-link -machine:arm64x -dll -noentry -out:out2.dll symref-aarch64.obj symref-arm64ec.obj sym.lib
29+
30+
#--- symref.s
31+
.data
32+
.rva sym
33+
34+
#--- sym.s
35+
.data
36+
.globl sym
37+
sym:
38+
.word 0

0 commit comments

Comments
 (0)