@@ -921,52 +921,88 @@ void DelayLoadContents::create() {
921
921
auto *dir = make<DelayDirectoryChunk>(dllNames.back ());
922
922
923
923
size_t base = addresses.size ();
924
- Chunk *tm = newTailMergeChunk (ctx.symtab , dir);
925
- Chunk *pdataChunk = newTailMergePDataChunk (ctx.symtab , tm );
926
- for (DefinedImportData *s : syms) {
927
- Chunk *t = newThunkChunk (s, tm );
928
- auto *a = make<DelayAddressChunk>(ctx, t);
929
- addresses.push_back (a);
930
- s->setLocation (a);
931
- thunks.push_back (t);
932
- StringRef extName = s->getExternalName ();
933
- if (extName.empty ()) {
934
- names.push_back (make<OrdinalOnlyChunk>(ctx, s->getOrdinal ()));
935
- } else {
936
- auto *c = make<HintNameChunk>(extName, 0 );
937
- names.push_back (make<LookupChunk>(ctx, c));
938
- hintNames.push_back (c);
939
- // Add a synthetic symbol for this load thunk, using the "__imp___load"
940
- // prefix, in case this thunk needs to be added to the list of valid
941
- // call targets for Control Flow Guard.
942
- StringRef symName = saver ().save (" __imp___load_" + extName);
943
- s->loadThunkSym =
944
- cast<DefinedSynthetic>(ctx.symtab .addSynthetic (symName, t));
924
+ 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 ));
945
940
}
946
941
947
- if (s->file ->impECSym ) {
948
- auto chunk = make<AuxImportChunk>(s->file );
949
- auxIat.push_back (chunk);
950
- s->file ->impECSym ->setLocation (chunk);
942
+ Chunk *tm = nullptr ;
951
943
952
- chunk = make<AuxImportChunk>(s->file );
953
- auxIatCopy.push_back (chunk);
954
- s->file ->auxImpCopySym ->setLocation (chunk);
944
+ for (DefinedImportData *s : syms) {
945
+ // Process only the symbols belonging to the current symtab.
946
+ if (symtab.isEC () != s->file ->isEC ())
947
+ continue ;
948
+
949
+ if (!tm ) {
950
+ tm = newTailMergeChunk (symtab, dir);
951
+ Chunk *pdataChunk = newTailMergePDataChunk (symtab, tm );
952
+ if (pdataChunk)
953
+ pdata.push_back (pdataChunk);
954
+ }
955
+
956
+ Chunk *t = newThunkChunk (s, tm );
957
+ auto *a = make<DelayAddressChunk>(ctx, t);
958
+ addresses.push_back (a);
959
+ s->setLocation (a);
960
+ thunks.push_back (t);
961
+ StringRef extName = s->getExternalName ();
962
+ if (extName.empty ()) {
963
+ names.push_back (make<OrdinalOnlyChunk>(ctx, s->getOrdinal ()));
964
+ } else {
965
+ auto *c = make<HintNameChunk>(extName, 0 );
966
+ names.push_back (make<LookupChunk>(ctx, c));
967
+ hintNames.push_back (c);
968
+ // Add a synthetic symbol for this load thunk, using the
969
+ // "__imp___load" prefix, in case this thunk needs to be added to the
970
+ // list of valid call targets for Control Flow Guard.
971
+ StringRef symName = saver ().save (" __imp___load_" + extName);
972
+ s->loadThunkSym =
973
+ cast<DefinedSynthetic>(symtab.addSynthetic (symName, t));
974
+ }
975
+
976
+ if (symtab.isEC ()) {
977
+ auto chunk = make<AuxImportChunk>(s->file );
978
+ auxIat.push_back (chunk);
979
+ s->file ->impECSym ->setLocation (chunk);
980
+
981
+ chunk = make<AuxImportChunk>(s->file );
982
+ auxIatCopy.push_back (chunk);
983
+ s->file ->auxImpCopySym ->setLocation (chunk);
984
+ } else if (ctx.hybridSymtab ) {
985
+ // Fill the auxiliary IAT with null chunks for native imports.
986
+ auxIat.push_back (make<NullChunk>(ctx));
987
+ auxIatCopy.push_back (make<NullChunk>(ctx));
988
+ }
955
989
}
956
- }
957
- thunks.push_back (tm );
958
- if (pdataChunk)
959
- pdata.push_back (pdataChunk);
960
- StringRef tmName =
961
- saver ().save (" __tailMerge_" + syms[0 ]->getDLLName ().lower ());
962
- ctx.symtab .addSynthetic (tmName, tm );
963
- // Terminate with null values.
964
- addresses.push_back (make<NullChunk>(ctx, 8 ));
965
- names.push_back (make<NullChunk>(ctx, 8 ));
966
- if (ctx.config .machine == ARM64EC) {
967
- auxIat.push_back (make<NullChunk>(ctx, 8 ));
968
- auxIatCopy.push_back (make<NullChunk>(ctx, 8 ));
969
- }
990
+
991
+ if (tm ) {
992
+ thunks.push_back (tm );
993
+ StringRef tmName =
994
+ saver ().save (" __tailMerge_" + syms[0 ]->getDLLName ().lower ());
995
+ symtab.addSynthetic (tmName, tm );
996
+ }
997
+
998
+ // Terminate with null values.
999
+ addresses.push_back (make<NullChunk>(ctx, 8 ));
1000
+ names.push_back (make<NullChunk>(ctx, 8 ));
1001
+ if (ctx.symtabEC ) {
1002
+ auxIat.push_back (make<NullChunk>(ctx, 8 ));
1003
+ auxIatCopy.push_back (make<NullChunk>(ctx, 8 ));
1004
+ }
1005
+ });
970
1006
971
1007
auto *mh = make<NullChunk>(8 , 8 );
972
1008
moduleHandles.push_back (mh);
0 commit comments