@@ -921,54 +921,89 @@ void DelayLoadContents::create() {
921921 auto *dir = make<DelayDirectoryChunk>(dllNames.back ());
922922
923923 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- thunks.push_back (t);
931- StringRef extName = s->getExternalName ();
932- if (extName.empty ()) {
933- names.push_back (make<OrdinalOnlyChunk>(ctx, s->getOrdinal ()));
934- } else {
935- auto *c = make<HintNameChunk>(extName, 0 );
936- names.push_back (make<LookupChunk>(ctx, c));
937- hintNames.push_back (c);
938- // Add a synthetic symbol for this load thunk, using the "__imp___load"
939- // prefix, in case this thunk needs to be added to the list of valid
940- // call targets for Control Flow Guard.
941- StringRef symName = saver ().save (" __imp___load_" + extName);
942- s->loadThunkSym =
943- 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 ));
944940 }
945941
946- if (s->file ->impECSym ) {
947- auto chunk = make<AuxImportChunk>(s->file );
948- auxIat.push_back (chunk);
949- s->file ->impECSym ->setLocation (chunk);
942+ Chunk *tm = nullptr ;
950943
951- chunk = make<AuxImportChunk>(s->file );
952- auxIatCopy.push_back (chunk);
953- 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+ }
954989 }
955- }
956- thunks.push_back (tm);
957- if (pdataChunk)
958- pdata.push_back (pdataChunk);
959- StringRef tmName =
960- saver ().save (" __tailMerge_" + syms[0 ]->getDLLName ().lower ());
961- ctx.symtab .addSynthetic (tmName, tm);
962- // Terminate with null values.
963- addresses.push_back (make<NullChunk>(ctx, 8 ));
964- names.push_back (make<NullChunk>(ctx, 8 ));
965- if (ctx.config .machine == ARM64EC) {
966- auxIat.push_back (make<NullChunk>(ctx, 8 ));
967- auxIatCopy.push_back (make<NullChunk>(ctx, 8 ));
968- }
969990
970- for (int i = 0 , e = syms.size (); i < e; ++i)
971- syms[i]->setLocation (addresses[base + i]);
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+ });
1006+
9721007 auto *mh = make<NullChunk>(8 , 8 );
9731008 moduleHandles.push_back (mh);
9741009
0 commit comments