https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/116334
1. Sign return address before storing into stack. 2. Treat lazy resolver address as signed. >From 7fbca897414b538d2b528cc8ca54a89d38ba3c6d Mon Sep 17 00:00:00 2001 From: Daniil Kovalev <dkova...@accesssoftek.com> Date: Mon, 21 Oct 2024 16:46:22 +0300 Subject: [PATCH] [PAC][lld] Use PAC instructions in PLT header with `-z pac-plt` 1. Sign return address before storing into stack. 2. Treat lazy resolver address as signed. --- lld/ELF/Arch/AArch64.cpp | 30 ++++++++++++++++++++++++--- lld/test/ELF/aarch64-feature-btipac.s | 4 ++-- lld/test/ELF/aarch64-feature-pac.s | 6 +++--- lld/test/ELF/aarch64-feature-pauth.s | 8 ++++--- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index c64a0dbe8bd62b..8382195f47e1f4 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -1040,13 +1040,23 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) { void AArch64BtiPac::writePltHeader(uint8_t *buf) const { const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c + const uint8_t signLR[] = {0x7f, 0x23, 0x03, 0xd5}; // pacibsp const uint8_t pltData[] = { 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]! 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.got.plt[2])) 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.got.plt[2]))] 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.got.plt[2])) - 0x20, 0x02, 0x1f, 0xd6, // br x17 - 0x1f, 0x20, 0x03, 0xd5, // nop + }; + const uint8_t pacHintBr[] = { + 0x9f, 0x21, 0x03, 0xd5, // autia1716 + 0x20, 0x02, 0x1f, 0xd6 // br x17 + }; + const uint8_t pacBr[] = { + 0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16 + 0x1f, 0x20, 0x03, 0xd5 // nop + }; + const uint8_t stdBr[] = { + 0x20, 0x02, 0x1f, 0xd6, // br x17 0x1f, 0x20, 0x03, 0xd5 // nop }; const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop @@ -1061,15 +1071,29 @@ void AArch64BtiPac::writePltHeader(uint8_t *buf) const { buf += sizeof(btiData); plt += sizeof(btiData); } + if (pacEntry) { + memcpy(buf, signLR, sizeof(signLR)); + buf += sizeof(signLR); + plt += sizeof(signLR); + } memcpy(buf, pltData, sizeof(pltData)); relocateNoSym(buf + 4, R_AARCH64_ADR_PREL_PG_HI21, getAArch64Page(got + 16) - getAArch64Page(plt + 4)); relocateNoSym(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16); relocateNoSym(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16); + + if (pacEntry) + memcpy(buf + sizeof(pltData), (pacUseHint ? pacHintBr : pacBr), + sizeof(pacUseHint ? pacHintBr : pacBr)); + else + memcpy(buf + sizeof(pltData), stdBr, sizeof(stdBr)); if (!btiHeader) // We didn't add the BTI c instruction so round out size with NOP. - memcpy(buf + sizeof(pltData), nopData, sizeof(nopData)); + memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData)); + if (!pacEntry) + // We didn't add the PACIBSP instruction so round out size with NOP. + memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData)); } void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym, diff --git a/lld/test/ELF/aarch64-feature-btipac.s b/lld/test/ELF/aarch64-feature-btipac.s index 3b3c1744370362..caba4862059e8b 100644 --- a/lld/test/ELF/aarch64-feature-btipac.s +++ b/lld/test/ELF/aarch64-feature-btipac.s @@ -155,13 +155,13 @@ func1: # BTIPACEX2: Disassembly of section .plt: # BTIPACEX2: 0000000000210380 <.plt>: # BTIPACEX2-NEXT: 210380: bti c +# BTIPACEX2-NEXT: pacibsp # BTIPACEX2-NEXT: stp x16, x30, [sp, #-16]! # BTIPACEX2-NEXT: adrp x16, 0x230000 # BTIPACEX2-NEXT: ldr x17, [x16, #1208] # BTIPACEX2-NEXT: add x16, x16, #1208 +# BTIPACEX2-NEXT: autia1716 # BTIPACEX2-NEXT: br x17 -# BTIPACEX2-NEXT: nop -# BTIPACEX2-NEXT: nop # BTIPACEX2: 00000000002103a0 <func2@plt>: # BTIPACEX2-NEXT: 2103a0: adrp x16, 0x230000 # BTIPACEX2-NEXT: ldr x17, [x16, #1216] diff --git a/lld/test/ELF/aarch64-feature-pac.s b/lld/test/ELF/aarch64-feature-pac.s index 4fd1fd2acea737..e2b385a61ef448 100644 --- a/lld/test/ELF/aarch64-feature-pac.s +++ b/lld/test/ELF/aarch64-feature-pac.s @@ -96,14 +96,14 @@ # PACPLT-NEXT: 210378: ret # PACPLT: Disassembly of section .plt: # PACPLT: 0000000000210380 <.plt>: -# PACPLT-NEXT: 210380: stp x16, x30, [sp, #-16]! +# PACPLT-NEXT: 210380: pacibsp +# PACPLT-NEXT: stp x16, x30, [sp, #-16]! # PACPLT-NEXT: adrp x16, 0x230000 # PACPLT-NEXT: ldr x17, [x16, #1192] # PACPLT-NEXT: add x16, x16, #1192 +# PACPLT-NEXT: autia1716 # PACPLT-NEXT: br x17 # PACPLT-NEXT: nop -# PACPLT-NEXT: nop -# PACPLT-NEXT: nop # PACPLT: 00000000002103a0 <func2@plt>: # PACPLT-NEXT: 2103a0: adrp x16, 0x230000 # PACPLT-NEXT: ldr x17, [x16, #1200] diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s index c50f38f4a7c975..b8b0baa50051b7 100644 --- a/lld/test/ELF/aarch64-feature-pauth.s +++ b/lld/test/ELF/aarch64-feature-pauth.s @@ -65,13 +65,15 @@ # PACPLT-NEXT: ret # PACPLT: Disassembly of section .plt: # PACPLT: <.plt>: +# PACPLT-NEXT: pacibsp # PACPLT-NEXT: stp x16, x30, [sp, #-0x10]! # PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000> # PACPLT-NEXT: ldr x17, [x16, #0x[[B]]] # PACPLT-NEXT: add x16, x16, #0x[[B]] -# PACPLT-NEXT: br x17 -# PACPLT-NEXT: nop -# PACPLT-NEXT: nop +# NOHINT-NEXT: braa x17, x16 +# NOHINT-NEXT: nop +# HINT-NEXT: autia1716 +# HINT-NEXT: br x17 # PACPLT-NEXT: nop # PACPLT: <func3@plt>: # PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000> _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits