From a8c288f7d72555c20c9cbf7ba4ea139857329f48 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 13 Jun 2025 16:25:31 +0200 Subject: [PATCH] [LLD][COFF] Fix ARM64X CHPE exception data size relocation when no x86 .pdata is present Fixes an issue where we incorrectly skip setting the relocation value if `hybridPdata.first` is null. --- lld/COFF/Writer.cpp | 16 +++------- lld/test/COFF/pdata-arm64ec.test | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index cb9d0001015bd..5f1da5e79daca 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -2495,22 +2495,16 @@ void Writer::setECSymbols() { offsetof(data_directory, Size), ctx.symtab.edataEnd->getRVA() - ctx.symtab.edataStart->getRVA() + ctx.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); - } - } + if (chpeSym && pdata.first) + ctx.dynamicRelocs->set( + chpeSym->getRVA() + offsetof(chpe_metadata, ExtraRFETableSize), + pdata.last->getRVA() + pdata.last->getSize() - pdata.first->getRVA()); } } diff --git a/lld/test/COFF/pdata-arm64ec.test b/lld/test/COFF/pdata-arm64ec.test index cf59330b23543..6bdcc5c5682bd 100644 --- a/lld/test/COFF/pdata-arm64ec.test +++ b/lld/test/COFF/pdata-arm64ec.test @@ -80,10 +80,63 @@ DIR3-NEXT: ExtraRFETableSize: 0x10 DIR3: ] DIR3: } +arm64x with no x86 .pdata: + RUN: llvm-objdump -s --section=.pdata test4.dll | FileCheck -check-prefix=DATA4 %s DATA4: 180006000 00100000 11000001 00200000 11000001 ......... ...... DATA4: 180006010 00300000 0e300000 +RUN: lld-link -out:testx2.dll -machine:arm64x arm64-func-sym.obj arm64ec-func-sym.obj \ +RUN: loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry + +RUN: llvm-readobj --headers --coff-load-config testx2.dll | FileCheck -check-prefix=DIR4 %s +DIR4: ImageOptionalHeader { +DIR4: DataDirectory { +DIR4: ExceptionTableRVA: 0x5000 +DIR4-NEXT: ExceptionTableSize: 0x10 +DIR4: } +DIR4: } +DIR4: CHPEMetadata [ +DIR4: ExtraRFETable: 0x0 +DIR4-NEXT: ExtraRFETableSize: 0x0 +DIR4: ] +DIR4: HybridObject { +DIR4: ImageOptionalHeader { +DIR4: ExceptionTableRVA: 0x0 +DIR4-NEXT: ExceptionTableSize: 0x0 +DIR4: } +DIR4: CHPEMetadata [ +DIR4: ExtraRFETable: 0x5000 +DIR4-NEXT: ExtraRFETableSize: 0x10 +DIR4: ] +DIR4: } + +arm64x with no ARM .pdata: + +RUN: lld-link -out:testx3.dll -machine:arm64x x86_64-func-sym.obj loadconfig-arm64.obj loadconfig-arm64ec.obj -dll -noentry + +RUN: llvm-readobj --headers --coff-load-config testx3.dll | FileCheck -check-prefix=DIR5 %s +DIR5: ImageOptionalHeader { +DIR5: DataDirectory { +DIR5: ExceptionTableRVA: 0x0 +DIR5-NEXT: ExceptionTableSize: 0x0 +DIR5: } +DIR5: } +DIR5: CHPEMetadata [ +DIR5: ExtraRFETable: 0x4000 +DIR5-NEXT: ExtraRFETableSize: 0xC +DIR5: ] +DIR5: HybridObject { +DIR5: ImageOptionalHeader { +DIR5: ExceptionTableRVA: 0x4000 +DIR5-NEXT: ExceptionTableSize: 0xC +DIR5: } +DIR5: CHPEMetadata [ +DIR5: ExtraRFETable: 0x0 +DIR5-NEXT: ExtraRFETableSize: 0x0 +DIR5: ] +DIR5: } + Order of inputs doesn't matter, the data is sorted by type and RVA: RUN: lld-link -out:test5.dll -machine:arm64ec x86_64-func-sym.obj arm64ec-func-sym.obj \