Also default to disassembling a and m features
Some code taken from https://reviews.llvm.org/D62732 , which hasn't been
updated in a year.
Tested with 32 and 64 bit Linux user space QEMU
Differential D159101
[RISC-V] Add RISC-V ABI plugin ted on Aug 29 2023, 7:57 AM. Authored by
Details Also default to disassembling a and m features Tested with 32 and 64 bit Linux user space QEMU
Diff Detail
Event TimelineComment Actions From what little I know about the ABI this looks ok. Consider adding a riscv expert to check those bits for you. Testing wise riscv is in a strange place without a working lldb-server or a buildbot that could run such a thing (and qemu-user doesn't emulate ptrace calls). Getting the test suite to run against qemu instead is probably more effort than it's worth assuming lldb-server is not that far off working. If that's true then I'd be ok accepting this, it's quite self contained in any case and we have all that instruction emulation code for single stepping already. If someone could get lldb-server running on qemu-system and test against that (just locally) that would be a great improvement and likely flush out many problems with a lot of the more niche methods in these classes.
Comment Actions Also could you provide a list of things you have tested with qemu. So I can get an idea of how sure we can be any of this works / be a test plan, albeit manual for anyone updating this code in future. Comment Actions With this change, I'm able to debug RISC-V 32 and 64 bit applications using Linux user space QEMU, using @labath 's QemuUser platform. Simple expression parsing with the IR Interpreter is working. Complex expression parsing with JIT is not tested. Here's an example of a simple debug session: > bin/lldb (lldb) platform select qemu-user Platform: qemu-user Triple: x86_64-*-linux-gnu OS Version: 5.4.0 (5.4.0-136-generic) Hostname: 127.0.0.1 WorkingDir: /local/mnt/ted/upstream/full Kernel: #153~18.04.1-Ubuntu SMP Wed Nov 30 15:47:57 UTC 2022 (lldb) file ~/lldb_test/factrv32 Current executable set to '/usr2/tedwood/lldb_test/factrv32' (riscv32). (lldb) b main Breakpoint 1: where = factrv32`main + 28 at factorial.c:32:8, address = 0x000104ea (lldb) target list Current targets: * target #0: /usr2/tedwood/lldb_test/factrv32 ( arch=riscv32-*-linux, platform=qemu-user ) (lldb) r Process 1 launched: '/usr2/tedwood/lldb_test/factrv32' (riscv32) Process 1 stopped * thread #1, stop reason = breakpoint 1.1 frame #0: 0x000104ea factrv32`main(argc=1, argv=0x40800604) at factorial.c:32:8 29 } 30 */ 31 -> 32 base = 10; 33 34 printf("Factorial of %d is %d\n", base, factorial(base)); 35 return 0; (lldb) s Process 1 stopped * thread #1, stop reason = step in frame #0: 0x000104ee factrv32`main(argc=1, argv=0x40800604) at factorial.c:34:37 31 32 base = 10; 33 -> 34 printf("Factorial of %d is %d\n", base, factorial(base)); 35 return 0; 36 } 37 (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x00010488 factrv32`factorial(i=10) at factorial.c:6:7 3 4 int factorial(int i) 5 { -> 6 if (i == 1) 7 return 1; 8 else 9 return i * factorial(i - 1); (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x000104a4 factrv32`factorial(i=10) at factorial.c:9:12 6 if (i == 1) 7 return 1; 8 else -> 9 return i * factorial(i - 1); 10 } 11 12 int main(int argc, char **argv) (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x00010488 factrv32`factorial(i=9) at factorial.c:6:7 3 4 int factorial(int i) 5 { -> 6 if (i == 1) 7 return 1; 8 else 9 return i * factorial(i - 1); (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x000104a4 factrv32`factorial(i=9) at factorial.c:9:12 6 if (i == 1) 7 return 1; 8 else -> 9 return i * factorial(i - 1); 10 } 11 12 int main(int argc, char **argv) (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x00010488 factrv32`factorial(i=8) at factorial.c:6:7 3 4 int factorial(int i) 5 { -> 6 if (i == 1) 7 return 1; 8 else 9 return i * factorial(i - 1); (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x000104a4 factrv32`factorial(i=8) at factorial.c:9:12 6 if (i == 1) 7 return 1; 8 else -> 9 return i * factorial(i - 1); 10 } 11 12 int main(int argc, char **argv) (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x00010488 factrv32`factorial(i=7) at factorial.c:6:7 3 4 int factorial(int i) 5 { -> 6 if (i == 1) 7 return 1; 8 else 9 return i * factorial(i - 1); (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x000104a4 factrv32`factorial(i=7) at factorial.c:9:12 6 if (i == 1) 7 return 1; 8 else -> 9 return i * factorial(i - 1); 10 } 11 12 int main(int argc, char **argv) (lldb) Process 1 stopped * thread #1, stop reason = step in frame #0: 0x00010488 factrv32`factorial(i=6) at factorial.c:6:7 3 4 int factorial(int i) 5 { -> 6 if (i == 1) 7 return 1; 8 else 9 return i * factorial(i - 1); (lldb) bt * thread #1, stop reason = step in * frame #0: 0x00010488 factrv32`factorial(i=6) at factorial.c:6:7 frame #1: 0x000104b0 factrv32`factorial(i=7) at factorial.c:9:16 frame #2: 0x000104b0 factrv32`factorial(i=8) at factorial.c:9:16 frame #3: 0x000104b0 factrv32`factorial(i=9) at factorial.c:9:16 frame #4: 0x000104b0 factrv32`factorial(i=10) at factorial.c:9:16 frame #5: 0x000104f8 factrv32`main(argc=1, argv=0x40800604) at factorial.c:34:43 frame #6: 0x000106f0 factrv32`__libc_start_main(main=(factrv32`main at factorial.c:13), argc=1, argv=0x40800604, init=(factrv32`__libc_csu_init at elf-init.c:69:1), fini=(factrv32`__libc_csu_fini at elf-init.c:97:1), rtld_fini=0x00000000, stack_end=<unavailable>) at libc-start.c:332:16 frame #7: 0x000103d8 factrv32`_start at start.S:61 (lldb) dis factrv32`factorial: 0x1047c <+0>: addi sp, sp, -32 0x1047e <+2>: sw ra, 28(sp) 0x10480 <+4>: sw s0, 24(sp) 0x10482 <+6>: addi s0, sp, 32 0x10484 <+8>: sw a0, -16(s0) -> 0x10488 <+12>: lw a0, -16(s0) 0x1048c <+16>: li a1, 1 0x1048e <+18>: beq a0, a1, 0x10496 0x10492 <+22>: j 0x104a4 0x10496 <+26>: j 0x1049a 0x1049a <+30>: li a0, 1 0x1049c <+32>: sw a0, -12(s0) 0x104a0 <+36>: j 0x104c2 0x104a4 <+40>: lw a0, -16(s0) 0x104a8 <+44>: sw a0, -20(s0) 0x104ac <+48>: addi a0, a0, -1 0x104ae <+50>: jal 0x1047c 0x104b0 <+52>: mv a1, a0 0x104b2 <+54>: lw a0, -20(s0) 0x104b6 <+58>: mul a0, a0, a1 0x104ba <+62>: sw a0, -12(s0) 0x104be <+66>: j 0x104c2 0x104c2 <+70>: lw a0, -12(s0) 0x104c6 <+74>: lw ra, 28(sp) 0x104c8 <+76>: lw s0, 24(sp) 0x104ca <+78>: addi sp, sp, 32 0x104cc <+80>: ret (lldb) c Process 1 resuming Factorial of 10 is 3628800 Process 1 exited with status = 0 (0x00000000) (lldb) Comment Actions I'll answer this first, because it's the easiest! I've done the following:
@jasonmolenda the step plan issue we discussed was actually a disassembler issue, and was fixed by D156086.
Comment Actions
Great. Could you include that in the commit message? Seems like we get a lot of questions about how mature risc-v support is, so we can point to this as a milestone for that. There is https://lldb.llvm.org/#platform-support but there's probably too many caveats to add it there yet. I have some vague idea that maybe we could put a hack in the test suite to use the qemu-user platform instead of lldb-server. To at least give it a go, but I haven't tried it myself yet. Comment Actions Downstream I've got a hack to the qemu-user platform that allows it to be automatically selected for riscv32/64-unknown-linux. I didn't think it would be appropriate upstream. So I can launch lldb with a riscv binary and do a run, and it launches qemu-riscv32/64. I'm planning on running the test suite on upstream + this patch, with that hack, and seeing what happens.
Comment Actions Will do.
Comment Actions In the interests of not being caught by the impeding shutdown at the end of the month, this is where we're at with this: I'm interested in the test suite results, but mostly for context of where this support is at, and not to block this. If it shows up bugs in Could you summarise those results in the commit message too? (x mostly works, y all fail but we expect that, z fails for as yet unknown reasons, etc.) Other than that you have @jasonmolenda 's comment about unwinding. Make sure you're both on the same page there.
Comment Actions @DavidSpickett update on testing: I'm running tests. I found an issue in the IR Interpreter when calling class methods. Somehow a 32 bit pointer gets the upper 32 bits in the 64 bit uint it's stored in set to 0xffffffff, which causes an assert. Downstream we've changed the assert should probably to an error so it doesn't take down the debugger. I can make this change here, but I wonder if it should be a separate change. For now I'm skipping the tests that cause this. Progress is slow, but steady. Comment Actions
Sounds like bitness confusion, so yes it's worth making a patch for that. We don't test that scenario on the build bots but people do do this. Comment Actions Fix crash when there was no process (found by API tests) Comment Actions FYI I will be away next week, and the week after that Phab is supposed to be made read-only. So look to @jasonmolenda to approve in that time frame, or we can take this to a PR after that.
Comment Actions Remove disabling JIT and enabling IR Interpreter function calls, as requested Added default unwind plan as suggested by Jason Molenda. Comment Actions This looks good to me, thanks for reviving this and finishing it up. We should land before phabracator is flash frozen, we can iterate issues are found in the future.
|
clang-format not found in user’s local PATH; not linting file.