@@ -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
@@ -2360,16 +2363,17 @@ void Writer::setECSymbols() {
2360
2363
return a.first ->getRVA () < b.first ->getRVA ();
2361
2364
});
2362
2365
2366
+ ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
2363
2367
Symbol *rfeTableSym = symtab->findUnderscore (" __arm64x_extra_rfe_table" );
2364
2368
replaceSymbol<DefinedSynthetic>(rfeTableSym, " __arm64x_extra_rfe_table" ,
2365
- pdata .first );
2369
+ chpePdata .first );
2366
2370
2367
- if (pdata .first ) {
2371
+ if (chpePdata .first ) {
2368
2372
Symbol *rfeSizeSym =
2369
2373
symtab->findUnderscore (" __arm64x_extra_rfe_table_size" );
2370
2374
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 ());
2373
2377
}
2374
2378
2375
2379
Symbol *rangesCountSym =
@@ -2423,12 +2427,22 @@ void Writer::setECSymbols() {
2423
2427
offsetof (data_directory, Size),
2424
2428
symtab->edataEnd ->getRVA () - symtab->edataStart ->getRVA () +
2425
2429
symtab->edataEnd ->getSize ());
2426
- if (hybridPdata.first )
2430
+ if (hybridPdata.first ) {
2427
2431
ctx.dynamicRelocs ->set (
2428
2432
dataDirOffset64 + EXCEPTION_TABLE * sizeof (data_directory) +
2429
2433
offsetof (data_directory, Size),
2430
2434
hybridPdata.last ->getRVA () - hybridPdata.first ->getRVA () +
2431
2435
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
+ }
2432
2446
}
2433
2447
}
2434
2448
@@ -2664,21 +2678,26 @@ void Writer::createDynamicRelocs() {
2664
2678
coffHeaderOffset + offsetof (coff_file_header, Machine),
2665
2679
AMD64);
2666
2680
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
+
2667
2689
if (ctx.symtab .entry != ctx.hybridSymtab ->entry ) {
2668
2690
ctx.dynamicRelocs ->add (IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2669
2691
peHeaderOffset +
2670
2692
offsetof (pe32plus_header, AddressOfEntryPoint),
2671
2693
cast_or_null<Defined>(ctx.hybridSymtab ->entry ));
2672
2694
2673
2695
// 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)
2676
2697
ctx.dynamicRelocs ->add (
2677
2698
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof (uint32_t ),
2678
2699
Arm64XRelocVal (chpeSym, offsetof (chpe_metadata, AlternateEntryPoint)),
2679
2700
cast_or_null<Defined>(ctx.symtab .entry ));
2680
- else
2681
- Warn (ctx) << " '__chpe_metadata' is missing for ARM64X target" ;
2682
2701
}
2683
2702
2684
2703
if (ctx.symtab .edataStart != ctx.hybridSymtab ->edataStart ) {
@@ -2705,6 +2724,18 @@ void Writer::createDynamicRelocs() {
2705
2724
dataDirOffset64 +
2706
2725
EXCEPTION_TABLE * sizeof (data_directory) +
2707
2726
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
+ }
2708
2739
}
2709
2740
2710
2741
// Set the hybrid load config to the EC load config.
0 commit comments