Sorry for the delayed response Greg.
I have been working on a proof of concept which adds a new dynamic loader for gdb-remote as you suggest, and perhaps when I get it working with
the behavior I'm expecting, I can post it for review and we can have a look at how best to integrate something like this with upstream LLDB. Perhaps
it can indeed by integrated cleanly with the posixDYLD.
It would be best if we use the PosixDYLD one because this knows where to set the breakpoints to get shared library load updates on the fly. Not sure if the GDB remote versions handle this. I believe there are async notifications, but we really need shared library loads to be synchronous so we can set breakpoints when shared libraries get loaded.
There is one issue that has emerged while I have been working on this, with regard to how LLDB regards the target executable as the first module loaded.
Since the first and potentially only module that I can give to LLDB is a shared library it doesn't seem to make sense to regard it as the executable module.
My thoughts were to change the way the target handles this, so that LLDB instead looks for the first executable module loaded, which would exclude shared object.
I changed it to be something like this:
ModuleSP
Target::GetExecutableModule ()
{
for ( uint32_t i = 0; i < (uint32_t)m_images.GetSize( ); ++i )
Use size_t here and avoid the cast to uint32_t.
{
ModuleSP modsp = m_images.GetModuleAtIndex( i );
lldb_private::ObjectFile * obj = modsp->GetObjectFile( );
if ( obj == nullptr )
continue;
ObjectFile::Type type = obj->GetType( );
if ( type == ObjectFile::Type::eTypeExecutable )
return modsp;
}
return ModuleSP();
}
That would be OK, but I would change it so if you don't find any executable you should return the first module like it did before. Not sure what fallout this could have for people.
Module*
Target::GetExecutableModulePointer ()
{
return GetExecutableModule().get();
}
This problem surfaced when I noticed the posixDYLD (which I was using at the time) takes the executable (module index 0), and forcefully sets its load address based
on the entry point of the program. In the case of my shared library this is the incorrect address.
So dynamic loaders are currently expected to re-order the target module list, though this isn't formally declared anywhere.
The DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(...) will set the target executable if it doesn't match so that it is always at index zero. See the code in DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands() for details on how this is done.
So you can either change Target::GetExecutableModule() or update the POSIXDYLD dynamic loader to set the executable correctly and re-order the images.
Greg