@@ -911,67 +911,99 @@ uint64_t DelayLoadContents::getDirSize() {
911911 return dirs.size () * sizeof (delay_import_directory_table_entry);
912912}
913913
914- void DelayLoadContents::create (Defined *h) {
915- helper = h;
914+ void DelayLoadContents::create () {
916915 std::vector<std::vector<DefinedImportData *>> v = binImports (ctx, imports);
917916
918- Chunk *unwind = newTailMergeUnwindInfoChunk ();
919-
920917 // Create .didat contents for each DLL.
921918 for (std::vector<DefinedImportData *> &syms : v) {
922919 // Create the delay import table header.
923920 dllNames.push_back (make<StringChunk>(syms[0 ]->getDLLName ()));
924921 auto *dir = make<DelayDirectoryChunk>(dllNames.back ());
925922
926923 size_t base = addresses.size ();
927- Chunk *tm = newTailMergeChunk (dir);
928- Chunk *pdataChunk = unwind ? newTailMergePDataChunk (tm, unwind) : nullptr ;
929- for (DefinedImportData *s : syms) {
930- Chunk *t = newThunkChunk (s, tm);
931- auto *a = make<DelayAddressChunk>(ctx, t);
932- addresses.push_back (a);
933- thunks.push_back (t);
934- StringRef extName = s->getExternalName ();
935- if (extName.empty ()) {
936- names.push_back (make<OrdinalOnlyChunk>(ctx, s->getOrdinal ()));
937- } else {
938- auto *c = make<HintNameChunk>(extName, 0 );
939- names.push_back (make<LookupChunk>(ctx, c));
940- hintNames.push_back (c);
941- // Add a synthetic symbol for this load thunk, using the "__imp___load"
942- // prefix, in case this thunk needs to be added to the list of valid
943- // call targets for Control Flow Guard.
944- StringRef symName = saver ().save (" __imp___load_" + extName);
945- s->loadThunkSym =
946- 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 ));
947940 }
948941
949- if (s->file ->impECSym ) {
950- auto chunk = make<AuxImportChunk>(s->file );
951- auxIat.push_back (chunk);
952- s->file ->impECSym ->setLocation (chunk);
942+ Chunk *tm = nullptr ;
953943
954- chunk = make<AuxImportChunk>(s->file );
955- auxIatCopy.push_back (chunk);
956- 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+ }
957989 }
958- }
959- thunks.push_back (tm);
960- if (pdataChunk)
961- pdata.push_back (pdataChunk);
962- StringRef tmName =
963- saver ().save (" __tailMerge_" + syms[0 ]->getDLLName ().lower ());
964- ctx.symtab .addSynthetic (tmName, tm);
965- // Terminate with null values.
966- addresses.push_back (make<NullChunk>(ctx, 8 ));
967- names.push_back (make<NullChunk>(ctx, 8 ));
968- if (ctx.config .machine == ARM64EC) {
969- auxIat.push_back (make<NullChunk>(ctx, 8 ));
970- auxIatCopy.push_back (make<NullChunk>(ctx, 8 ));
971- }
972990
973- for (int i = 0 , e = syms.size (); i < e; ++i)
974- 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+
9751007 auto *mh = make<NullChunk>(8 , 8 );
9761008 moduleHandles.push_back (mh);
9771009
@@ -982,15 +1014,18 @@ void DelayLoadContents::create(Defined *h) {
9821014 dirs.push_back (dir);
9831015 }
9841016
985- if (unwind)
986- unwindinfo.push_back (unwind);
1017+ ctx.forEachSymtab ([&](SymbolTable &symtab) {
1018+ if (symtab.tailMergeUnwindInfoChunk )
1019+ unwindinfo.push_back (symtab.tailMergeUnwindInfoChunk );
1020+ });
9871021 // Add null terminator.
9881022 dirs.push_back (
9891023 make<NullChunk>(sizeof (delay_import_directory_table_entry), 4 ));
9901024}
9911025
992- Chunk *DelayLoadContents::newTailMergeChunk (Chunk *dir) {
993- switch (ctx.config .machine ) {
1026+ Chunk *DelayLoadContents::newTailMergeChunk (SymbolTable &symtab, Chunk *dir) {
1027+ auto helper = cast<Defined>(symtab.delayLoadHelper );
1028+ switch (symtab.machine ) {
9941029 case AMD64:
9951030 case ARM64EC:
9961031 return make<TailMergeChunkX64>(dir, helper);
@@ -1005,21 +1040,14 @@ Chunk *DelayLoadContents::newTailMergeChunk(Chunk *dir) {
10051040 }
10061041}
10071042
1008- Chunk *DelayLoadContents::newTailMergeUnwindInfoChunk () {
1009- switch (ctx.config .machine ) {
1010- case AMD64:
1011- case ARM64EC:
1012- return make<TailMergeUnwindInfoX64>();
1013- // FIXME: Add support for other architectures.
1014- default :
1015- return nullptr ; // Just don't generate unwind info.
1016- }
1017- }
1018- Chunk *DelayLoadContents::newTailMergePDataChunk (Chunk *tm, Chunk *unwind) {
1019- switch (ctx.config .machine ) {
1043+ Chunk *DelayLoadContents::newTailMergePDataChunk (SymbolTable &symtab,
1044+ Chunk *tm) {
1045+ switch (symtab.machine ) {
10201046 case AMD64:
10211047 case ARM64EC:
1022- return make<TailMergePDataChunkX64>(tm, unwind);
1048+ if (!symtab.tailMergeUnwindInfoChunk )
1049+ symtab.tailMergeUnwindInfoChunk = make<TailMergeUnwindInfoX64>();
1050+ return make<TailMergePDataChunkX64>(tm, symtab.tailMergeUnwindInfoChunk );
10231051 // FIXME: Add support for other architectures.
10241052 default :
10251053 return nullptr ; // Just don't generate unwind info.
@@ -1028,7 +1056,7 @@ Chunk *DelayLoadContents::newTailMergePDataChunk(Chunk *tm, Chunk *unwind) {
10281056
10291057Chunk *DelayLoadContents::newThunkChunk (DefinedImportData *s,
10301058 Chunk *tailMerge) {
1031- switch (ctx. config . machine ) {
1059+ switch (s-> file -> getMachineType () ) {
10321060 case AMD64:
10331061 case ARM64EC:
10341062 return make<ThunkChunkX64>(s, tailMerge);
0 commit comments