[lld] 52a7116 - [LLD][COFF] Add support for CHPE code ranges metadata. (#105741)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 12:17:41 PDT 2024


Author: Jacek Caban
Date: 2024-08-23T21:17:38+02:00
New Revision: 52a7116f5c6ada234f47f7794aaf501a3692b997

URL: https://github.com/llvm/llvm-project/commit/52a7116f5c6ada234f47f7794aaf501a3692b997
DIFF: https://github.com/llvm/llvm-project/commit/52a7116f5c6ada234f47f7794aaf501a3692b997.diff

LOG: [LLD][COFF] Add support for CHPE code ranges metadata. (#105741)

This is part of CHPE metadata containing a sorted list of x86_64 export
thunks RVAs and sizes.

Added: 
    

Modified: 
    lld/COFF/Chunks.cpp
    lld/COFF/Chunks.h
    lld/COFF/Driver.cpp
    lld/COFF/Writer.cpp
    lld/test/COFF/Inputs/loadconfig-arm64ec.s
    lld/test/COFF/arm64ec-export-thunks.test
    lld/test/COFF/arm64ec-patchable-thunks.test

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 4e3a564ebacd87..72a9ad05ca11c1 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -1078,6 +1078,22 @@ void ECExportThunkChunk::writeTo(uint8_t *buf) const {
   write32le(buf + 10, target->getRVA() - rva - 14);
 }
 
+size_t CHPECodeRangesChunk::getSize() const {
+  return exportThunks.size() * sizeof(chpe_code_range_entry);
+}
+
+void CHPECodeRangesChunk::writeTo(uint8_t *buf) const {
+  auto ranges = reinterpret_cast<chpe_code_range_entry *>(buf);
+
+  for (uint32_t i = 0; i < exportThunks.size(); i++) {
+    Chunk *thunk = exportThunks[i].first;
+    uint32_t start = thunk->getRVA();
+    ranges[i].StartRva = start;
+    ranges[i].EndRva = start + thunk->getSize();
+    ranges[i].EntryPoint = start;
+  }
+}
+
 size_t CHPERedirectionChunk::getSize() const {
   return exportThunks.size() * sizeof(chpe_redirection_entry);
 }

diff  --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 015df41b04c67d..fe202008971a54 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -749,6 +749,17 @@ class ECCodeMapChunk : public NonSectionChunk {
   std::vector<ECCodeMapEntry> ↦
 };
 
+class CHPECodeRangesChunk : public NonSectionChunk {
+public:
+  CHPECodeRangesChunk(std::vector<std::pair<Chunk *, Defined *>> &exportThunks)
+      : exportThunks(exportThunks) {}
+  size_t getSize() const override;
+  void writeTo(uint8_t *buf) const override;
+
+private:
+  std::vector<std::pair<Chunk *, Defined *>> &exportThunks;
+};
+
 class CHPERedirectionChunk : public NonSectionChunk {
 public:
   CHPERedirectionChunk(std::vector<std::pair<Chunk *, Defined *>> &exportThunks)

diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 472f5074ba8b8c..3ef9fa3f65c6a6 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -2444,6 +2444,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
     ctx.symtab.addAbsolute("__arm64x_redirection_metadata_count", 0);
     ctx.symtab.addAbsolute("__hybrid_code_map", 0);
     ctx.symtab.addAbsolute("__hybrid_code_map_count", 0);
+    ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points", 0);
+    ctx.symtab.addAbsolute("__x64_code_ranges_to_entry_points_count", 0);
   }
 
   if (config->pseudoRelocs) {

diff  --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 358d16fe330cea..0360e186ecf0cf 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -2071,6 +2071,12 @@ void Writer::createECChunks() {
   replaceSymbol<DefinedSynthetic>(codeMapSym, codeMapSym->getName(),
                                   codeMapChunk);
 
+  CHPECodeRangesChunk *ranges = make<CHPECodeRangesChunk>(exportThunks);
+  rdataSec->addChunk(ranges);
+  Symbol *rangesSym =
+      ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points");
+  replaceSymbol<DefinedSynthetic>(rangesSym, rangesSym->getName(), ranges);
+
   CHPERedirectionChunk *entryPoints = make<CHPERedirectionChunk>(exportThunks);
   a64xrmSec->addChunk(entryPoints);
   Symbol *entryPointsSym =
@@ -2186,6 +2192,10 @@ void Writer::setECSymbols() {
                 pdata.first->getRVA());
   }
 
+  Symbol *rangesCountSym =
+      ctx.symtab.findUnderscore("__x64_code_ranges_to_entry_points_count");
+  cast<DefinedAbsolute>(rangesCountSym)->setVA(exportThunks.size());
+
   Symbol *entryPointCountSym =
       ctx.symtab.findUnderscore("__arm64x_redirection_metadata_count");
   cast<DefinedAbsolute>(entryPointCountSym)->setVA(exportThunks.size());

diff  --git a/lld/test/COFF/Inputs/loadconfig-arm64ec.s b/lld/test/COFF/Inputs/loadconfig-arm64ec.s
index 62a6d0cab642e9..78e7fba43a0a4d 100644
--- a/lld/test/COFF/Inputs/loadconfig-arm64ec.s
+++ b/lld/test/COFF/Inputs/loadconfig-arm64ec.s
@@ -66,7 +66,7 @@ __chpe_metadata:
         .word 1
         .rva __hybrid_code_map
         .word __hybrid_code_map_count
-        .word 0 // __x64_code_ranges_to_entry_points
+        .rva __x64_code_ranges_to_entry_points
         .rva __arm64x_redirection_metadata
         .rva __os_arm64x_dispatch_call_no_redirect
         .rva __os_arm64x_dispatch_ret
@@ -75,7 +75,7 @@ __chpe_metadata:
         .rva __os_arm64x_check_icall_cfg
         .word 0 // __arm64x_native_entrypoint
         .word 0 // __hybrid_auxiliary_iat
-        .word 0 // __x64_code_ranges_to_entry_points_count
+        .word __x64_code_ranges_to_entry_points_count
         .word __arm64x_redirection_metadata_count
         .rva __os_arm64x_get_x64_information
         .rva __os_arm64x_set_x64_information

diff  --git a/lld/test/COFF/arm64ec-export-thunks.test b/lld/test/COFF/arm64ec-export-thunks.test
index 2e4cfd6203b751..809fac1f24a7dc 100644
--- a/lld/test/COFF/arm64ec-export-thunks.test
+++ b/lld/test/COFF/arm64ec-export-thunks.test
@@ -58,7 +58,10 @@ EXP-CHPE:       CodeMap [
 EXP-CHPE-NEXT:    0x1000 - 0x100C  ARM64EC
 EXP-CHPE-NEXT:    0x2000 - 0x3020  X64
 EXP-CHPE-NEXT:  ]
-EXP-CHPE-NEXT:  CodeRangesToEntryPoints: 0
+EXP-CHPE-NEXT:  CodeRangesToEntryPoints [
+EXP-CHPE-NEXT:    0x3000 - 0x3010 -> 0x3000
+EXP-CHPE-NEXT:    0x3010 - 0x3020 -> 0x3010
+EXP-CHPE-NEXT:  ]
 EXP-CHPE-NEXT:  RedirectionMetadata [
 EXP-CHPE-NEXT:    0x3000 -> 0x1000
 EXP-CHPE-NEXT:    0x3010 -> 0x1000
@@ -121,7 +124,9 @@ ENTRY-CHPE:       CodeMap [
 ENTRY-CHPE-NEXT:    0x1000 - 0x100C  ARM64EC
 ENTRY-CHPE-NEXT:    0x2000 - 0x2010  X64
 ENTRY-CHPE-NEXT:  ]
-ENTRY-CHPE-NEXT:  CodeRangesToEntryPoints: 0
+ENTRY-CHPE-NEXT:  CodeRangesToEntryPoints [
+ENTRY-CHPE-NEXT:    0x2000 - 0x2010 -> 0x2000
+ENTRY-CHPE-NEXT:  ]
 ENTRY-CHPE-NEXT:  RedirectionMetadata [
 ENTRY-CHPE-NEXT:    0x2000 -> 0x1000
 ENTRY-CHPE-NEXT:  ]

diff  --git a/lld/test/COFF/arm64ec-patchable-thunks.test b/lld/test/COFF/arm64ec-patchable-thunks.test
index 044f3c7cebdf8e..5cebe7cc27ad63 100644
--- a/lld/test/COFF/arm64ec-patchable-thunks.test
+++ b/lld/test/COFF/arm64ec-patchable-thunks.test
@@ -34,7 +34,9 @@ PATCH-CHPE:       CodeMap [
 PATCH-CHPE-NEXT:    0x1000 - 0x1008  ARM64EC
 PATCH-CHPE-NEXT:    0x2000 - 0x2010  X64
 PATCH-CHPE-NEXT:  ]
-PATCH-CHPE-NEXT:  CodeRangesToEntryPoints: 0
+PATCH-CHPE-NEXT:  CodeRangesToEntryPoints [
+PATCH-CHPE-NEXT:    0x2000 - 0x2010 -> 0x2000
+PATCH-CHPE-NEXT:  ]
 PATCH-CHPE-NEXT:  RedirectionMetadata [
 PATCH-CHPE-NEXT:    0x2000 -> 0x1000
 PATCH-CHPE-NEXT:  ]


        


More information about the llvm-commits mailing list