Closed occheung closed 3 years ago
Tested libunwind with OR1K by inserting a panic in artiq runtime startup, this is the result of the subsequent backtrace.
0x40031014
0x400139b0
0x4001395c
0x40030148
0x40030754
These PC refers to the following instructions.
40031014: 04 00 2e 3e l.jal 4003c90c <_Unwind_Backtrace>
...
400139b0: 04 00 75 1e l.jal 40030e28 <rust_begin_unwind>
...
4001395c: 04 00 00 04 l.jal 4001396c <_ZN4core9panicking9panic_fmt17h7960887f32d6fb90E>
...
40030148: 07 ff 8d ec l.jal 400138f8 <_ZN4core9panicking5panic17h404b8d21e6fc634fE>
...
40030754: 07 ff ee 3a l.jal 4002c03c <_ZN7runtime7startup17hbac6b0b62f1dea75E>
Which leads back to the runtime startup.
@occheung Nope, that breaks or1k. artiq.test.coredevice.test_portability.HostVsDeviceCase.test_exceptions hangs. https://nixbld.m-labs.hk/build/197745/nixlog/2
Ran the test and got the following trace.
Then the kernel hangs afterwards. The TCP session is still alive.
These 2 lines are a bit questionable.
https://github.com/m-labs/misoc/blob/79a27a82050266ce4d99d35ca0fe6b53a44649ac/misoc/software/unwinder/src/UnwindRegistersRestore.S#L803-L807
During unwind_resume
in the second phase of raiseException
, the landing pad address (lpad
) is wrote to the __pc
field of a or1k_thread_state_t
struct by invoking the setIP
method.
struct or1k_thread_state_t {
unsigned int __r[32]; // r0-r31
unsigned int __pc; // Program counter
unsigned int __epcr; // Program counter at exception
};
Therefore, the lpad
is stored with an offset of 128, as all registers in OR1K contains 32 bits/4 bytes.
After the lpad
is found, the unwinder proceeds to resume the execution at lpad
. This is handled by __unw_resume
, which calls jumpto
. This is then resolved into the assembly procedure in UnwindRegistersRestore.S
.
The quoted code above will NOT load the lpad
to r9
(link address register) from the offset explained above, since r3
is restored prematurely. It will fail to resume in the expected catch block.
Swapping these 2 instructions should resolve the issue, like the following.
# load new pc into ra
l.lwz r9,128(r3)
# at last, restore r3
l.lwz r3, 12(r3)
Summary
This PR adds a newer version of libunwind that supports RISC-V 32-bits target.
Details
AddedUpdatedllvm-project
as submodule for libunwind.unwinder
, see37bd336
.Both OR1K & RV32 use the updatedlibunwind/Makefile
specifiesunwinder
&llvm-project/libunwind
as libunwind sources for OR1K & RV32 CPUs respectively.unwinder
.-funwind-tables
-fno-exceptions
to prevent the emission of personality symbol__gxx_personality_v0
.alloca
&UINTPTR_MAX
demanded byllvm-project/libunwind
using RISC-V target.size_t
andptrdiff_t
for VexRiscv compatibility.