One of my customers brought a new use case to me yesterday. He runs a bootloader, that loads the actual program that he wants to debug.
We’re using a simulator, which my Hexagon Platform can launch and connect to. I launch the simulator with the target to run (the boot loader) and arguments from target.run-args, consisting of args for the simulator, followed by “–“ and args for the target. In this case, args for the bootloader include the ELF file (which I’ll call the secondary) that it should load and run.
I tried using “target modules add” to add the secondary, but breakpoints I set on its symbols weren’t hit.
I could use the secondary as LLDB’s target, but then LLDB couldn’t launch the simulator with the bootloader. I could launch the simulator manually and connect to it with gdb-remote, but I’d rather do that automatically.
Any advice on how to treat the secondary as part of the target?
Ted, in this kind of environment it's often necessary to set the load address of the modules manually. There is no dynamic loader in this environment which tells lldb where solibs are loaded in memory. "target modules add" adds the Module to the Target but until lldb is told where that is loaded in memory, it won't have load addresses and I'm guessing breakpoints won't actually be written into memory.
Try the "target modules load" command after you've "target modules add"ed the second file.
"target modules add" should work in that it will add the module to your target. The question is who is setting the load addresses for your program? Do you have a DynamicLoaderHexagon? Or do you load shared libraries through GDB remote auxv packets? As Jason said, one solution is to manually set the load location of your secondary ELF file, but that is a job your dynamic loader plug-in should be doing.
Right now you seem to be creating a target with the boot loader as the main executable. Is this the right thing to do? Do your customers expect to be debugging a boot loader just so they can debug their ELF executable? My questions and info below will go on the assumption this isn't what you want, I would think your customers really want to say "debug this foo.elf file".
It almost sounds like your boot loader should be a setting you set via:
(lldb) settings set platform.plugin.hexagon.simulator.boot-loader /tmp/bootloader.bin
Then you can just specify the executable as the sole executable of your target:
(lldb) file foo.elf
Then your PlatformHexagon would grab the boot-loader setting and launch your simulator with it.
Does your ELF program know anything about which simulator it should run with? How many different boot loaders do you have? Just one? Different boot loader for each program?
Can your ELF executable have an ELF note that describes which boot loader it should be run with so the simulator can automagically know which boot loader to use without having to specify it with a setting? If so, I believe this would be the best way to go. I am guessing during linking of your "foo.elf" you will need to link against the boot loader, so it might be nice to package the path to the boot loader up into the ELF executable so your PlatformHexagonSimulator knows to just find the info it needs in the main executable.