Re: [PATCH] loongarch: Only select HAVE_OBJTOOL and allow ORC unwinder if the inline assembler supports R_LARCH_{32,64}_PCREL

From: Jinyang He
Date: Wed Jun 05 2024 - 22:10:25 EST


On 2024-06-06 03:05, Xi Ruoyao wrote:

On Wed, 2024-06-05 at 23:47 +0800, Jinyang He wrote:
In our 419 repo this func has been renamed arch_update_insn_state (, now it
should be arch_update_cfi_state) and give some actions to deal with the
frame pointer case. If we support it we may deal with some case but for
clang...

.global test
.type test,@function
test:

addi.d  $sp,$sp,-448
st.d    $ra,$sp,440
st.d    $fp,$sp,432
addi.d  $fp,$sp,448

# do something  <- not change $sp
This is simplified. In the real code $sp is changed, something like:

bstrins.d $sp, $zero, 5, 0

$fp is needed to allow restoring $sp after realigning $sp for some local
over-aligned variables, as demonstrated by this example:

struct x { _Alignas(64) char buf[128]; };

void f(struct x *p);
void g()
{
struct x x = { .buf = "1145141919810" };
f(&x);
}

GCC does not align $sp, it produces the aligned address for x from an
unaligned $sp instead:

addi.d $a0, $sp, 63
srli.d $a0, $a0, 6
slli.d $a0, $a0, 6

thus there's no need to use $fp.

/* snip */

<- restore regs from non-cfa ?
         ld.d    $ra, $sp, 8                     # 8-byte Folded Reload
/* snip */

Maybe Clang have anything wrong?
I don't think we must restore regs based on $fp just because CFA is
based on $fp.

You are right.


The .cfi directives only provides *one* possible way to
restore the regs.
What I just confused is that there is no ".cfi_*"
in the eplogue by clang, which may cause wrong backtrace if gdb set

breakpoint there and backtrace. (But this is out of this topic.)



This way is convenient to the unwinder, but not
necessarily convenient to the CPU thus the real instruction sequence can
use a different way. They only need to be "equivalent", not necessarily
"exactly same."

Also note that .cfi_* directives are completely irrelevant for objtool.
THe objtool synthesizes the ORC unwind info from the machine
instructions, not the DWARF unwind info coded with .cfi_*.
The entire point of ORC is avoiding DWARF. It's even named ORC because
ORC and DWARF are sworn enemies in some tales.
Yes.
The yestorday attachment has something wrong.
Enmmmm.... (It seems I'm careless.) diff is,

                switch (op->src.type) {
                case OP_SRC_ADD:
                        if (op->dest.reg == CFI_SP && op->src.reg == CFI_SP) {
-                               /* addi.d sp, sp, imm */
-                               cfi->stack_size -= op->src.offset;
-                               if (cfa->base == CFI_SP)
                                /* addi.d sp, sp, imm */
                                cfi->stack_size -= op->src.offset;
                                if (cfa->base == CFI_SP)

Or you can get the tmp fix by [1].

[1]: https://github.com/MQ-mengqing/linux/commit/c1f7df3eb2a2bb7a1c10c2aa6e0e3d585b457352