<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I would look at existing code and mimic what other NativeRegisterContextLinux classes do, but the basics are:<div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">ID OFFSET SIZE NAME FORMAT</div><div class="">0  0      8    R0   eFormatHex</div><div class="">1  8      8    R1   eFormatHex</div><div class="">...</div><div class="">32 256    8    FP0  eFormatFloat</div><div class="">33 264    8    FP1  eFormatFloat</div><div class="">...</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">So a read typically goes like:</div><div class=""><br class=""></div><div class="">When registers are read as a set:</div><div class="">- check if the register value is valid and already cached in the register context, if so, copy the bytes out and you are done</div><div class="">- 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</div><div class="">- copy data out of register context buffer for the read</div><div class=""><br class=""></div><div class="">When registers are read individually:</div><div class=""><div class="">- check if the register value is valid and already cached in the register context, if so, copy the bytes out and you are done</div><div class="">- read one register and copy bytes into register context buffer at the correct offset, mark that register as valid</div><div class="">- copy data out of register context buffer for the read</div></div><div class=""><br class=""></div><div class="">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. </div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">2 - define registers sets into a set of register IDs that you defined in step 1:</div><div class=""><br class=""></div><div class="">GPRS = [ 0, 1, ..., 31];</div><div class="">FPRS = [ 32, 33, ..., 63];</div><div class=""><br class=""></div><div class="">3 - Implement the read and write as mentioned above.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div class=""><div><blockquote type="cite" class=""><div class="">On Aug 16, 2017, at 12:39 PM, Alexandre Yukio Yamashita via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" class="">lldb-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">

<div text="#000000" bgcolor="#FFFFFF" class=""><p class="">Hi,<br class="">
<br class="">
I am new to the lldb development and trying to add support for ppc64le.<br class="">
</p><p class="">Now, I am having some problems to handle the breakpoints.<br class="">
In the file /lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:1868, I am not able to get the PC address.<br class="">
<br class="">
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.</p><p class="">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.<br class="">
Does anyone have an idea about why this is happening?<br class="">
I am sending the code of the DoReadRegisterValue function below.</p><p class="">Alexandre.<br class="">
<br class="">
------------------------------------------------------------<br class="">
Status NativeRegisterContextLinux_ppc64le::DoReadRegisterValue(<br class="">
    uint32_t offset, const char *reg_name, uint32_t size,<br class="">
    RegisterValue &value) {<br class="">
    Status error;<br class="">
<br class="">
    elf_gregset_t regs;<br class="">
    int regset = NT_PRSTATUS;<br class="">
    struct iovec ioVec;<br class="">
    struct pt_regs regs_p;<br class="">
    ioVec.iov_base = &regs;<br class="">
    ioVec.iov_len = sizeof regs;<br class="">
<br class="">
    bool isPc = strcmp(reg_name, "pc") == 0;<br class="">
    if (isPc) {<br class="">
    error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,<br class="">
            m_thread.GetID(), &regset, &regs_p, sizeof regs_p);<br class="">
    } else {<br class="">
    error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET,<br class="">
            m_thread.GetID(), &regset, &ioVec, sizeof regs);<br class="">
    }<br class="">
<br class="">
    if (error.Success()) {<br class="">
      ArchSpec arch;<br class="">
      if (m_thread.GetProcess()->GetArchitecture(arch))<br class="">
    if (isPc) {<br class="">
        value.SetBytes(&regs_p.nip, 8, arch.GetByteOrder());<br class="">
    } else {<br class="">
        value.SetBytes((void *) (((unsigned char *) (regs)) + offset), 8,<br class="">
                arch.GetByteOrder());<br class="">
    }<br class="">
      else<br class="">
        error.SetErrorString("failed to get architecture");<br class="">
    }<br class="">
  return error;<br class="">
}</p>
-- <br class="">
<div class="moz-signature">Alexandre Yukio Yamashita<br class="">
Eldorado Research Institute <br class="">
<a href="http://www.eldorado.org.br/" title="Eldorado" class="">www.eldorado.org.br</a></div>
</div>

_______________________________________________<br class="">lldb-dev mailing list<br class=""><a href="mailto:lldb-dev@lists.llvm.org" class="">lldb-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev<br class=""></div></blockquote></div><br class=""></div></div></body></html>