This is an archive of the discontinued LLVM Phabricator instance.

[RISC-V] Add RISC-V ABI plugin
ClosedPublic

Authored by ted on Aug 29 2023, 7:57 AM.

Details

Summary

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

Diff Detail

Event Timeline

ted created this revision.Aug 29 2023, 7:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2023, 7:57 AM
ted requested review of this revision.Aug 29 2023, 7:57 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2023, 7:57 AM
DavidSpickett added a subscriber: DavidSpickett.

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.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
12

In general most of these include comments you can remove, but this one in particular because there are no C includes.

We don't have a rule that states you comment each block, clang-format may re-order them but that's it.

108

What's the reason to do this this way? It seems like adding an extra argument to the constructor of ABISysV_riscv would do the same thing unless someone is calling the constructor directly but that's what CreateInstance tries to prevent.

I see that mips has 2 ABI plugins, and MacOS on x86 has i386 and x86_64. The former I don't think has massive differences between 32 and 64 but the latter does.

So I agree with sharing the ABI here between riscv32 and riscv64 just with the way it's implemented.

If it's because you use an array later, either make it a vector or better an llvm::SmallVector which for rv32 will likely just use stack space for 4 byte stuff.

146

Looking at the comments in lldb/include/lldb/Target/ABI.h I'm not sure which of these should be implemented. I think this one is what most plugins provide.

One way to figure this out is to figure out what actually needs this. Return false from both and try a bunch of things to see if it fails, run an expression, step in and out etc.

I'd be more comfortable having one not implemented if we know how the other one gets used.

218

If, as I think, this and the bit below are just memcpy and memset, just use those and make it obvious.

222

Add a comment here like "// Pad if the type's size is smaller than the register.".

311

I see this came from Arc which appears to be 32 bit, so this needs to change for rv64?

If it doesn't, add comments above to note where rv64 would exit before getting here.

393

I'm not sure, but perhaps switch (byte_size) removing one level of if/else would make this whole thing more clear.

409

No need for else after a return.

463
return GetValObjFromIntRegs(thread, reg_ctx, machine, type_flags, byte_size);
468

In general don't use this order for comparisons, it's harder to understand as a reader. byte_size <= 4 is easier.

483

Blank line between this and the switch above it.

493

use_fp_regs is a bool so if (use_fp_regs) the else is always taken if false, so you don't need else here. Simply:

if ( ...) {
}

// implicit else
return ...;

Unless you want to do:

if (...) {
   return_valobj_sp = ...
} else
   return_valobj_sp = ...

return return_valobj_sp;

Either is fine.

541

Once more for emphasis, please reverse the order of comparisons like this.

702

Please clang format all the changes. The easiest way is to use https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting, git diff -U0 --no-color --relative HEAD^ | clang-format-diff.py -p1 -i.

706

Looks like plain iteration would do the job, no use for the index here.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
80–81

Combine this into one if.

lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
1554

You might want to take the lead from AArch64 here:

// If any AArch64 variant, enable latest ISA with all extensions.

If "+all" doesn't already work for riscv then you don't have to go and make that work right now.

But in general we decided that much like llvm-objdump, we'll try to disassemble any possible encoding. If the user happens to point the disassembler at garbage that looks like a fancy extension on a cpu from 20 years ago, that's on them.

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.

ted added a subscriber: labath.Aug 29 2023, 11:30 AM

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)
ted added a comment.EditedAug 29 2023, 12:56 PM

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.

I'll answer this first, because it's the easiest!

I've done the following:

  • Run 32 and 64 bit Linux binaries, launched on user space riscv32 and riscv64 QEMU, using the QemuUser platform.
  • Hit a breakpoint
  • Continue
  • Step in, step over, step out, instruction step in, instruction step out, including stepping all the way down and back up a 10 level recursive call
  • Looked at a backtrace
  • Looked at variables with frame variable
  • Looked at and modified variables with the expression parser
  • Read and writte memory
  • Disassembly

@jasonmolenda the step plan issue we discussed was actually a disassembler issue, and was fixed by D156086.

ted marked 13 inline comments as done.Aug 29 2023, 2:50 PM
ted added inline comments.
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
108

I copied this from the ARC ABI plugin.

word_size and reg_size are used in computations, in PrepareTrivialCall and SetReturnValueObject.

146

The first one is used for calling functions via JIT. The second is used for calling functions via the IR Interpreter. I didn't want to enable JIT, so I took the Hexagon implementation (Hexagon doesn't support JIT in lldb, but can call functions with the IR interpreter) and reworked it for RISC-V.

Here's a function call on riscv64:
(lldb) re r pc

pc = 0x00000000000106b2 factrv64`main + 28 at factorial.c:32:8  factrv64`main + 28 at factorial.c:32:8

(lldb) p factorial(3)
(int) 6

311

Yes - on rv64, a 128 bit scalar can be passed in ARG1 and ARG2. Get the next chunk of data from data and write that.

lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
1554

While I like the "turn on the latest" philosophy in general, for RISC-V we don't want to do that. It's modular architecture means features can be turned on and off when a core is designed, so one core might have +d (floating point double), while an newer core might not have any floating point at all. I'm inclined to leave the features as they are now, with a and m turned on.

ted added a reviewer: apazos.Aug 29 2023, 3:02 PM
ted marked an inline comment as done.
ted updated this revision to Diff 554505.Aug 29 2023, 3:05 PM

Updated with David Spickett's comments

ted marked an inline comment as done.Aug 29 2023, 3:07 PM
jasonmolenda added inline comments.Aug 29 2023, 3:15 PM
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
108

I'd prefer that the CreateInstance method initialize an ivar with the word size based on the passed-in ArchSpec, or save the ArchSpec in an ivar. risc-v seems to have many variants so I worry about saving the full ArchSpec when ABI::CreateInstance is being called, possibly where we might not have the most specific ArchSpec for this process? But 32-bit v. 64-bit will surely be constant. When I was reading the patch later I'd see references to reg_size and scratch my head where that variable was coming from.

This static will not work correctly if you have an lldb connected to an rv32 target and an rv64 target simultaneously.

Didn't the earlier ABI have a isRV64 ivar (should have been m_is_rv64 but whatever) to solve this?

639

We were emailing a couple of months ago and I think I suggested something like this, based on the previous ABI patch

bool ABISysV_riscv::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
  unwind_plan.Clear();
  unwind_plan.SetRegisterKind(eRegisterKindGeneric);

  uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
  uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;

  UnwindPlan::RowSP row(new UnwindPlan::Row);

  // Define the CFA as the current frame pointer value.
  row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 0);
  row->SetOffset(0);

  int ptr_size = 4;
  if (isRV64)
    ptr_size = 8;

  // Assume the ra reg (return pc) and caller's frame pointer 
  // have been spilled to stack already.
  row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
  row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);

  unwind_plan.AppendRow(row);
  unwind_plan.SetSourceName("riscv default unwind plan");
  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
  unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
  return true;
}
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
80–81

Maybe more clear like

if (arch_flags | ArchSpec::eRISCV_rvc && pc & 2) 
  return false;

It's too bad ArchSpec doesn't have a Flags() method which returns a Flags object, so this could be if (arch.Flags().Test(ArchSpec::eRISCV_rvc) && pc & 2).

Suppose it would be just as easy to do

Flags arch_flags(arch.GetFlags();
if (arch_flags.Test(ArchSpec::eRISCV_rvc) && pc & 2)
  return false;
DavidSpickett added inline comments.Aug 30 2023, 1:40 AM
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
146

Ok cool, as long as one of us knows what these do :)

The other way to kinda chaos engineer this is to take your host's target, make a function fail and see what parts of the test suite fail. Then that can tell you what to test manually for riscv's version of the same functions.

lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
1554

Fair enough, I see that +all does not in fact work for risc-v llvm-objdump which backs that up. I guess you'd have to pass through some kind of object attributes to detect some of them.

I've done the following:

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.

ted added a comment.Aug 30 2023, 2:58 PM

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.

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.

kito-cheng added inline comments.Aug 30 2023, 6:53 PM
lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
1554

RISC-V have ELF attribute* to record which arch used for this binary, so you may need to add something at lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp to read that and record something in ArchSpec like what ObjectFileELF::ParseARMAttributes do.

ted added a comment.Aug 31 2023, 12:19 PM

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.

Will do.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
108

This is a very good point - debugging both rv32 and rv64 programs at the same time could give incorrect results. I think setting an ivar with 32-bit vs 64-bit in CreateInstance, and setting local variables based on that is a good idea.

639

The RISC-V ABI says the frame pointer is optional, and I haven't found a way to tell if the FP (register s0) is being used as an FP, or if it's a generic callee-saved register.

Debugging an rv32 program that doesn't use the FP works with the current CreateDefaultUnwindPlan. I can step in, step over, step out and get a backtrace. Is there anything else I need to test?

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
80–81

I like this idea.

Adding a Flags() method to ArchSpec is simple:

#include "lldb/Utility/Flags.h"

Flags Flags() const { return lldb_private::Flags(m_flags); }

Do you think I should add that to this diff? Or I could go with your alternative:

Flags arch_flags(arch.GetFlags();
if (arch_flags.Test(ArchSpec::eRISCV_rvc) && pc & 2)

return false;

What do you think?

lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
1554

The ArchSpec flags come from the ELF attributes. Unfortunately they don't have everything we need, specifically attributes for the "A" (atomic instructions) and "M" (integer multiplication and division) extensions, but I think pretty much everyone will have those, so having them always on is OK.

ted updated this revision to Diff 555155.Aug 31 2023, 1:25 PM
ted marked an inline comment as done.

Implement Jason Molenda's request to use an ivar instead of static variables.

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
anything that's fully implemented here then of course fix them. If there are large parts that still fail for other reasons, I think those should
be dealt with in follow up patches (it's going to be cleaner that way anyway).

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.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
157

Nit: you could just say word_size = reg_size.

The separate names is fine since it helps to explain the calculation below, so keep those.

204

word_size = reg_size; ?

ted added a comment.EditedSep 12 2023, 6:22 AM

@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.

I can make this change here, but I wonder if it should be a separate change.

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.

pierce added a subscriber: pierce.Sep 18 2023, 6:29 AM
ted updated this revision to Diff 557049.EditedSep 19 2023, 8:31 AM

Fix crash when there was no process (found by API tests)
Remove bugs in function call setup when using IR interpreter (found by API tests)
Change flag tests to use lldb_private::Flags (requested by @jasonmolenda )

DavidSpickett added inline comments.Sep 19 2023, 8:39 AM
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
204

This.

262

Seems like are got split up here.

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.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
133

Do you know why this check is needed? Is there a specific test that hits this?

The other ABI plugins seem to sidestep this by not having to -> on it, but that could just be luck.

jasonmolenda added inline comments.Sep 19 2023, 4:35 PM
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
135

These should not be set in the ABI, please remove these. These are probably correct for the qemu environment you're testing against, but if we're connected to a remote stub that can allocate memory (_M packet), we can JIT code.

en-sc added a subscriber: en-sc.Sep 20 2023, 4:01 AM
ted added inline comments.Sep 21 2023, 9:17 AM
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
133

Without that check, certain tests crashed when they instantiated the ABI plugin without a process.

135

I can remove these, but for the current environment they're correct. We don't have function calling for JIT, or RuntimeDyld set up for RISC-V.

ted updated this revision to Diff 557321.Sep 25 2023, 1:21 PM

Remove disabling JIT and enabling IR Interpreter function calls, as requested
by Jason Molenda.

Added default unwind plan as suggested by Jason Molenda.

ted updated this revision to Diff 557322.Sep 25 2023, 1:24 PM
ted marked 3 inline comments as done.

Change "word_size = m_is_rv64 ? 8 : 4" to "word_size = reg_size"

ted marked 3 inline comments as done.Sep 25 2023, 1:25 PM
ted updated this revision to Diff 557323.Sep 25 2023, 1:27 PM
ted marked 4 inline comments as done.

Fix comment about "a" registers

jasonmolenda accepted this revision.Sep 26 2023, 4:37 PM

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.

lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
14

I don't see this used anywhere.

This revision is now accepted and ready to land.Sep 26 2023, 4:37 PM
This revision was landed with ongoing or failed builds.Sep 29 2023, 8:31 AM
This revision was automatically updated to reflect the committed changes.