@@ -343,6 +343,9 @@ class Writer {
343
343
// x86_64 .pdata sections on ARM64EC/ARM64X targets.
344
344
ChunkRange hybridPdata;
345
345
346
+ // CHPE metadata symbol on ARM64C target.
347
+ DefinedRegular *chpeSym = nullptr ;
348
+
346
349
COFFLinkerContext &ctx;
347
350
};
348
351
} // anonymous namespace
@@ -2362,16 +2365,17 @@ void Writer::setECSymbols() {
2362
2365
return a.first ->getRVA () < b.first ->getRVA ();
2363
2366
});
2364
2367
2368
+ ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
2365
2369
Symbol *rfeTableSym = symtab->findUnderscore (" __arm64x_extra_rfe_table" );
2366
2370
replaceSymbol<DefinedSynthetic>(rfeTableSym, " __arm64x_extra_rfe_table" ,
2367
- pdata .first );
2371
+ chpePdata .first );
2368
2372
2369
- if (pdata .first ) {
2373
+ if (chpePdata .first ) {
2370
2374
Symbol *rfeSizeSym =
2371
2375
symtab->findUnderscore (" __arm64x_extra_rfe_table_size" );
2372
2376
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 ());
2375
2379
}
2376
2380
2377
2381
Symbol *rangesCountSym =
@@ -2425,12 +2429,22 @@ void Writer::setECSymbols() {
2425
2429
offsetof (data_directory, Size),
2426
2430
symtab->edataEnd ->getRVA () - symtab->edataStart ->getRVA () +
2427
2431
symtab->edataEnd ->getSize ());
2428
- if (hybridPdata.first )
2432
+ if (hybridPdata.first ) {
2429
2433
ctx.dynamicRelocs ->set (
2430
2434
dataDirOffset64 + EXCEPTION_TABLE * sizeof (data_directory) +
2431
2435
offsetof (data_directory, Size),
2432
2436
hybridPdata.last ->getRVA () - hybridPdata.first ->getRVA () +
2433
2437
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
+ }
2434
2448
}
2435
2449
}
2436
2450
@@ -2666,21 +2680,26 @@ void Writer::createDynamicRelocs() {
2666
2680
coffHeaderOffset + offsetof (coff_file_header, Machine),
2667
2681
AMD64);
2668
2682
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
+
2669
2691
if (ctx.symtab .entry != ctx.hybridSymtab ->entry ) {
2670
2692
ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2671
2693
peHeaderOffset +
2672
2694
offsetof (pe32plus_header, AddressOfEntryPoint),
2673
2695
cast_or_null<Defined>(ctx.hybridSymtab ->entry ));
2674
2696
2675
2697
// 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)
2678
2699
ctx.dynamicRelocs ->add (
2679
2700
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2680
2701
Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, AlternateEntryPoint)),
2681
2702
cast_or_null<Defined>(ctx.symtab .entry ));
2682
- else
2683
- Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
2684
2703
}
2685
2704
2686
2705
if (ctx.symtab .edataStart != ctx.hybridSymtab ->edataStart ) {
@@ -2707,6 +2726,18 @@ void Writer::createDynamicRelocs() {
2707
2726
dataDirOffset64 +
2708
2727
EXCEPTION_TABLE * sizeof (data_directory) +
2709
2728
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
+ }
2710
2741
}
2711
2742
2712
2743
// Set the hybrid load config to the EC load config.
0 commit comments