@@ -560,7 +560,8 @@ class TailMergeChunkARM64 : public NonSectionCodeChunk {
560
560
memcpy (buf, tailMergeARM64, sizeof (tailMergeARM64));
561
561
applyArm64Addr (buf + 44 , desc->getRVA (), rva + 44 , 12 );
562
562
applyArm64Imm (buf + 48 , desc->getRVA () & 0xfff , 0 );
563
- applyArm64Branch26 (buf + 52 , helper->getRVA () - rva - 52 );
563
+ if (helper)
564
+ applyArm64Branch26 (buf + 52 , helper->getRVA () - rva - 52 );
564
565
}
565
566
566
567
Chunk *desc = nullptr ;
@@ -781,6 +782,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
781
782
// ordinal values to the table.
782
783
size_t base = lookups.size ();
783
784
Chunk *lookupsTerminator = nullptr , *addressesTerminator = nullptr ;
785
+ uint32_t nativeOnly = 0 ;
784
786
for (DefinedImportData *s : syms) {
785
787
uint16_t ord = s->getOrdinal ();
786
788
HintNameChunk *hintChunk = nullptr ;
@@ -806,8 +808,8 @@ void IdataContents::create(COFFLinkerContext &ctx) {
806
808
// the native terminator, they will be ignored in the native view.
807
809
// In the EC view, they should act as terminators, so emit ZEROFILL
808
810
// relocations overriding them.
809
- if (ctx.hybridSymtab && !lookupsTerminator && s-> file -> isEC () &&
810
- !s->file ->hybridFile ) {
811
+ if (ctx.config . machine == ARM64X && !lookupsTerminator &&
812
+ s-> file -> isEC () && !s->file ->hybridFile ) {
811
813
lookupsTerminator = lookupsChunk;
812
814
addressesTerminator = addressesChunk;
813
815
lookupsChunk = make<NullChunk>(ctx);
@@ -841,6 +843,7 @@ void IdataContents::create(COFFLinkerContext &ctx) {
841
843
// Fill the auxiliary IAT with null chunks for native-only imports.
842
844
auxIat.push_back (make<NullChunk>(ctx));
843
845
auxIatCopy.push_back (make<NullChunk>(ctx));
846
+ ++nativeOnly;
844
847
}
845
848
}
846
849
// Terminate with null values.
@@ -862,18 +865,15 @@ void IdataContents::create(COFFLinkerContext &ctx) {
862
865
// Create the import table header.
863
866
dllNames.push_back (make<StringChunk>(syms[0 ]->getDLLName ()));
864
867
auto *dir = make<ImportDirectoryChunk>(dllNames.back ());
865
- dir->lookupTab = lookups[base];
866
- dir->addressTab = addresses[base];
867
- dirs.push_back (dir);
868
868
869
- if (ctx.hybridSymtab ) {
870
- // If native-only imports exist, they will appear as a prefix to all
871
- // imports. Emit ARM64X relocations to skip them in the EC view.
872
- uint32_t nativeOnly =
873
- llvm::find_if (syms,
874
- [](DefinedImportData *s ) { return s-> file -> isEC (); }) -
875
- syms. begin ();
876
- if (nativeOnly) {
869
+ if (ctx.hybridSymtab && nativeOnly ) {
870
+ if (ctx. config . machine != ARM64X)
871
+ // On pure ARM64EC targets, skip native-only imports in the import
872
+ // directory.
873
+ base += nativeOnly;
874
+ else if (nativeOnly ) {
875
+ // If native-only imports exist, they will appear as a prefix to all
876
+ // imports. Emit ARM64X relocations to skip them in the EC view.
877
877
ctx.dynamicRelocs ->add (
878
878
IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0 ,
879
879
Arm64XRelocVal (
@@ -886,6 +886,10 @@ void IdataContents::create(COFFLinkerContext &ctx) {
886
886
nativeOnly * sizeof (uint64_t ));
887
887
}
888
888
}
889
+
890
+ dir->lookupTab = lookups[base];
891
+ dir->addressTab = addresses[base];
892
+ dirs.push_back (dir);
889
893
}
890
894
// Add null terminator.
891
895
dirs.push_back (make<NullChunk>(sizeof (ImportDirectoryTableEntry), 4 ));
@@ -922,21 +926,25 @@ void DelayLoadContents::create() {
922
926
923
927
size_t base = addresses.size ();
924
928
ctx.forEachSymtab ([&](SymbolTable &symtab) {
925
- if (ctx.hybridSymtab && symtab.isEC ()) {
926
- // For hybrid images, emit null-terminated native import entries
927
- // followed by null-terminated EC entries. If a view is missing imports
928
- // for a given module, only terminators are emitted. Emit ARM64X
929
- // relocations to skip native entries in the EC view.
930
- ctx.dynamicRelocs ->add (
931
- IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0 ,
932
- Arm64XRelocVal (dir, offsetof (delay_import_directory_table_entry,
933
- DelayImportAddressTable)),
934
- (addresses.size () - base) * sizeof (uint64_t ));
935
- ctx.dynamicRelocs ->add (
936
- IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0 ,
937
- Arm64XRelocVal (dir, offsetof (delay_import_directory_table_entry,
938
- DelayImportNameTable)),
939
- (addresses.size () - base) * sizeof (uint64_t ));
929
+ if (symtab.isEC ()) {
930
+ if (ctx.config .machine == ARM64X) {
931
+ // For hybrid images, emit null-terminated native import entries
932
+ // followed by null-terminated EC entries. If a view is missing
933
+ // imports for a given module, only terminators are emitted. Emit
934
+ // ARM64X relocations to skip native entries in the EC view.
935
+ ctx.dynamicRelocs ->add (
936
+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0 ,
937
+ Arm64XRelocVal (dir, offsetof (delay_import_directory_table_entry,
938
+ DelayImportAddressTable)),
939
+ (addresses.size () - base) * sizeof (uint64_t ));
940
+ ctx.dynamicRelocs ->add (
941
+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA, 0 ,
942
+ Arm64XRelocVal (dir, offsetof (delay_import_directory_table_entry,
943
+ DelayImportNameTable)),
944
+ (addresses.size () - base) * sizeof (uint64_t ));
945
+ } else {
946
+ base = addresses.size ();
947
+ }
940
948
}
941
949
942
950
Chunk *tm = nullptr ;
@@ -981,7 +989,7 @@ void DelayLoadContents::create() {
981
989
chunk = make<AuxImportChunk>(s->file );
982
990
auxIatCopy.push_back (chunk);
983
991
s->file ->auxImpCopySym ->setLocation (chunk);
984
- } else if (ctx.hybridSymtab ) {
992
+ } else if (ctx.config . machine == ARM64X ) {
985
993
// Fill the auxiliary IAT with null chunks for native imports.
986
994
auxIat.push_back (make<NullChunk>(ctx));
987
995
auxIatCopy.push_back (make<NullChunk>(ctx));
@@ -995,6 +1003,10 @@ void DelayLoadContents::create() {
995
1003
symtab.addSynthetic (tmName, tm);
996
1004
}
997
1005
1006
+ // Skip terminators on pure ARM64EC target if there are no native imports.
1007
+ if (!tm && !symtab.isEC () && ctx.config .machine != ARM64X)
1008
+ return ;
1009
+
998
1010
// Terminate with null values.
999
1011
addresses.push_back (make<NullChunk>(ctx, 8 ));
1000
1012
names.push_back (make<NullChunk>(ctx, 8 ));
@@ -1024,7 +1036,7 @@ void DelayLoadContents::create() {
1024
1036
}
1025
1037
1026
1038
Chunk *DelayLoadContents::newTailMergeChunk (SymbolTable &symtab, Chunk *dir) {
1027
- auto helper = cast <Defined>(symtab.delayLoadHelper );
1039
+ auto helper = cast_or_null <Defined>(symtab.delayLoadHelper );
1028
1040
switch (symtab.machine ) {
1029
1041
case AMD64:
1030
1042
case ARM64EC:
0 commit comments