@@ -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
@@ -2360,16 +2363,17 @@ void Writer::setECSymbols() {
23602363 return a.first ->getRVA () < b.first ->getRVA ();
23612364 });
23622365
2366+ ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
23632367 Symbol *rfeTableSym = symtab->findUnderscore (" __arm64x_extra_rfe_table" );
23642368 replaceSymbol<DefinedSynthetic>(rfeTableSym, " __arm64x_extra_rfe_table" ,
2365- pdata .first );
2369+ chpePdata .first );
23662370
2367- if (pdata .first ) {
2371+ if (chpePdata .first ) {
23682372 Symbol *rfeSizeSym =
23692373 symtab->findUnderscore (" __arm64x_extra_rfe_table_size" );
23702374 cast<DefinedAbsolute>(rfeSizeSym)
2371- ->setVA (pdata .last ->getRVA () + pdata .last ->getSize () -
2372- pdata .first ->getRVA ());
2375+ ->setVA (chpePdata .last ->getRVA () + chpePdata .last ->getSize () -
2376+ chpePdata .first ->getRVA ());
23732377 }
23742378
23752379 Symbol *rangesCountSym =
@@ -2423,12 +2427,22 @@ void Writer::setECSymbols() {
24232427 offsetof (data_directory, Size),
24242428 symtab->edataEnd ->getRVA () - symtab->edataStart ->getRVA () +
24252429 symtab->edataEnd ->getSize ());
2426- if (hybridPdata.first )
2430+ if (hybridPdata.first ) {
24272431 ctx.dynamicRelocs ->set (
24282432 dataDirOffset64 + EXCEPTION_TABLE * sizeof (data_directory) +
24292433 offsetof (data_directory, Size),
24302434 hybridPdata.last ->getRVA () - hybridPdata.first ->getRVA () +
24312435 hybridPdata.last ->getSize ());
2436+ if (chpeSym) {
2437+ size_t size = 0 ;
2438+ if (pdata.first )
2439+ size = pdata.last ->getRVA () - pdata.first ->getRVA () +
2440+ pdata.last ->getSize ();
2441+ ctx.dynamicRelocs ->set (chpeSym->getRVA () +
2442+ offsetof (chpe_metadata, ExtraRFETableSize),
2443+ size);
2444+ }
2445+ }
24322446 }
24332447}
24342448
@@ -2664,21 +2678,26 @@ void Writer::createDynamicRelocs() {
26642678 coffHeaderOffset + offsetof (coff_file_header, Machine),
26652679 AMD64);
26662680
2681+ if (ctx.symtab .entry != ctx.hybridSymtab ->entry ||
2682+ pdata.first != hybridPdata.first ) {
2683+ chpeSym = cast_or_null<DefinedRegular>(
2684+ ctx.hybridSymtab ->findUnderscore (" __chpe_metadata" ));
2685+ if (!chpeSym)
2686+ Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
2687+ }
2688+
26672689 if (ctx.symtab .entry != ctx.hybridSymtab ->entry ) {
26682690 ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
26692691 peHeaderOffset +
26702692 offsetof (pe32plus_header, AddressOfEntryPoint),
26712693 cast_or_null<Defined>(ctx.hybridSymtab ->entry ));
26722694
26732695 // Swap the alternate entry point in the CHPE metadata.
2674- Symbol *s = ctx.hybridSymtab ->findUnderscore (" __chpe_metadata" );
2675- if (auto chpeSym = cast_or_null<DefinedRegular>(s))
2696+ if (chpeSym)
26762697 ctx.dynamicRelocs ->add (
26772698 IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
26782699 Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, AlternateEntryPoint)),
26792700 cast_or_null<Defined>(ctx.symtab .entry ));
2680- else
2681- Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
26822701 }
26832702
26842703 if (ctx.symtab .edataStart != ctx.hybridSymtab ->edataStart ) {
@@ -2705,6 +2724,18 @@ void Writer::createDynamicRelocs() {
27052724 dataDirOffset64 +
27062725 EXCEPTION_TABLE * sizeof (data_directory) +
27072726 offsetof (data_directory, Size));
2727+
2728+ // Swap ExtraRFETable in the CHPE metadata.
2729+ if (chpeSym) {
2730+ ctx.dynamicRelocs ->add (
2731+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2732+ Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, ExtraRFETable)),
2733+ pdata.first );
2734+ // The Size value is assigned after addresses are finalized.
2735+ ctx.dynamicRelocs ->add (
2736+ IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2737+ Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, ExtraRFETableSize)));
2738+ }
27082739 }
27092740
27102741 // Set the hybrid load config to the EC load config.
0 commit comments