[lldb-dev] Adding lldb support for ppc64le

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Wed Aug 16 13:40:22 PDT 2017


I would look at existing code and mimic what other NativeRegisterContextLinux classes do, but the basics are:

1 - you define register information for each register (ID (register index that starts at zero and increases with no gaps), name, alt name, offset, size, type) so that all registers have a single location in a large register context buffer:

ID OFFSET SIZE NAME FORMAT
0  0      8    R0   eFormatHex
1  8      8    R1   eFormatHex
...
32 256    8    FP0  eFormatFloat
33 264    8    FP1  eFormatFloat
...

Note we have GPR registers R0 - R31, and FPR registers FP0-FP31 above in the fake example. Each registers has a unique offset in the buffer. When we read registers, you might end up reading all registers at once with something like PTRACE_GETREGSET below, or one at a time. Up to you. As you read each register, you read it into the register context buffer and cache its value and mark it as read. The buffer will be invalidated when the process resumes and there is a map that says if the data for a register is already in the cache. If so, you can avoid retrieving the register value each time by copying it out of the register context buffer.

So a read typically goes like:

When registers are read as a set:
- check if the register value is valid and already cached in the register context, if so, copy the bytes out and you are done
- read all registers for the register set and copy results into register context buffer at the correct offset, mark all register (GPR, or FPR) as valid
- copy data out of register context buffer for the read

When registers are read individually:
- check if the register value is valid and already cached in the register context, if so, copy the bytes out and you are done
- read one register and copy bytes into register context buffer at the correct offset, mark that register as valid
- copy data out of register context buffer for the read

The code below looks like each time you want a registers you are getting all of the GPRs or FPRs and then copying the data out. No caching. 


2 - define registers sets into a set of register IDs that you defined in step 1:

GPRS = [ 0, 1, ..., 31];
FPRS = [ 32, 33, ..., 63];

3 - Implement the read and write as mentioned above.


There seems to be some smarts built into NativeRegisterContextLinux that you will need to look at the figure out exactly what you need to do, but the best thing is to find an example like ($trunk)/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp and see what it does and how it handles things. So I would copy on of the files in ($trunk)/source/Plugins/Process/Linux (if this is on linux) and change everything so things match up. You will need to find out how ptrace gets the registers as the system usually defines what the GPR and FPR registers sets look like, and then update all register info to match reality.



> On Aug 16, 2017, at 12:39 PM, Alexandre Yukio Yamashita via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Hi,
> 
> I am new to the lldb development and trying to add support for ppc64le.
> Now, I am having some problems to handle the breakpoints.
> In the file /lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:1868, I am not able to get the PC address.
> 
> I created a new file (NativeRegisterContextLinux_ppc64le.cpp), modifying the file /lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp to implement a function to read the register values.
> 
> In the function DoReadRegisterValue (NativeRegisterContextLinux_ppc64le.cpp:856), I am trying to map the PC value using the NIP register. But the NIP is coming with a zero value.
> Does anyone have an idea about why this is happening?
> I am sending the code of the DoReadRegisterValue function below.
> 
> Alexandre.
> 
> ------------------------------------------------------------
> Status NativeRegisterContextLinux_ppc64le::DoReadRegisterValue(
>     uint32_t offset, const char *reg_name, uint32_t size,
>     RegisterValue &value) {
>     Status error;
> 
>     elf_gregset_t regs;
>     int regset = NT_PRSTATUS;
>     struct iovec ioVec;
>     struct pt_regs regs_p;
>     ioVec.iov_base = ®s;
>     ioVec.iov_len = sizeof regs;
> 
>     bool isPc = strcmp(reg_name, "pc") == 0;
>     if (isPc) {
>     error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,
>             m_thread.GetID(), &regset, &regs_p, sizeof regs_p);
>     } else {
>     error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,
>             m_thread.GetID(), &regset, &ioVec, sizeof regs);
>     }
> 
>     if (error.Success()) {
>       ArchSpec arch;
>       if (m_thread.GetProcess()->GetArchitecture(arch))
>     if (isPc) {
>         value.SetBytes(&regs_p.nip, 8, arch.GetByteOrder());
>     } else {
>         value.SetBytes((void *) (((unsigned char *) (regs)) + offset), 8,
>                 arch.GetByteOrder());
>     }
>       else
>         error.SetErrorString("failed to get architecture");
>     }
>   return error;
> }
> 
> -- 
> Alexandre Yukio Yamashita
> Eldorado Research Institute 
> www.eldorado.org.br <http://www.eldorado.org.br/>_______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20170816/a936cdc5/attachment.html>


More information about the lldb-dev mailing list