This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On 15/11/16 19:25, Richard Earnshaw (lists) wrote:
On 15/11/16 16:48, Jiong Wang wrote:On 15/11/16 16:18, Jakub Jelinek wrote:I know nothing about the aarch64 return address signing, would all 3 or say 2 usually appear together without any separate pc advance, or are they all going to appear frequently and at different pcs?I think it's the latter, the DW_OP_AARCH64_paciasp and DW_OP_AARCH64_paciasp_deref are going to appear frequently and at different pcs. For example, the following function prologue, there are three instructions at 0x0, 0x4, 0x8. After the first instruction at 0x0, LR/X30 will be mangled. The "paciasp" always mangle LR register using SP as salt and write back the value into LR. We then generate DW_OP_AARCH64_paciasp to notify any unwinder that the original LR is mangled in this way so they can unwind the original value properly. After the second instruction at 0x4, The mangled value of LR/X30 will be pushed on to stack, unlike usual .cfi_offset, the unwind rule for LR/X30 becomes: first fetch the mangled value from stack offset -16, then do whatever to restore the original value from the mangled value. This is represented by (DW_OP_AARCH64_paciasp_deref, offset). .cfi_startproc 0x0 paciasp (this instruction sign return address register LR/X30) .cfi_val_expression 30, DW_OP_AARCH64_paciasp 0x4 stp x29, x30, [sp, -32]! .cfi_val_expression 30, DW_OP_AARCH64_paciasp_deref, -16 .cfi_offset 29, -32 .cfi_def_cfa_offset 32 0x8 add x29, sp, 0Now I'm confused. I was thinking that we needed one opcode for the sign operation in the prologue and one for the unsign/validate operation in the epilogue (to support non-call exceptions.
IMO, non-call exceptions is fine, it looks to me doesn't need extra description as for non-call exceptions (exceptions thrown from signal handler) the key point is how to unwind across signal frame. For libgcc EH unwinder, when normal unwinding failed, it will fall back to architecture unwinding hook which restore some information from signal frame which is just on top of the signal handler's frame. I can see AArch64 implementation will setup return address column like the following logic where "sc->pc" is initialized by kernel and it's not signed therefore should sucess on further unwinding. fs->regs.reg[__LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__].how = REG_SAVED_VAL_OFFSET; fs->regs.reg[__LIBGCC_DWARF_ALT_FRAME_RETURN_COLUMN__].loc.offset = (_Unwind_Ptr) (sc->pc) - new_cfa;
But why do we need a separate code to say that a previously signed value has now been pushed on the stack? Surely that's just a normal store operation that can be tracked through the unwinding state machine.
I was thinking the same thing, but found it doesn't work. My understanding of frame unwinding described at DWARF specification is: there are two steps for frame unwinding. The first step is to calculate register restore rules. Unwinder scans register rules from function start to the unwinding PC, one rule will be *overridden* by the next for the same register, there is *no inheritance*. The second step is then to evaluate all the final rules collected at the unwinding PC. According to the rule, either fetch the value from stack or evaluate the value on DWARF expression stack etc. I also had tried to modify ".cfi_val_expression" at offset 0x4 in above example into ".cfi_offset 30, -24", libgcc EH unwinder just doesn't work.
I was expecting the third opcode to be needed for the special operations that are not frequently used by the compiler.
The two operations DW_OP_AARCH64_paciasp and DW_OP_AARCH64_paciasp_deref were designed as shortcut operations when LR is signed with A key and using function's CFA as salt. This is the default behaviour of return address signing so is expected to be used for most of the time. DW_OP_AARCH64_pauth is designed as a generic operation that allow describing pointer signing on any value using any salt and key in case we can't use the shortcut operations we can use this.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |