@@ -343,6 +343,9 @@ class Writer {
343343 // x86_64 .pdata sections on ARM64EC/ARM64X targets.
344344 ChunkRange hybridPdata;
345345
346+ // CHPE metadata symbol on ARM64C target.
347+ DefinedRegular *chpeSym = nullptr ;
348+
346349 COFFLinkerContext &ctx;
347350};
348351} // anonymous namespace
@@ -2362,16 +2365,17 @@ void Writer::setECSymbols() {
23622365 return a.first ->getRVA () < b.first ->getRVA ();
23632366 });
23642367
2368+ ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
23652369 Symbol *rfeTableSym = symtab->findUnderscore (" __arm64x_extra_rfe_table" );
23662370 replaceSymbol<DefinedSynthetic>(rfeTableSym, " __arm64x_extra_rfe_table" ,
2367- pdata .first );
2371+ chpePdata .first );
23682372
2369- if (pdata .first ) {
2373+ if (chpePdata .first ) {
23702374 Symbol *rfeSizeSym =
23712375 symtab->findUnderscore (" __arm64x_extra_rfe_table_size" );
23722376 cast<DefinedAbsolute>(rfeSizeSym)
2373- ->setVA (pdata .last ->getRVA () + pdata .last ->getSize () -
2374- pdata .first ->getRVA ());
2377+ ->setVA (chpePdata .last ->getRVA () + chpePdata .last ->getSize () -
2378+ chpePdata .first ->getRVA ());
23752379 }
23762380
23772381 Symbol *rangesCountSym =
@@ -2425,12 +2429,22 @@ void Writer::setECSymbols() {
24252429 offsetof (data_directory, Size),
24262430 symtab->edataEnd ->getRVA () - symtab->edataStart ->getRVA () +
24272431 symtab->edataEnd ->getSize ());
2428- if (hybridPdata.first )
2432+ if (hybridPdata.first ) {
24292433 ctx.dynamicRelocs ->set (
24302434 dataDirOffset64 + EXCEPTION_TABLE * sizeof (data_directory) +
24312435 offsetof (data_directory, Size),
24322436 hybridPdata.last ->getRVA () - hybridPdata.first ->getRVA () +
24332437 hybridPdata.last ->getSize ());
2438+ if (chpeSym) {
2439+ size_t size = 0 ;
2440+ if (pdata.first )
2441+ size = pdata.last ->getRVA () + pdata.last ->getSize () -
2442+ pdata.first ->getRVA ();
2443+ ctx.dynamicRelocs ->set (chpeSym->getRVA () +
2444+ offsetof (chpe_metadata, ExtraRFETableSize),
2445+ size);
2446+ }
2447+ }
24342448 }
24352449}
24362450
@@ -2666,21 +2680,26 @@ void Writer::createDynamicRelocs() {
26662680 coffHeaderOffset + offsetof (coff_file_header, Machine),
26672681 AMD64);
26682682
2683+ if (ctx.symtab .entry != ctx.hybridSymtab ->entry ||
2684+ pdata.first != hybridPdata.first ) {
2685+ chpeSym = cast_or_null<DefinedRegular>(
2686+ ctx.hybridSymtab ->findUnderscore (" __chpe_metadata" ));
2687+ if (!chpeSym)
2688+ Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
2689+ }
2690+
26692691 if (ctx.symtab .entry != ctx.hybridSymtab ->entry ) {
26702692 ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
26712693 peHeaderOffset +
26722694 offsetof (pe32plus_header, AddressOfEntryPoint),
26732695 cast_or_null<Defined>(ctx.hybridSymtab ->entry ));
26742696
26752697 // Swap the alternate entry point in the CHPE metadata.
2676- Symbol *s = ctx.hybridSymtab ->findUnderscore (" __chpe_metadata" );
2677- if (auto chpeSym = cast_or_null<DefinedRegular>(s))
2698+ if (chpeSym)
26782699 ctx.dynamicRelocs ->add (
26792700 IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
26802701 Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, AlternateEntryPoint)),
26812702 cast_or_null<Defined>(ctx.symtab .entry ));
2682- else
2683- Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
26842703 }
26852704
26862705 if (ctx.symtab .edataStart != ctx.hybridSymtab ->edataStart ) {
@@ -2707,6 +2726,18 @@ void Writer::createDynamicRelocs() {
27072726 dataDirOffset64 +
27082727 EXCEPTION_TABLE * sizeof (data_directory) +
27092728 offsetof (data_directory, Size));
2729+
2730+ // Swap ExtraRFETable in the CHPE metadata.
2731+ if (chpeSym) {
2732+ ctx.dynamicRelocs ->add (
2733+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2734+ Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, ExtraRFETable)),
2735+ pdata.first );
2736+ // The Size value is assigned after addresses are finalized.
2737+ ctx.dynamicRelocs ->add (
2738+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2739+ Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, ExtraRFETableSize)));
2740+ }
27102741 }
27112742
27122743 // Set the hybrid load config to the EC load config.
0 commit comments