Greg Clayton <[email protected]> writes:

> A few quick questions: 
>
> Regaring the:
>
>   virtual lldb_private::Address
>   GetImageInfoAddress () { return Address(); }
>
> Is this value not in any symbol in the symbol table in the ELF file?
> If it is a symbol, and the ELF plug-in could classify the symbol type
> as a special symbol type (see Symbol.h), then could we do it this way?

Unfortunately, no, there is no symbol.  We do have _DYNAMIC which gives
the start address of the .dynamic section, but we still need to parse
the contents.  It seems natural to me to do that parsing/processing in
the ObjectFile class.

However, it may still be useful to export _DYNAMIC as a special symbol
type.  I have not thought about it as an option.  I will keep it in mind
as I work on the dynamic loader plugin.


Thanks!

>
>
>
> On Jan 12, 2011, at 11:07 AM, Greg Clayton wrote:
>
>> 
>> On Jan 11, 2011, at 8:17 PM, Stephen Wilson wrote:
>> 
>>> 
>>> *,
>>> 
>>> I have been prototyping a DynamicLoader plugin for the Linux platform.
>>> Current state of the effort is available here:
>>> 
>>>  https://github.com/eightcien/lldb/tree/lldb-linux
>>> 
>>> 
>>> On ELF platforms there is a "rendezvous" structure in a processes
>>> address space populated by the runtime linker for use by debuggers.
>>> This structure provides the address of a function which is called by the
>>> linker each time a shared object is loaded and unloaded (thus a
>>> breakpoint at that address will let a debugger intercept such events), a
>>> list of entries describing the currently loaded shared objects, plus a
>>> few other things.
>>> 
>>> In order to locate this structure one must interrogate the object file
>>> for the process.  The location of this rendezvous is provided by a
>>> DT_DEBUG entry in the processes .dynamic section.  The actual address
>>> must be reaped by looking at the loaded .dynamic section contents of the
>>> process.
>>> 
>>> The first proposal is to add the following method to ObjectFile, which
>>> allows us to locate the needed information:
>>> 
>>>   //------------------------------------------------------------------
>>>   /// Similar to Process::GetImageInfoAddress().
>>>   ///
>>>   /// Some platforms embed auxiliary structures useful to debuggers in the
>>>   /// address space of the inferior process.  This method returns the 
>>> address
>>>   /// of such a structure if the information can be resolved via entries in
>>>   /// the object file.  ELF, for example, provides a means to hook into the
>>>   /// runtime linker so that a debugger may monitor the loading and 
>>> unloading
>>>   /// of shared libraries.
>>>   ///
>>>   /// @return 
>>>   ///     The address of any auxiliary tables, or an invalid address if this
>>>   ///     object file format does not support or contain such information.
>>>   virtual lldb_private::Address
>>>   GetImageInfoAddress () { return Address(); }
>>> 
>>> In my prototype the above method is implemented by ObjectFileELF, and
>>> Process::GetImageInfoAddress in turn uses this information.
>>> 
>>> I use an Address object instead of an lldb::addr_t as it is slightly
>>> more generic, and perhaps more useful, to represent the info as a
>>> "section load address + offset".
>> 
>> Yes, this looks fine. The "Address" is the right thing to use since it can 
>> point you back to your module.
>> 
>> A quick note to everyone: if you have an Address can you get the module from 
>> which is comes which can then get your to your object and symbol files:
>> 
>> Address addr (...);
>> Module *module = addr.GetModule();
>> // Check the module in case "addr" was not section/offset (the section might 
>> be NULL)
>> if (module)
>> {
>>    ObjectFile *objfile = module->GetObjectFile();
>>    SymbolVendor*symbols = module->GetSymbolVendor();
>>    ...
>> }
>> 
>> Since addresses are stored as section offset, when shared libraries get 
>> loaded, the dynamic loader plug-ins tell the target where each section got 
>> loaded. Then we can resolve addresses as needed. 
>> 
>> For example, if you have a PC value 0x100020 that you got from a register in 
>> a thread, you can then resolve it:
>> 
>> addr_t pc = 0x100020;
>> Address pc_addr;
>> if 
>> (thread.GetProcess().GetTarget().GetSectionLoadList().ResolveLoadAddress(pc, 
>> pc_addr))
>> {
>>    // The address was successfully resolved and now contains a "Section *" 
>> that can point
>>    // you to the Module/ObjectFile/Symbols...
>> }
>> 
>>> 
>>> 
>>> The second bit is to provide the DynamicLoader plugin with a method to
>>> synchronize with the runtime linker.  A simple strategy is to set a
>>> breakpoint on the entry address for the executable and to parse the
>>> rendezvous structure after the linker has had a chance to populate it.
>>> Hence the following addition:
>>> 
>>>   //------------------------------------------------------------------
>>>   /// Returns the virtual address of the entry point for this object 
>>>   /// file.
>>>   ///
>>>   /// @return
>>>   ///     The virtual address of the entry point or 
>>>   ///     LLDB_INVALID_ADDRESS if an entry point is not defined.
>>>   //------------------------------------------------------------------
>>>   virtual lldb::addr_t
>>>   GetEntryPoint () const { return LLDB_INVALID_ADDRESS; }
>>> 
>>> 
>>> The above two methods are enough to get a minimal DynamicLoader plugin
>>> functioning on Linux.  I would very much appreciate any
>>> feedback/comments on the above.
>> 
>> I would rather see this added as:
>> 
>>   virtual Address
>>   GetEntryPoint () const { return Address(); }
>> 
>> So that you know what module the entry point came from. The linux dynamic 
>> loader would then just know that the file and load addresses for a linux 
>> executable (not shared library, just executable files) are the same (is this 
>> true? Do the virtual addresses in the ELF file for an executable never 
>> change?) and it could get the entry point as an addr_t by doing:
>> 
>> 
>> ModuleSP exe_module_sp (target->GetExecutableModule ());
>> if (exe_module_sp)
>> {
>>      ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
>>      if (exe_objfile)
>>      {
>>              Address entry_point (exe_objfile->GetEntryPoint());
>>              addr_t entry_point_load_addr = entry_point.GetFileAddress();
>>      }
>> }
>> 
>> 
>> The other thing you might want to do, is in the linix dynamic loader 
>> plug-in, if you know that the executable is always at the same address as 
>> the virtual addresses in the file, you can automatically register the load 
>> address of the sections as soon as you construct the DynamicLoaderLinux 
>> object. Because when setting a breakoint, it will eventually turn into a 
>> section/offset breakpoint and the breakpoint won't set itself until the 
>> section gets loaded.
>> 
>> Let me know if you have any questions on this.
>> 
>> Greg Clayton
>> 
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> [email protected]
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>

--
steve
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to