clayborg added a comment.

In http://reviews.llvm.org/D16508#338046, @krytarowski wrote:

> 1. I was trying to comment out `DBG` registers (as unsupported by NetBSD) 
> from `RegisterInfos_x86_64.h` with the following patch:
>
> But I get this assert being triggered:
>
>   In file included from 
> /tmp/pkgsrc-tmp/wip/lldb-git/work/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp:59:0:
>   
> /tmp/pkgsrc-tmp/wip/lldb-git/work/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h:271:1:
>  error: static assertion failed: g_register_infos_x86_64 has wrong number of 
> register infos
>    static_assert((sizeof(g_register_infos_x86_64) / 
> sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
>    ^


You usually make a sized array that matches your zero based enumerations for 
your registers. So the number of items in the g_register_infos_x86_64 structure 
should be the same as your zero based register number enumerations. I prefer to 
always make an enum like:

  enum RegisterNumbers
  {
      eGPRRegisterRAX,
      eGPRRegisterRBX,
      eGPRRegisterRCX,
      eGPRRegisterRDX,
      k_num_registers
  };

Then define the RegisterInfo structure as a constant array that sizes itself:

  static RegisterInfo g_register_infos_x86_64[] = {
      ... rax ...,
      ... rbx ...,
      ... rcx ...,
      ... rdx ...,
      ... rsi ...,
  };

Note that if we had this definition, that the assert you had would fire because 
our enumerations in RegisterNumbers has the number of registers as 4, but we 
have 5 in our g_register_infos_x86_64 structure. I do it this way to ensure 
that we don't get our enumeration definition off somehow and then access an 
array item in g_register_infos_x86_64 that is out of bounds.

>   What's the correct approach to address it? Mirror modified 
> `RegisterInfos_x86_64.h` in `RegisterContextNetBSD_x86_64.cpp` and 
> removed/altered `static_assert`?

>   

>   2. I don't understand "marking registers as valid". NetBSD offers 
> `ptrace`(2) call to with a pair of accessors set or get, one for `REG` and 
> the other for `FPREG`.


Somehow you need to track which registers are valid and which aren't. If 
someone asks you to read "rax", you will read all GPR registers. The next time 
someone asks you to read "rbx", if you have already read the GPR registers, you 
can just grab the value from your local structure. The register context will be 
asked to invalidate its registers via the pure virtual function:

  virtual void
  RegisterContext::InvalidateAllRegisters () = 0;

This would make you say "m_gpr_regs_valid = false;" and possible 
"m_fpu_regs_valid = false;" or something inside your register context to track 
which registers are valid. We want to avoid multiple ptrace calls to read all 
registers when they aren't needed. Also, if a registers is written, you will 
need to invalidate these as needed (if reg comes from GPR registers, then mark 
all GPRs as invalid, same for FPU reg). The GDB remote servers sometimes can 
only read single registers, one at a time, so a register context like that 
needs to track the validity of each register individually. So it really depends 
on your register context. So just make sure you correctly track when your 
registers are valid so you can avoid re-reading register sets via ptrace.


Repository:
  rL LLVM

http://reviews.llvm.org/D16508



_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to