This is an archive of the discontinued LLVM Phabricator instance.

[LLDB][RISCV] Add riscv register definition and read/write
ClosedPublic

Authored by Emmmer on Jul 22 2022, 3:15 AM.

Details

Summary

This patch is based on the minimal extract of D128250.

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Refactor some duplicate code, and delete unused register definitions.

Diff Detail

Event Timeline

Emmmer created this revision.Jul 22 2022, 3:15 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 22 2022, 3:15 AM
Emmmer requested review of this revision.Jul 22 2022, 3:15 AM
Emmmer updated this revision to Diff 446766.Jul 22 2022, 3:18 AM
JDevlieghere added inline comments.Jul 22 2022, 1:44 PM
lldb/source/Utility/ArchSpec.cpp
1390–1395 ↗(On Diff #446766)

I don't think this is needed. The case where the two cores are identical is already covered by line 1084. This would be for something like eCore_riscv32 if that were a thing.

Emmmer updated this revision to Diff 447189.Jul 24 2022, 10:51 PM
Emmmer marked an inline comment as done.
DavidSpickett added inline comments.Jul 25 2022, 3:54 AM
lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
1347 ↗(On Diff #447189)

Why is this only needed for PECOFF? (maybe it is the only one that lists them like this)

lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_riscv64.cpp
25

This can be sys/uio.h I'm pretty sure.

I know the other NativeRegisterContexts include socket.h but I'm looking at changing those.

Emmmer updated this revision to Diff 447322.Jul 25 2022, 7:13 AM

Why is this only needed for PECOFF? (maybe it is the only one that lists them like this)

At first, I tracked a bug from LLDBServerTests and thought that GetArchitecture() returned a wrong match, so I added case llvm::COFF::IMAGE_FILE_MACHINE_RISCV64 to the function (there is indeed an IMAGE_FILE_MACHINE_RISCV64 in COFF.h, so I regarded it was a global architecture judgment ).

Later, I found out that HostInfoBase.cpp did not add a match to riscv64, and it ran as expected after adding it.

I forgot to delete it in my local repo, sorry.

Emmmer marked 2 inline comments as done.Jul 25 2022, 7:13 AM

Please note in the commit title/description that this is adding riscv64 only.

Does this build if you don't have the rest of the changes from https://reviews.llvm.org/D128250? Or do you plan to split out more from that and have this depend on those changes.

(thanks for splitting them out though, it is easier to get through!)

Emmmer updated this revision to Diff 447344.Jul 25 2022, 8:02 AM

case llvm::Triple::riscv64: in ArchSpec::CharIsSignedByDefault() is unnecessary as well.

Please note in the commit title/description that this is adding riscv64 only.

Does this build if you don't have the rest of the changes from https://reviews.llvm.org/D128250? Or do you plan to split out more from that and have this depend on those changes.

(thanks for splitting them out though, it is easier to get through!)

I try to split unrelated code as much as possible so that they are easier to check and look cleaner.

Emmmer updated this revision to Diff 451140.Aug 9 2022, 7:29 AM
Emmmer retitled this revision from [LLDB][RISCV] Add Register Info and Context to [LLDB][RISCV] Add register stuff and make breakpoint work.
Emmmer edited the summary of this revision. (Show Details)
Emmmer added a subscriber: tzb99.

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Take RISC-V ebreak instruction as breakpoint trap code, so our breakpoint works as expected now.
  • Refactor some duplicate code.

Further work:

  • RISC-V does not support hardware single stepping yet. A software implementation may come in future PR.
  • Add support for RVC extension (the trap code, etc.).
tzb99 added a comment.Aug 9 2022, 9:05 AM

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Take RISC-V ebreak instruction as breakpoint trap code, so our breakpoint works as expected now.
  • Refactor some duplicate code.

Further work:

  • RISC-V does not support hardware single stepping yet. A software implementation may come in future PR.
  • Add support for RVC extension (the trap code, etc.).

Thank you so much for the contribution! I have few more questions. What is your qemu spec? Is it operated in the user mode or the system mode? In addition, did your cross compilation build using in-tree build or build lldb separately?

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Take RISC-V ebreak instruction as breakpoint trap code, so our breakpoint works as expected now.
  • Refactor some duplicate code.

Further work:

  • RISC-V does not support hardware single stepping yet. A software implementation may come in future PR.
  • Add support for RVC extension (the trap code, etc.).

Thank you so much for the contribution! I have few more questions. What is your qemu spec? Is it operated in the user mode or the system mode? In addition, did your cross compilation build using in-tree build or build lldb separately?

I'm using qemu-system 7.0.0 and in-tree cross build.

tzb99 added a comment.Aug 9 2022, 9:58 PM

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Take RISC-V ebreak instruction as breakpoint trap code, so our breakpoint works as expected now.
  • Refactor some duplicate code.

Further work:

  • RISC-V does not support hardware single stepping yet. A software implementation may come in future PR.
  • Add support for RVC extension (the trap code, etc.).

Thank you so much for the contribution! I have few more questions. What is your qemu spec? Is it operated in the user mode or the system mode? In addition, did your cross compilation build using in-tree build or build lldb separately?

I'm using qemu-system 7.0.0 and in-tree cross build.

I am sorry to bother you again, is the dwarf header file changed since the last diff? I noticed the title of the file is changed, and based on the observation, such change should be related to the RISCV64_DWARF_Registers.h file? Directly using the file from last diff will not compile, so I rearrange the file with dwarf_gpr naming convention, but seems like the functionality is not complete.

lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h
18

Do you change the name of it since last diff?

What is implemented:

  • Use the same register layout as Linux kernel and mock read/write for x0 register (the always zero register).
  • Take RISC-V ebreak instruction as breakpoint trap code, so our breakpoint works as expected now.
  • Refactor some duplicate code.

Further work:

  • RISC-V does not support hardware single stepping yet. A software implementation may come in future PR.
  • Add support for RVC extension (the trap code, etc.).

Thank you so much for the contribution! I have few more questions. What is your qemu spec? Is it operated in the user mode or the system mode? In addition, did your cross compilation build using in-tree build or build lldb separately?

I'm using qemu-system 7.0.0 and in-tree cross build.

I am sorry to bother you again, is the dwarf header file changed since the last diff? I noticed the title of the file is changed, and based on the observation, such change should be related to the RISCV64_DWARF_Registers.h file? Directly using the file from last diff will not compile, so I rearrange the file with dwarf_gpr naming convention, but seems like the functionality is not complete.

RISCV64_DWARF_Registers.h has been merged to main in D130686, you may need rebase from main

Can "and make breakpoint work" be made into its own patch? I'd much rather see "register read and write" and "software breakpoints" in their own changes (and please differentiate in commit title/messages between hardware break and software break).

(otherwise the content seems fine just some comments on names and formatting)

lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h
50

clang-format will align these to the left. So I suggest adding "// clang-format off" to disable that and go with the "clang-format on" below. Then indent them as if they were normal code.

131

I check the arm64 file and it also had an orphaned "on". I fixed that in https://github.com/llvm/llvm-project/commit/552dccf311c6134c6c895328602172821e3efaed.

See comment above.

lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h
20 ↗(On Diff #451140)

We want to keep the "riscv" tag here. It provides a sort of namespace for the enumerator otherwise overlapping names in different anonymous enums is an error.

https://godbolt.org/z/1W8P1z83T

E.g. if arm64 just used "gpr_x0" we'd get an error, so it uses "gpr_x0_arm64" to prevent that.

94 ↗(On Diff #451140)

Why did the vector registers get removed?

Emmmer updated this revision to Diff 451441.Aug 10 2022, 6:48 AM
Emmmer retitled this revision from [LLDB][RISCV] Add register stuff and make breakpoint work to [LLDB][RISCV] Add riscv register stuff.
Emmmer edited the summary of this revision. (Show Details)

Address review comments:

  • Split the software breakpoint as a separate PR.
  • Add _riscv suffix to register enums

About vector registers:

  • Deleted as they are unused in current codebase, we can add them back if required in the future.
Emmmer updated this revision to Diff 451442.Aug 10 2022, 6:52 AM
Emmmer marked an inline comment as done.
Emmmer marked 3 inline comments as done.
DavidSpickett accepted this revision.Aug 10 2022, 9:09 AM

we can add them back if required in the future.

Sounds good to me. Certainly SVE for Arm required a bunch of changes, a lot easier to do it later.

This LGTM, but:

[LLDB][RISCV] Add riscv register stuff

Can we have something more specific than "stuff" :) (not that I don't use vague terms sometimes) "Add RISCV register information" ?

Just thinking that if I was a riscv user and I was looking at lldb logs I'd want to know "what did this commit enable", what works now that didn't before? And "stuff" doesn't help me there. "information" at least doesn't commit to enabling any new functionality.

This revision is now accepted and ready to land.Aug 10 2022, 9:09 AM
Emmmer retitled this revision from [LLDB][RISCV] Add riscv register stuff to [LLDB][RISCV] Add riscv register information.Aug 10 2022, 11:05 PM
Emmmer retitled this revision from [LLDB][RISCV] Add riscv register information to [LLDB][RISCV] Add riscv register definition and read/write.Aug 10 2022, 11:22 PM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Aug 11 2022, 3:57 AM

This breaks building on windows: http://45.33.8.238/win/64255/step_4.txt

Please take a look and revert for now if it takes a while to fix.

This breaks building on windows: http://45.33.8.238/win/64255/step_4.txt

Please take a look and revert for now if it takes a while to fix.

Yes. This is probably because we don't have a CI configured to enable riscv target.
It should be a simple fix and it is coming, don't worry :)

This breaks building on windows: http://45.33.8.238/win/64255/step_4.txt

Please take a look and revert for now if it takes a while to fix.

Should be fixed after D131667

DavidSpickett added a comment.EditedAug 11 2022, 5:51 AM

The error appears to be:

../../lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h(67,5): error: constant expression evaluates to -1 which cannot be narrowed to type 'uint32_t' (aka 'unsigned int') [-Wc++11-narrowing]
    DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC),

So I'm not sure that patch will fix everything but let's see.