[lldb-dev] Accessing physical memory while remote debugging

Zdenek Prikryl via lldb-dev lldb-dev at lists.llvm.org
Mon Jan 7 04:43:27 PST 2019


Hi Daniel, Sanimir,

This feature request is repeating every now and then :-). I think it's 
very useful, but it's not that easy to implement.

Additional comments embedded.

--
Zdenek Prikryl

On 11/28/2018 07:01 PM, Sanimir Agovic via lldb-dev wrote:
> Hi Daniel,
>
>
> On Sat, Nov 24, 2018 at 9:34 PM Daniel Shaulov via lldb-dev 
> <lldb-dev at lists.llvm.org <mailto:lldb-dev at lists.llvm.org>> wrote:
> > The one thing that is really missing is the ability to read/write to 
> physical memory addresses.
> This would indeed be a neat addition to improve debugging bare-metal 
> targets, be it simulator or jtag based e.g. openocd.
> My suggestion is to generalize your idea. Add support/api to access 
> memory in arbitrary address spaces. Accessing physical memory would be 
> just a user of this api. This way lldb could support llvm 
> architectures with multiple address spaces e.g. nvidia cuda and some 
> opencl implementations.
>
>
> > I looked a bit at the gdb protocol and it only supports 'm' and 'M' 
> for reading and writing to virtual memory, and nothing for physical 
> memory.
> >
> > So I suggest we add a new extensions to the gdb protocol:
> > QReadPhysicalMemory - works just like 'm', but with physical memory.
> > QWritePhysicalMemory - works just like 'M', but with physical memory.
> Have a look at the qXfer rsp packets[1] which is used for transferring 
> target objects, a prototype might look like this 
> qXfer:memory:read:annex:tid:offset,length (write is analogue) where 
> annex denotes to an address space identifier, offset and length are 
> obvious.
> Similar to the x/X packet the payload is binary encoded and not hex as 
> in m/M making this new packet a superset of both x and m. I also 
> highly recommend to propagate memory access errors back to the 
> debugger there are plenty of reasons why memory access may fail on an 
> on-chip-debugger. Afaik gdb/rsp supports error messages with the 
> E.errtext notation where errtext is the error message.

Seems fine.

>
> Coming back to tid, it is the thread id. Rsp is a stateful protocol 
> and for certain operations it needs to switch the thread. This avoids 
> switching back and forth and is similar to the lldb extension 
> QThreadSuffixSupported[2].
> Passing a tid is not needed to read memory from a process and it seems 
> rather unusual but for a jtag debugger it is required to correctly 
> translate the virtual address if a mmu is enabled. It is up to the 
> target how to interpret tid.
>
>
> > I am willing to work on adding support for this in lldb and in qemu. 
> In fact, the qemu part was so easy and straightforward, that I already 
> have a branch ready with the change.
> Provide an API similar to llvm to support address spaces. A prototype 
> might look like this: size_t ReadMemory(addr_t addr, void *buf, size_t 
> size, unsigned addr_space, lldb::SBError &error)
> The current ReadMemory would call this new API with addr_space = 0, 
> the default address space.

The last time we discussed this issue we ended with an additional type 
for the address with an address space id (e.g., class AddressBase). The 
reason for it is that you need to propagate the address space id to 
expression evaluation and other parts as well. So, the relation would be 
lldb::addr_t < AddressBase < Address.

The big challenge here is to patch all lldb::addr_t instances that 
represent memory addresses to AddressBase (lldb::addr_t is used for 
non-address data time to time as well). Who's volunteering for it? :-)...

>
>
> > The lldb part is a bit more tricky. At the core, changing 
> ProcessGDBRemote.cpp:2776, writing  "QReadPhysicalMemory" instead of 
> 'm', is enough to change ALL the reads to physical memory. But we 
> don't want that. So we need to add a new flag to 
> CommandObjectMemoryRead, and pass it in CommandObjectMemory.cpp:669, 
> then pass the flag to Process::ReadMemory. Here it gets a bit tricky, 
> since Process::ReadMemory has a cache, so we can't just pass the flag 
> to ReadMemoryFromInferior, we need to have a separate cache for it.
> You need a per addresspace cache.

Correct, caches has to be address space aware (I think there are several 
of them).

>
>
> > 3. I know it's the wrong place to ask, but does anyone know how 
> accepting the qemu community will be with the patch? Have they ever 
> accepted patches aimed at making lldb work better with the gdbstub, or 
> is it strictly for debugging with gdb proper?
> There is no right way but providing tests with your patches, keeping 
> them small and rather independent of each other, and adding 
> documentation is a good start.
>
> To fully support address spaces one needs to interpret the debug 
> information correctly to dispatch the memory access to the right 
> address space and the type system needs to be extended as well. Having 
> a way to query for available address spaces would also be helpful. 
> Keep in mind to extend the lldb commands to expose this feature to the 
> user
> memory read/write --asid <id> | --asid-name <string>
> memory list
> disassemble --asid <id> | --asid-name <string>

That is correct as well.

>
> [1] 
> https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#General-Query-Packets
> [2] 
> https://github.com/llvm-mirror/lldb/blob/master/docs/lldb-gdb-remote.txt
>
>  -Sanimir
> -- 
>  -Sanimir
>
>
> _______________________________________________
> 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/20190107/66b06c32/attachment.html>


More information about the lldb-dev mailing list