changing register size on the fly?

Some cores can change register sizes on the fly; for example, the Freescale e6500 can switch between 32 bit and 64 bit mode by writing the CM bit in the MSR. This causes the upper 32 bits of many 64 bit registers to be ignored.

I’m working with a device that has registers that behave like this. I could display the larger size, but that’s confusing to a user who’s working with the smaller size.

Is there a way to change register size on the fly?

Yes. Your RegisterContext subclass needs to override:

    virtual const RegisterInfo *
    GetRegisterInfoAtIndex (size_t reg) = 0;

So you can just return the correct RegisterInfo that contains "4" or "8" as the RegisterInfo.byte_size by grabbing using the m_thread to get to the process and somehow read the MSR and return the correct one dynamically.


Thanks Greg.

My problem is we're using gdb-remote, and aren't subclassing RegisterContext. Any advice?


My advice would be to just always show 64 bits.

Otherwise you will need to define some new methods on GDBRemoteDynamicRegisterInfo or the base class DynamicRegisterInfo that allows you to modify a register info (or maybe just change a register byte size) by specifying the register number and the new info or new byte size.

You would then need a way to, each time you stop, to check the MSR and see if the you need to update your register infos.

One way to implement this efficiently would be to add a special key value pair to all of your stop reply packets something like:


This key/value pair would only exist in your e6500 targets (thus the reverse dot notation to ensure this is the case).

So if we added this to a stop reply packet:

< 280> read packet: $T05thread:32cf86;00:045ace21;...;com.freescale.e6500.msr:01200034;

Then you can add a handler for this special key/value pair in:

ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)

And the handler for this could grab the register context and make the changes if needed based on the value of the MSR. So you check the bit, then get one of the RegisterInfo structs using the register name, check its byte size, and if it isn't set correctly, change all needed registers.

I don't recommend doing this though. Why? Your g/G packet will change size depending on if you are in 32 or 64 bit register mode. If one of your registers is number 0 in the GDB remote protocol, if you send a p/P packet to read/write the register, will it return a 32 bit value if in 32 bit mode and a 64 bit value in 64 bit mode? I hope not. If you do to this change you will need to make sure that the GDBRemoteDynamicRegisterInfo can handle that because I believe it uses the byte size when decoding data from the p/P packets, or the expedited registers in the stop reply packets...

So I would recommend just always showing 64 bits so you can avoid and such potential issues.