[lld] 8252e0e - [LLD][COFF] Emit ARM64X relocations for CHPE ExtraRFETable entries (#126713)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 13 10:23:01 PST 2025


Author: Jacek Caban
Date: 2025-02-13T19:22:57+01:00
New Revision: 8252e0ef82efe672f1878dbfd74f99b86f293d8f

URL: https://github.com/llvm/llvm-project/commit/8252e0ef82efe672f1878dbfd74f99b86f293d8f
DIFF: https://github.com/llvm/llvm-project/commit/8252e0ef82efe672f1878dbfd74f99b86f293d8f.diff

LOG: [LLD][COFF] Emit ARM64X relocations for CHPE ExtraRFETable entries (#126713)

In the native view, ExtraEFRTable references the x86 exception table.
The EC view references the ARM exception table, as it did before this
change.

Added: 
    

Modified: 
    lld/COFF/Writer.cpp
    lld/test/COFF/pdata-arm64ec.test

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index b03a4eab16ce2..678de915b6cdb 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -343,6 +343,9 @@ class Writer {
   // x86_64 .pdata sections on ARM64EC/ARM64X targets.
   ChunkRange hybridPdata;
 
+  // CHPE metadata symbol on ARM64C target.
+  DefinedRegular *chpeSym = nullptr;
+
   COFFLinkerContext &ctx;
 };
 } // anonymous namespace
@@ -2362,16 +2365,17 @@ void Writer::setECSymbols() {
     return a.first->getRVA() < b.first->getRVA();
   });
 
+  ChunkRange &chpePdata = ctx.hybridSymtab ? hybridPdata : pdata;
   Symbol *rfeTableSym = symtab->findUnderscore("__arm64x_extra_rfe_table");
   replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
-                                  pdata.first);
+                                  chpePdata.first);
 
-  if (pdata.first) {
+  if (chpePdata.first) {
     Symbol *rfeSizeSym =
         symtab->findUnderscore("__arm64x_extra_rfe_table_size");
     cast<DefinedAbsolute>(rfeSizeSym)
-        ->setVA(pdata.last->getRVA() + pdata.last->getSize() -
-                pdata.first->getRVA());
+        ->setVA(chpePdata.last->getRVA() + chpePdata.last->getSize() -
+                chpePdata.first->getRVA());
   }
 
   Symbol *rangesCountSym =
@@ -2425,12 +2429,22 @@ void Writer::setECSymbols() {
               offsetof(data_directory, Size),
           symtab->edataEnd->getRVA() - symtab->edataStart->getRVA() +
               symtab->edataEnd->getSize());
-    if (hybridPdata.first)
+    if (hybridPdata.first) {
       ctx.dynamicRelocs->set(
           dataDirOffset64 + EXCEPTION_TABLE * sizeof(data_directory) +
               offsetof(data_directory, Size),
           hybridPdata.last->getRVA() - hybridPdata.first->getRVA() +
               hybridPdata.last->getSize());
+      if (chpeSym) {
+        size_t size = 0;
+        if (pdata.first)
+          size = pdata.last->getRVA() + pdata.last->getSize() -
+                 pdata.first->getRVA();
+        ctx.dynamicRelocs->set(chpeSym->getRVA() +
+                                   offsetof(chpe_metadata, ExtraRFETableSize),
+                               size);
+      }
+    }
   }
 }
 
@@ -2666,6 +2680,14 @@ void Writer::createDynamicRelocs() {
                          coffHeaderOffset + offsetof(coff_file_header, Machine),
                          AMD64);
 
+  if (ctx.symtab.entry != ctx.hybridSymtab->entry ||
+      pdata.first != hybridPdata.first) {
+    chpeSym = cast_or_null<DefinedRegular>(
+        ctx.hybridSymtab->findUnderscore("__chpe_metadata"));
+    if (!chpeSym)
+      Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
+  }
+
   if (ctx.symtab.entry != ctx.hybridSymtab->entry) {
     ctx.dynamicRelocs->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
                            peHeaderOffset +
@@ -2673,14 +2695,11 @@ void Writer::createDynamicRelocs() {
                            cast_or_null<Defined>(ctx.hybridSymtab->entry));
 
     // Swap the alternate entry point in the CHPE metadata.
-    Symbol *s = ctx.hybridSymtab->findUnderscore("__chpe_metadata");
-    if (auto chpeSym = cast_or_null<DefinedRegular>(s))
+    if (chpeSym)
       ctx.dynamicRelocs->add(
           IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
           Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, AlternateEntryPoint)),
           cast_or_null<Defined>(ctx.symtab.entry));
-    else
-      Warn(ctx) << "'__chpe_metadata' is missing for ARM64X target";
   }
 
   if (ctx.symtab.edataStart != ctx.hybridSymtab->edataStart) {
@@ -2707,6 +2726,18 @@ void Writer::createDynamicRelocs() {
                            dataDirOffset64 +
                                EXCEPTION_TABLE * sizeof(data_directory) +
                                offsetof(data_directory, Size));
+
+    // Swap ExtraRFETable in the CHPE metadata.
+    if (chpeSym) {
+      ctx.dynamicRelocs->add(
+          IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
+          Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETable)),
+          pdata.first);
+      // The Size value is assigned after addresses are finalized.
+      ctx.dynamicRelocs->add(
+          IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE, sizeof(uint32_t),
+          Arm64XRelocVal(chpeSym, offsetof(chpe_metadata, ExtraRFETableSize)));
+    }
   }
 
   // Set the hybrid load config to the EC load config.

diff  --git a/lld/test/COFF/pdata-arm64ec.test b/lld/test/COFF/pdata-arm64ec.test
index fbec797525f7f..cf59330b23543 100644
--- a/lld/test/COFF/pdata-arm64ec.test
+++ b/lld/test/COFF/pdata-arm64ec.test
@@ -58,18 +58,26 @@ Mixed arm64x code:
 RUN: lld-link -out:test4.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \
 RUN:          x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
 
-RUN: llvm-readobj --headers test4.dll | FileCheck -check-prefix=DIR3 %s
+RUN: llvm-readobj --headers --coff-load-config test4.dll | FileCheck -check-prefix=DIR3 %s
 DIR3:      ImageOptionalHeader {
 DIR3:        DataDirectory {
 DIR3:          ExceptionTableRVA: 0x6000
 DIR3-NEXT:     ExceptionTableSize: 0x10
 DIR3:        }
 DIR3:      }
+DIR3:      CHPEMetadata [
+DIR3:        ExtraRFETable: 0x6010
+DIR3-NEXT:   ExtraRFETableSize: 0xC
+DIR3:      ]
 DIR3:      HybridObject {
 DIR3:        ImageOptionalHeader {
 DIR3:          ExceptionTableRVA: 0x6010
 DIR3-NEXT:     ExceptionTableSize: 0xC
 DIR3:        }
+DIR3:        CHPEMetadata [
+DIR3:          ExtraRFETable: 0x6000
+DIR3-NEXT:     ExtraRFETableSize: 0x10
+DIR3:        ]
 DIR3:      }
 
 RUN: llvm-objdump -s --section=.pdata test4.dll | FileCheck -check-prefix=DATA4 %s
@@ -86,12 +94,12 @@ RUN: llvm-objdump -s --section=.pdata test5.dll | FileCheck -check-prefix=DATA3
 
 RUN: lld-link -out:test6.dll -machine:arm64x arm64ec-func-sym.obj x86_64-func-sym.obj \
 RUN:          arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
-RUN: llvm-readobj --headers test6.dll | FileCheck -check-prefix=DIR3 %s
+RUN: llvm-readobj --headers --coff-load-config test6.dll | FileCheck -check-prefix=DIR3 %s
 RUN: llvm-objdump -s --section=.pdata test6.dll | FileCheck -check-prefix=DATA4 %s
 
 RUN: lld-link -out:test7.dll -machine:arm64x x86_64-func-sym.obj arm64ec-func-sym.obj \
 RUN:          arm64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry
-RUN: llvm-readobj --headers test7.dll | FileCheck -check-prefix=DIR3 %s
+RUN: llvm-readobj --headers --coff-load-config test7.dll | FileCheck -check-prefix=DIR3 %s
 RUN: llvm-objdump -s --section=.pdata test7.dll | FileCheck -check-prefix=DATA4 %s
 
 #--- arm64-func-sym.s


        


More information about the llvm-commits mailing list