[Lldb-commits] [lldb] r221213 - Fixed SBTarget::ReadMemory() to work correctly and the TestTargetAPI.py test case that was reading target memory in TargetAPITestCase.test_read_memory_with_dsym and TargetAPITestCase.test_read_memory_with_dwarf.

Matthew Gardiner mg11 at csr.com
Mon Nov 3 22:53:08 PST 2014


Hi Greg,

So what in lldb's world is the difference between a file and a load
address? In my world I consider the file and load addresses to be the
same thing, that is, the address (not the file offset) of the symbol in
the object file, e.g. when I objdump symbols and grep for ones I know of
in a kalimba ELF, I get

0000054f g       DM|0	00000000 $_g_matt1
...


0x54f as the file address of g_matt1.


The other address terminology I hear of is "virtual address". To me this
the address of the symbol once the binary is actually running on the
processor. So in some embedded scenarios (like kalimba where there is no
OS) we have code addresses in the ELF (i.e. file/load address) all
starting at 80000000 e.g.

80000354 g     F PM|0	00000000 $_main

But on the device (since it's harvard architecture with a CODE and DATA
bus), main is actually at 0x0354. So in this context I'd say 0x80000354
was the "load/file address" but 0x0354 was the virtual address. I see
similar scenario with linux shared object files where in the file the
symbol addresses are often based at 0, but at runtime are fixed-up to
some arbitrary offset.   

Can you explain what lldb means by file/load/virtual and so on
addresses?   

thanks    
Matt



On Tue, 2014-11-04 at 00:56 +0000, Greg Clayton wrote:
> Author: gclayton
> Date: Mon Nov  3 18:56:30 2014
> New Revision: 221213
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=221213&view=rev
> Log:
> Fixed SBTarget::ReadMemory() to work correctly and the TestTargetAPI.py test case that was reading target memory in TargetAPITestCase.test_read_memory_with_dsym and TargetAPITestCase.test_read_memory_with_dwarf.
> 
> The problem was that SBTarget::ReadMemory() was making a new section offset lldb_private::Address by doing:
> 
> 
> size_t
> SBTarget::ReadMemory (const SBAddress addr,
>                       void *buf,
>                       size_t size,
>                       lldb::SBError &error)
> {
>         ...
>         lldb_private::Address addr_priv(addr.GetFileAddress(), NULL);
>         bytes_read = target_sp->ReadMemory(addr_priv, false, buf, size, err_priv);
> 
> 
> This is wrong. If you get the file addresss from the "addr" argument and try to read memory using that, it will think the file address is a load address and it will try to resolve it accordingly. This will work fine if your executable is loaded at the same address (no slide), but it won't work if there is a slide.
> 
> The fix is to just pass along the "addr.ref()" instead of making a new addr_priv as this will pass along the lldb_private::Address that is inside the SBAddress (which is what we want), and not always change it into something that becomes a load address (if we are running), or abmigious file address (think address zero when you have 150 shared libraries that have sections that start at zero, which one would you pick). The main reason for passing a section offset address to SBTarget::ReadMemory() is so you _can_ read from the actual section + offset that is specified in the SBAddress. 
> 
> 
> 
> Modified:
>     lldb/trunk/source/API/SBTarget.cpp
>     lldb/trunk/test/python_api/target/TestTargetAPI.py
> 
> Modified: lldb/trunk/source/API/SBTarget.cpp
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=221213&r1=221212&r2=221213&view=diff
> ==============================================================================
> --- lldb/trunk/source/API/SBTarget.cpp (original)
> +++ lldb/trunk/source/API/SBTarget.cpp Mon Nov  3 18:56:30 2014
> @@ -1306,13 +1306,11 @@ SBTarget::ReadMemory (const SBAddress ad
>      if (target_sp)
>      {
>          Mutex::Locker api_locker (target_sp->GetAPIMutex());
> -        lldb_private::Address addr_priv(addr.GetFileAddress(), NULL);
> -        lldb_private::Error err_priv;    
> -        bytes_read = target_sp->ReadMemory(addr_priv, false, buf, size, err_priv);
> -        if(err_priv.Fail())
> -        {
> -            sb_error.SetError(err_priv.GetError(), err_priv.GetType());
> -        }
> +        bytes_read = target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref());
> +    }
> +    else
> +    {
> +        sb_error.SetErrorString("invalid target");
>      }
>  
>      return bytes_read;
> 
> Modified: lldb/trunk/test/python_api/target/TestTargetAPI.py
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/target/TestTargetAPI.py?rev=221213&r1=221212&r2=221213&view=diff
> ==============================================================================
> --- lldb/trunk/test/python_api/target/TestTargetAPI.py (original)
> +++ lldb/trunk/test/python_api/target/TestTargetAPI.py Mon Nov  3 18:56:30 2014
> @@ -213,16 +213,20 @@ class TargetAPITestCase(TestBase):
>          breakpoint = target.BreakpointCreateByLocation("main.c", self.line_main)
>          self.assertTrue(breakpoint, VALID_BREAKPOINT)
>  
> +        # Put debugger into synchronous mode so when we target.LaunchSimple returns
> +        # it will guaranteed to be at the breakpoint
> +        self.dbg.SetAsync(False)
> +        
>          # Launch the process, and do not stop at the entry point.
>          process = target.LaunchSimple (None, None, self.get_process_working_directory())
>  
>          # find the file address in the .data section of the main
>          # module            
>          data_section = self.find_data_section(target)
> -        data_section_addr = data_section.file_addr
> -        a = target.ResolveFileAddress(data_section_addr)
> -
> -        content = target.ReadMemory(a, 1, lldb.SBError())
> +        sb_addr = lldb.SBAddress(data_section, 0)
> +        error = lldb.SBError()
> +        content = target.ReadMemory(sb_addr, 1, error)
> +        self.assertTrue(error.Success(), "Make sure memory read succeeded")
>          self.assertEquals(len(content), 1)
>  
>      def create_simple_target(self, fn):
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
> 
> 
>  To report this email as spam click https://www.mailcontrol.com/sr/MZbqvYs5QwJvpeaetUwhCQ== .




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.



More information about the lldb-commits mailing list