Target and platform clarification request

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

When I invoke platform list I see:

(lldb) platform list
Available platforms:
host: Local Linux user platform plug-in.
remote-freebsd: Remote FreeBSD user platform plug-in.
remote-linux: Remote Linux user platform plug-in.
remote-windows: Remote Windows user platform plug-in.
remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport.

So I wondered why my target doesn't report remote-gdb-server as it's target. Should it?

Could someone clarify what this concept of platform means? I understand the concept of the host as being the Machine/OS where the debugger user is worked at, and the target as being the "thing being debugged", which could be co-located on the host (in either a 32-bit or 64-bit form) or remotely located, in particular for an embedded device, but where does the idea of the platform fit in?

all help appreciated,
Matthew Gardiner

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

No, you really should add a new platform that claims "kalimba-csr-unknown" as its architecture.

When I invoke platform list I see:

(lldb) platform list
Available platforms:
host: Local Linux user platform plug-in.
remote-freebsd: Remote FreeBSD user platform plug-in.
remote-linux: Remote Linux user platform plug-in.
remote-windows: Remote Windows user platform plug-in.
remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport.

So I wondered why my target doesn't report remote-gdb-server as it's target. Should it?

No, not unless you implement a lldb-platform style platform for "kalimba-csr-unknown". The current lldb-platform speaks the GDB remote protocol, but adds new packets.

Could someone clarify what this concept of platform means? I understand the concept of the host as being the Machine/OS where the debugger user is worked at, and the target as being the "thing being debugged", which could be co-located on the host (in either a 32-bit or 64-bit form) or remotely located, in particular for an embedded device, but where does the idea of the platform fit in?

Platforms do the following:
1 - Resolve executables (you might say "target create ls" and your platform could say "oh, 'ls' is in /usr/local/kalimba/root/bin/ls)
2 - Give a list of supported architectures ("kalimba-csr-unknown" for your platform)
3 - Find local copies of a binary when remote debugging and the dynamic loader gives a list of shared libraries your binary is linking against (for iOS, the "remote-ios" can resolve "/usr/lib/dyld" to be "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/lib/dyld")
4 - Find debug symbols for your binaries (they might be cached in your development kit folder)
5 - List processes that can be attached to (try "platform process list" after launching LLDB)
6 - Attach to a process from #5
7 - Launch a new process
8 - upload/download files
9 - install executables

So many of these things (1 - 4) can be done without being connected to the remote platform (the lldb_private::Platform subclass for your architecture can do these things locally on the current machine without being connected to the remote platform. But many (5 - 9) require being attached.

If you write a platform that recognizes "kalimba-csr-unknown", you can say:

(lldb) file /path/to/kalimba/a.out

And it will query all installed platforms and see if any claim the current architecture. If you made "PlatformKalimba", your platform be matched up with the binary since #2 from above in your platform would return "kalimba-csr-unknown", and your platform would automatically be selected.

The way the "remote-gdb-server" is currently used it by other platforms (like PlatformPOSIX) have a shared pointer to a platform as a member variable:

    lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS

And this platform can implement items 5-9, while the local subclass "PlatformKalimba" can take care of doing the specific local file system kinds of things (locating all development kits for Kalimba on the current host, finding all things you have debug symbols for, resolve executables, etc). When you then connect to your platform:

(lldb) platform connect <url>

Then your "PlatformKalimba" would then create a connection to a remote lldb-platform (which is a GDB remote protocol based platform) if you ever require the ability to do the steps 5-9 above. Otherwise, the platform is still useful for locating local copies of your executables.

Let me know if you have anymore questions.

Greg

Greg Clayton wrote:

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

No, you really should add a new platform that claims "kalimba-csr-unknown" as its architecture.

Right, thanks. Am I correct to assume that I'll need to add kalimba (architecture) and CSR (vendor) to llvm::Triple to really get this plan to take-off?

And would this implementation of the PlatformKalimba reside solely within lldb? I'm asking since I see that we have a command tool called lldb-platform. (Does this fit into to my world of custom platforms for embedded targets?).

When I invoke platform list I see:

(lldb) platform list
Available platforms:
host: Local Linux user platform plug-in.
remote-freebsd: Remote FreeBSD user platform plug-in.
remote-linux: Remote Linux user platform plug-in.
remote-windows: Remote Windows user platform plug-in.
remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport.

So I wondered why my target doesn't report remote-gdb-server as it's target. Should it?

No, not unless you implement a lldb-platform style platform for "kalimba-csr-unknown". The current lldb-platform speaks the GDB remote protocol, but adds new packets.

Could someone clarify what this concept of platform means? I understand the concept of the host as being the Machine/OS where the debugger user is worked at, and the target as being the "thing being debugged", which could be co-located on the host (in either a 32-bit or 64-bit form) or remotely located, in particular for an embedded device, but where does the idea of the platform fit in?

Platforms do the following:
1 - Resolve executables (you might say "target create ls" and your platform could say "oh, 'ls' is in /usr/local/kalimba/root/bin/ls)
2 - Give a list of supported architectures ("kalimba-csr-unknown" for your platform)
3 - Find local copies of a binary when remote debugging and the dynamic loader gives a list of shared libraries your binary is linking against (for iOS, the "remote-ios" can resolve "/usr/lib/dyld" to be "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/lib/dyld")
4 - Find debug symbols for your binaries (they might be cached in your development kit folder)
5 - List processes that can be attached to (try "platform process list" after launching LLDB)
6 - Attach to a process from #5
7 - Launch a new process
8 - upload/download files
9 - install executables

Thanks for this. I guess some of these actions can't really be mapped into CSRs current embedded scenarios, since they have no OS or filesystem. (Basically the instruction code is copied into the chip's ROM/RAM/FLASH/whatever, and when the device is reset, the processor understands which device/address to start to fetch from).

However some of these actions are applicable, and indeed useful. Our current debugger has a poor way of mapping different ELFs to a particular context - we only really support having just one (or zero) ELFs for any particular running core - so option 4. may be of benefit. 5. and 6. are also relevant, although we don't have the real processes, the concept of Process 1 in an unattached/attached-running/attached-stopped state would be useful.

If you write a platform that recognizes "kalimba-csr-unknown", you can say:

(lldb) file /path/to/kalimba/a.out

And it will query all installed platforms and see if any claim the current architecture. If you made "PlatformKalimba", your platform be matched up with the binary since #2 from above in your platform would return "kalimba-csr-unknown", and your platform would automatically be selected.

Yep, understood. Presumably to support this effort I'll need to augment the ArchType and VendorType enumerations of llvm::Triple and the relevant parseXXX:: and getXXXName:: functions, as I referred to above.

The way the "remote-gdb-server" is currently used it by other platforms (like PlatformPOSIX) have a shared pointer to a platform as a member variable:

     lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS

And this platform can implement items 5-9, while the local subclass "PlatformKalimba" can take care of doing the specific local file system kinds of things (locating all development kits for Kalimba on the current host, finding all things you have debug symbols for, resolve executables, etc). When you then connect to your platform:

(lldb) platform connect <url>

Then your "PlatformKalimba" would then create a connection to a remote lldb-platform (which is a GDB remote protocol based platform) if you ever require the ability to do the steps 5-9 above. Otherwise, the platform is still useful for locating local copies of your executables.

Oh, I see, we have a notion of the local and remote platforms when working with embedded debug.

thanks for this help, Greg, it is somewhat clearer now.

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Greg Clayton wrote:

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

No, you really should add a new platform that claims "kalimba-csr-unknown" as its architecture.

Right, thanks. Am I correct to assume that I'll need to add kalimba (architecture) and CSR (vendor) to llvm::Triple to really get this plan to take-off?

If you want expression parsing and for us to be able to make types using Clang ASTs it is going to require that you hook up your architecture within LLVM and Clang. Otherwise we won't be able to make a clang target so that we can covert the DWARF debug info into Clang ASTs.

And would this implementation of the PlatformKalimba reside solely within lldb?

Yes it would be in the core of lldb.

I'm asking since I see that we have a command tool called lldb-platform.

This tool links against the core of lldb, not the public API, but the core, so the PlatformKalimba would be available in lldb-platform as well.

(Does this fit into to my world of custom platforms for embedded targets?).

When I invoke platform list I see:

(lldb) platform list
Available platforms:
host: Local Linux user platform plug-in.
remote-freebsd: Remote FreeBSD user platform plug-in.
remote-linux: Remote Linux user platform plug-in.
remote-windows: Remote Windows user platform plug-in.
remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport.

So I wondered why my target doesn't report remote-gdb-server as it's target. Should it?

No, not unless you implement a lldb-platform style platform for "kalimba-csr-unknown". The current lldb-platform speaks the GDB remote protocol, but adds new packets.

Could someone clarify what this concept of platform means? I understand the concept of the host as being the Machine/OS where the debugger user is worked at, and the target as being the "thing being debugged", which could be co-located on the host (in either a 32-bit or 64-bit form) or remotely located, in particular for an embedded device, but where does the idea of the platform fit in?

Platforms do the following:
1 - Resolve executables (you might say "target create ls" and your platform could say "oh, 'ls' is in /usr/local/kalimba/root/bin/ls)
2 - Give a list of supported architectures ("kalimba-csr-unknown" for your platform)
3 - Find local copies of a binary when remote debugging and the dynamic loader gives a list of shared libraries your binary is linking against (for iOS, the "remote-ios" can resolve "/usr/lib/dyld" to be "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/usr/lib/dyld")
4 - Find debug symbols for your binaries (they might be cached in your development kit folder)
5 - List processes that can be attached to (try "platform process list" after launching LLDB)
6 - Attach to a process from #5
7 - Launch a new process
8 - upload/download files
9 - install executables

Thanks for this. I guess some of these actions can't really be mapped into CSRs current embedded scenarios, since they have no OS or filesystem. (Basically the instruction code is copied into the chip's ROM/RAM/FLASH/whatever, and when the device is reset, the processor understands which device/address to start to fetch from).

We can also modify the lldb_private::Platform to state it is a bare board somehow and add bareboard functionality to the platforms. Let us know what you would want from a bare board Platform and we can get this included. Often times with JTAG style debugging, the software that talks to the JTAG can often enumerate the core groups you can attach to and each core can be a separate architecture. In these scenarios the following mappings would hold true:
- different core groups would map to the equivalent of processes
- a group of cores would be represented by lldb_private::Process which a lldb_private::Thread representing a single core in the group (all cores must have same architecture)

Then you could attach to your platform and currently do:

(lldb) platform process list
PID PARENT USER ARCH NAME
====== ====== ========== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)

Then you could do:

(lldb) platform process attach --pid 1
(lldb) platform process attach --pid 2

We would add functionality to the platform like:

(lldb) platform bareboard list
Core ARCH Description
====== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)
(lldb) platform bareboard attach 1

Again, we can make the platform all we need it to be so we can make LLDB a great embedded debugger.

However some of these actions are applicable, and indeed useful. Our current debugger has a poor way of mapping different ELFs to a particular context - we only really support having just one (or zero) ELFs for any particular running core - so option 4. may be of benefit. 5. and 6. are also relevant, although we don't have the real processes, the concept of Process 1 in an unattached/attached-running/attached-stopped state would be useful.

again, see the above mapping of "processes" to "core groups" and see if that makes more sense.

If you write a platform that recognizes "kalimba-csr-unknown", you can say:

(lldb) file /path/to/kalimba/a.out

And it will query all installed platforms and see if any claim the current architecture. If you made "PlatformKalimba", your platform be matched up with the binary since #2 from above in your platform would return "kalimba-csr-unknown", and your platform would automatically be selected.

Yep, understood. Presumably to support this effort I'll need to augment the ArchType and VendorType enumerations of llvm::Triple and the relevant parseXXX:: and getXXXName:: functions, as I referred to above.

Yes, full clang support is actually required so we can make a clang Target and clang AST so we can represent your types and do expression evaluation. I was assuming this was already done, but this is a large amount of work if it isn't. Unless you can use another architecture that clang already supports, but that would be a large hack.

The way the "remote-gdb-server" is currently used it by other platforms (like PlatformPOSIX) have a shared pointer to a platform as a member variable:

    lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS

And this platform can implement items 5-9, while the local subclass "PlatformKalimba" can take care of doing the specific local file system kinds of things (locating all development kits for Kalimba on the current host, finding all things you have debug symbols for, resolve executables, etc). When you then connect to your platform:

(lldb) platform connect <url>

Then your "PlatformKalimba" would then create a connection to a remote lldb-platform (which is a GDB remote protocol based platform) if you ever require the ability to do the steps 5-9 above. Otherwise, the platform is still useful for locating local copies of your executables.

Oh, I see, we have a notion of the local and remote platforms when working with embedded debug.

thanks for this help, Greg, it is somewhat clearer now.

Let me know if you have any more questions.

Greg

Greg Clayton wrote:

Greg Clayton wrote:

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

No, you really should add a new platform that claims "kalimba-csr-unknown" as its architecture.

Right, thanks. Am I correct to assume that I'll need to add kalimba (architecture) and CSR (vendor) to llvm::Triple to really get this plan to take-off?

If you want expression parsing and for us to be able to make types using Clang ASTs it is going to require that you hook up your architecture within LLVM and Clang. Otherwise we won't be able to make a clang target so that we can covert the DWARF debug info into Clang ASTs.

Yes, sure. We at CSR are in the process of getting someone aboard to work on an LLVM backend for our Kalimbas. We are slowly changing bits of our existing toolchain (e.g. with an official EM_MACHINE number + an ELF notes section) to see how far we can get (before the LLVM backend) with an lldb port.

We can also modify the lldb_private::Platform to state it is a bare board somehow and add bareboard functionality to the platforms. Let us know what you would want from a bare board Platform and we can get this included. Often times with JTAG style debugging, the software that talks to the JTAG can often enumerate the core groups you can attach to and each core can be a separate architecture. In these scenarios the following mappings would hold true:
- different core groups would map to the equivalent of processes
- a group of cores would be represented by lldb_private::Process which a lldb_private::Thread representing a single core in the group (all cores must have same architecture)

As I mentioned offline to you and Todd, we have proprietary USB/SPI connections to our chips. So one host PC may be connected to several boards (each with a CSR chip) with one USB connection per board. Furthermore each chip may have several cores which may or may not share architectures (Kalimba, ARM, 8051-clone etc.). And yes I think we need to (currently) map a core to a process.

Then you could attach to your platform and currently do:

(lldb) platform process list
PID PARENT USER ARCH NAME
====== ====== ========== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)

Then you could do:

(lldb) platform process attach --pid 1
(lldb) platform process attach --pid 2

Yes, that looks like a nice plan. I see the lldb "target instance" is implicitly created. For the embedded world I'm curious as to how now to associate each of these targets with potentially different ELF files.

We would add functionality to the platform like:

(lldb) platform bareboard list
Core ARCH Description
====== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)
(lldb) platform bareboard attach 1

Cool. So let me see if I've understood this correctly. Currently we have the "platform process" concept, so that means for embedded stuff without OS support we emulate running cores with processes. However, in the future, if we add a "platform bareboard" concept which allows attachment to cores without OSes? Personally, I'm content to remain with "platform process" concept for cores, since we rely on the underlying lldb Process C++ implementation to debug (read memory/registers etc.) to debug these entities. I may have the wrong end of the stick here, though.

Again, we can make the platform all we need it to be so we can make LLDB a great embedded debugger.

I hope so. I'm trying to understand how to do this without busting the existing architecture. But I guess it's possible with incremental steps.

However some of these actions are applicable, and indeed useful. Our current debugger has a poor way of mapping different ELFs to a particular context - we only really support having just one (or zero) ELFs for any particular running core - so option 4. may be of benefit. 5. and 6. are also relevant, although we don't have the real processes, the concept of Process 1 in an unattached/attached-running/attached-stopped state would be useful.

again, see the above mapping of "processes" to "core groups" and see if that makes more sense.

If you write a platform that recognizes "kalimba-csr-unknown", you can say:

(lldb) file /path/to/kalimba/a.out

And it will query all installed platforms and see if any claim the current architecture. If you made "PlatformKalimba", your platform be matched up with the binary since #2 from above in your platform would return "kalimba-csr-unknown", and your platform would automatically be selected.

Yep, understood. Presumably to support this effort I'll need to augment the ArchType and VendorType enumerations of llvm::Triple and the relevant parseXXX:: and getXXXName:: functions, as I referred to above.

Yes, full clang support is actually required so we can make a clang Target and clang AST so we can represent your types and do expression evaluation. I was assuming this was already done, but this is a large amount of work if it isn't. Unless you can use another architecture that clang already supports, but that would be a large hack.

Well, all I'm trying to achieve right now is arrange that when I load a Kalimba ELF (with suitable EM_MACHINE and possibly a matching .notes section) we get a suitable target entry:

e.g.
target #0: kal.elf ( arch=kalimba-csr-unknown, platform=kalimba )

From earlier in this thread I'm given to understand that to do this right I need to create Plugins/Platform/Kalimba (i.e. "Platform Kalimba"). And from my own work I think I need the matching definitions in llvm::Triple to make this fly. Since we don't have a clang/llvm person on board yet, I was hoping I could at least get my "Platform Kalimba" working without full clang support. Please tell me if you don't think this is possible with ELF/DWARF built by other toolchains. I appreciate that expression evaluation would not work, but did think that things like stack unwind, source-line step and other debug primitives would still work.

Let me know if you have any more questions.

Greg

Will do. Thanks again.
Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Matthew Gardiner wrote:

The way the "remote-gdb-server" is currently used it by other platforms (like PlatformPOSIX) have a shared pointer to a platform as a member variable:

     lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS

And this platform can implement items 5-9, while the local subclass "PlatformKalimba" can take care of doing the specific local file system kinds of things (locating all development kits for Kalimba on the current host, finding all things you have debug symbols for, resolve executables, etc). When you then connect to your platform:

(lldb) platform connect <url>

Then your "PlatformKalimba" would then create a connection to a remote lldb-platform (which is a GDB remote protocol based platform) if you ever require the ability to do the steps 5-9 above. Otherwise, the platform is still useful for locating local copies of your executables.

Oh, I see, we have a notion of the local and remote platforms when working with embedded debug.

I'm still kind of intrigued as to the conceptual split between the notion of the local and the remote platforms.

As an example, presumably it's possible to be debugging a remote FreeBSD process (which is being controlled by a gdbserver running on a remote FreeBSD box) from lldb running on a local linux box. In that case would the:

local platform = remote-freebsd
remote platform = remote-gdb-server

with the local platform being -freebsd since the ELF being debugged was built for FreeBSD?

(Note that for my linux build I have only these platforms available:
host: Local Linux user platform plug-in.
remote-freebsd: Remote FreeBSD user platform plug-in.
remote-linux: Remote Linux user platform plug-in.
remote-windows: Remote Windows user platform plug-in.
remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport.)

(Sorry if this seems to be an overly simplistic question - I'm just trying to get my facts clear.)

thanks
Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Greg Clayton wrote:

Greg Clayton wrote:

Hi all,

I have modified my local copy of lldb in order that it can gdb-remote to an in-house gdb-rsp server. However after I connect to my target, the target list command informs me that my target's platform is "host".

e.g.

(lldb) target list
Current targets:
* target #0: /home/mg11/src/main/devtools/main/heracles/csrgdbserver/test/examples/simple/kalgsd5te_hello.elf ( arch=kalimba-csr-unknown, platform=host, pid=1, state=stopped )

Is this correct for a embedded target connected over gdb-rsp?

No, you really should add a new platform that claims "kalimba-csr-unknown" as its architecture.

Right, thanks. Am I correct to assume that I'll need to add kalimba (architecture) and CSR (vendor) to llvm::Triple to really get this plan to take-off?

If you want expression parsing and for us to be able to make types using Clang ASTs it is going to require that you hook up your architecture within LLVM and Clang. Otherwise we won't be able to make a clang target so that we can covert the DWARF debug info into Clang ASTs.

Yes, sure. We at CSR are in the process of getting someone aboard to work on an LLVM backend for our Kalimbas. We are slowly changing bits of our existing toolchain (e.g. with an official EM_MACHINE number + an ELF notes section) to see how far we can get (before the LLVM backend) with an lldb port.

Great.

We can also modify the lldb_private::Platform to state it is a bare board somehow and add bareboard functionality to the platforms. Let us know what you would want from a bare board Platform and we can get this included. Often times with JTAG style debugging, the software that talks to the JTAG can often enumerate the core groups you can attach to and each core can be a separate architecture. In these scenarios the following mappings would hold true:
- different core groups would map to the equivalent of processes
- a group of cores would be represented by lldb_private::Process which a lldb_private::Thread representing a single core in the group (all cores must have same architecture)

As I mentioned offline to you and Todd, we have proprietary USB/SPI connections to our chips. So one host PC may be connected to several boards (each with a CSR chip) with one USB connection per board. Furthermore each chip may have several cores which may or may not share architectures (Kalimba, ARM, 8051-clone etc.). And yes I think we need to (currently) map a core to a process.

Then you could attach to your platform and currently do:

(lldb) platform process list
PID PARENT USER ARCH NAME
====== ====== ========== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)

Then you could do:

(lldb) platform process attach --pid 1
(lldb) platform process attach --pid 2

Yes, that looks like a nice plan. I see the lldb "target instance" is implicitly created. For the embedded world I'm curious as to how now to associate each of these targets with potentially different ELF files.

We would add functionality to the platform like:

(lldb) platform bareboard list
Core ARCH Description
====== ===================== ============================
1 armv7-unknown-unknown ARMV7 (2 cores)
2 armv5-unknown-unknown ARMV5 (1 core)
(lldb) platform bareboard attach 1

Cool. So let me see if I've understood this correctly. Currently we have the "platform process" concept, so that means for embedded stuff without OS support we emulate running cores with processes. However, in the future, if we add a "platform bareboard" concept which allows attachment to cores without OSes? Personally, I'm content to remain with "platform process" concept for cores, since we rely on the underlying lldb Process C++ implementation to debug (read memory/registers etc.) to debug these entities. I may have the wrong end of the stick here, though.

I am happy to stick with this as well, so lets say for now we will continue to treat core groups as processes, and processes with threads that represent each individual core.

Again, we can make the platform all we need it to be so we can make LLDB a great embedded debugger.

I hope so. I'm trying to understand how to do this without busting the existing architecture. But I guess it's possible with incremental steps.

However some of these actions are applicable, and indeed useful. Our current debugger has a poor way of mapping different ELFs to a particular context - we only really support having just one (or zero) ELFs for any particular running core - so option 4. may be of benefit. 5. and 6. are also relevant, although we don't have the real processes, the concept of Process 1 in an unattached/attached-running/attached-stopped state would be useful.

again, see the above mapping of "processes" to "core groups" and see if that makes more sense.

If you write a platform that recognizes "kalimba-csr-unknown", you can say:

(lldb) file /path/to/kalimba/a.out

And it will query all installed platforms and see if any claim the current architecture. If you made "PlatformKalimba", your platform be matched up with the binary since #2 from above in your platform would return "kalimba-csr-unknown", and your platform would automatically be selected.

Yep, understood. Presumably to support this effort I'll need to augment the ArchType and VendorType enumerations of llvm::Triple and the relevant parseXXX:: and getXXXName:: functions, as I referred to above.

Yes, full clang support is actually required so we can make a clang Target and clang AST so we can represent your types and do expression evaluation. I was assuming this was already done, but this is a large amount of work if it isn't. Unless you can use another architecture that clang already supports, but that would be a large hack.

Well, all I'm trying to achieve right now is arrange that when I load a Kalimba ELF (with suitable EM_MACHINE and possibly a matching .notes section) we get a suitable target entry:

e.g.
target #0: kal.elf ( arch=kalimba-csr-unknown, platform=kalimba )

From earlier in this thread I'm given to understand that to do this right I need to create Plugins/Platform/Kalimba (i.e. "Platform Kalimba"). And from my own work I think I need the matching definitions in llvm::Triple to make this fly. Since we don't have a clang/llvm person on board yet, I was hoping I could at least get my "Platform Kalimba" working without full clang support. Please tell me if you don't think this is possible with ELF/DWARF built by other toolchains. I appreciate that expression evaluation would not work, but did think that things like stack unwind, source-line step and other debug primitives would still work.

Yes you will need to make a "Plugins/Platform/Kalimba" with a plug-in named "kalimba". It is possible to start getting ELF files loaded, but the big hurdle we will run into is you won't get any type introspection since the DWARF parser creates clang ASTs and converts DWARF back into DWARF ASTs. If your data layout is similar to another architecture, you could use that other architecture until you have your kalimba support in clang. As an example, there will be DWARF that describes a structure:

struct foo {
    int a;
    float b;
    uint64_t c;
};

We would create a clang AST and tell it to create a structure type "foo" and would add fields "a", "b", and "c" to that structure type and also assist the compiler with the layout by using data in the DWARF in case any #pragam or alignment attributes were used on any members. These clang AST types are used to display types with "frame variable" and also with expression results. Take a look at the ClangASTType.cpp file to get a feel for how we introspect types after they have been made into Clang types. So currently you would be able to make a target with your ELF file and get source correspondence, but you might fail to be able to display any variables.

Greg

As an example, presumably it's possible to be debugging a remote FreeBSD process (which is being controlled by a gdbserver running on a remote FreeBSD box) from lldb running on a local linux box. In that case would the:

local platform = remote-freebsd
remote platform = remote-gdb-server

with the local platform being -freebsd since the ELF being debugged was built for FreeBSD?

Yes the flow for this would current be to launch the remote gdb server:

remote.com% lldb-gdbserver host.com:1234 -- /bin/ls -lAF

Then start up LLDB on the host and debug to it

host.com% lldb
(lldb) target select remote-freebsd
(lldb) file /path/to/local/freebsd/build/a.out
(lldb) gdb-remote remote.com:1234

Selecting the platform first has a few benefits:
1 - if the "a.out" has dependent shared libraries like "/usr/lib/libfoo.so", the remote-freebsd platform might say "that file is in /usr/local/freebsd/sdk/9.0/usr/lib/libfoo.so". This would repeat for all shared libraries and you can do a "image list" and see all of the shared libraries you depend on and set breakpoint and inspect prior to running.
2 - platforms support some architectures and they can help select the right architecture in the /path/to/local/freebsd/build/a.out if there are more than 1 (not typical for ELF files currently, usually there is only 1 architecture in each file)

If you are connected to a remote platform, that connection could allow you download any needed files (like shared libraries) and have them cached locally:

remote.com% lldb-platform host.com:2000

(lldb) target select remote-freebsd
(lldb) platform connect connect://remote.com:2000
(lldb) file /path/to/local/freebsd/build/a.out
(lldb) run

When connected to a platform and if we are trying to track down dependencies for the "a.out" we could copy "libfoo.so" from remote.com:/usr/lib/libfoo.so" to a local cache directory.

So the connection to the platform is only required if you need to do dynamic things through the platform like list processes, and attach to an existing process, or run. In the above case, the lldb-platform would launch its own lldb-gdbserver for you and you would ever need to start the lldb-gdbserver on the remote machine. Or we can do things manually like the first case I showed where we start lldb-gdbserver ourselves and use "gdb-remote" to attach to it without the need for a live platform connection.

Greg

Just for completeness sake, the other thing that platforms encapsulate is are OS dependent features of the target system, for instance things like "How do I stop on new thread creation" or "What are the special trap handlers for the system?" and for other system specific features like "Queues" on Darwin...

You can't really do this in the process because then you'd have to have ProcessGDBRemote know about all the systems it might connect to...

Jim

Yes you will need to make a "Plugins/Platform/Kalimba" with a plug-in named "kalimba". It is possible to start getting ELF files loaded, but the big hurdle we will run into is you won't get any type introspection since the DWARF parser creates clang ASTs and converts DWARF back into DWARF ASTs. If your data layout is similar to another architecture, you could use that other architecture until you have your kalimba support in clang. As an example, there will be DWARF that describes a structure:

struct foo {
     int a;
     float b;
     uint64_t c;
};

We would create a clang AST and tell it to create a structure type "foo" and would add fields "a", "b", and "c" to that structure type and also assist the compiler with the layout by using data in the DWARF in case any #pragam or alignment attributes were used on any members. These clang AST types are used to display types with "frame variable" and also with expression results. Take a look at the ClangASTType.cpp file to get a feel for how we introspect types after they have been made into Clang types. So currently you would be able to make a target with your ELF file and get source correspondence, but you might fail to be able to display any variables.

Greg

Thanks for this Greg. Your last point concerning "frame variable" being very relevant regarding my overall quest.
Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

Greg Clayton wrote:

As an example, presumably it's possible to be debugging a remote FreeBSD process (which is being controlled by a gdbserver running on a remote FreeBSD box) from lldb running on a local linux box. In that case would the:

local platform = remote-freebsd
remote platform = remote-gdb-server

with the local platform being -freebsd since the ELF being debugged was built for FreeBSD?

Yes the flow for this would current be to launch the remote gdb server:

remote.com% lldb-gdbserver host.com:1234 -- /bin/ls -lAF

Then start up LLDB on the host and debug to it

host.com% lldb
(lldb) target select remote-freebsd
(lldb) file /path/to/local/freebsd/build/a.out
(lldb) gdb-remote remote.com:1234

Selecting the platform first has a few benefits:
1 - if the "a.out" has dependent shared libraries like "/usr/lib/libfoo.so", the remote-freebsd platform might say "that file is in /usr/local/freebsd/sdk/9.0/usr/lib/libfoo.so". This would repeat for all shared libraries and you can do a "image list" and see all of the shared libraries you depend on and set breakpoint and inspect prior to running.
2 - platforms support some architectures and they can help select the right architecture in the /path/to/local/freebsd/build/a.out if there are more than 1 (not typical for ELF files currently, usually there is only 1 architecture in each file)

If you are connected to a remote platform, that connection could allow you download any needed files (like shared libraries) and have them cached locally:

remote.com% lldb-platform host.com:2000

(lldb) target select remote-freebsd
(lldb) platform connect connect://remote.com:2000
(lldb) file /path/to/local/freebsd/build/a.out
(lldb) run

When connected to a platform and if we are trying to track down dependencies for the "a.out" we could copy "libfoo.so" from remote.com:/usr/lib/libfoo.so" to a local cache directory.

So the connection to the platform is only required if you need to do dynamic things through the platform like list processes, and attach to an existing process, or run. In the above case, the lldb-platform would launch its own lldb-gdbserver for you and you would ever need to start the lldb-gdbserver on the remote machine. Or we can do things manually like the first case I showed where we start lldb-gdbserver ourselves and use "gdb-remote" to attach to it without the need for a live platform connection.

Greg

Thanks for this, Greg.

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.

jingham@apple.com wrote:

Just for completeness sake, the other thing that platforms encapsulate is are OS dependent features of the target system, for instance things like "How do I stop on new thread creation" or "What are the special trap handlers for the system?" and for other system specific features like "Queues" on Darwin...

You can't really do this in the process because then you'd have to have ProcessGDBRemote know about all the systems it might connect to...

Jim

Yup. Thanks for this one, Jim.

Matt

Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Keep up to date with CSR on our technical blog, www.csr.com/blog, CSR people blog, www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook, www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at www.twitter.com/CSR_plc.
New for 2014, you can now access the wide range of products powered by aptX at www.aptx.com.