Hi Greg, Apologies for my sluggishness, but I've been off lldb for a bit, contributing to an in-house project.
Thanks for clarifying that a "virtual address" in my world is the same as a load address in lldb's terminology. What puzzles me is why the invocation of: a = target.ResolveFileAddress(data_section_addr) was removed in your recent change, since in that change, I had been attempting to associate the raw address with a file section. Did this fail to resolve to a section/offset based address? Matt On Tue, 2014-11-04 at 10:18 -0800, Greg Clayton wrote: > > On Nov 3, 2014, at 10:53 PM, Matthew Gardiner <[email protected]> wrote: > > > > Hi Greg, > > > > So what in lldb's world is the difference between a file and a load > > address? > > > "file address" (as LLDB treats them) is the address that is found in the > object file (ELF, MachO, or COFF). "load address" is the actual address in > the process where the section is loaded after being slid. > > For example you might have a shared library that has a function "foo" whose > file address is 0x1000, but when the shared library gets loaded into memory, > it will be loaded at a different address because all shared libraries have > functions in the low file address range (say from 0 to 0x400000 for example). > So if the shared library gets loaded with a slide of 0x1000000, foo will have > a load address of 0x1000000 + 0x1000. > > Now for most embedded debugging where there is no OS that will slide things > around, your file and load addresses will match. For actual OS level > debugging, they won't for shared libraries, and might for the main > executable. Sometimes the main executable doesn't get slid around, but other > OSs will use ASLR to slide the main executables around for security. > > The test that was written was trying to get a data section from the object > file. Then it made a section offset address that pointed to that data > section. Then it called SBTarget::ReadMemory(...) with that section offset > address. What was happening on MacOSX was: > > - get the data section whose file address was 0x10001000 > - Make a section + offset address from it that was represented as a.out's > data section + 0 bytes > - call target read memory > > Prior to my fix this happened: > > SBTarget::ReadMemory() made a new section offset address: > > Address address(section_offset_addr.GetFileAddress(), NULL); > > Now we have an address that has no section. If such an address is passed to > anything that is trying to read memory from a live process, an address with > no section is considered to be a "load address". It will try and read from > the "load address" 0x10001000. But on MacOSX, or any OS with ASLR, the data > section was slid by a random amount (like 0xef0000). So we would try to read > from "load address" 0x10001000 and it would fail. If we leave the address > object as a section offset address (don't make a new address like we did > above), we pass this address to a read memory function and it will resolve > the section offset address into an address in the live process, or into a > load address. This will be 0x10001000 + 0xef0000 + 0. The load address of the > data section is 0x10001000 + 0xef0000 and the offset was 0. And the resulting > memory it will read from in the process is 0x10ef1000. The old way it would > have tried to read from 0x10001000 which was incorrect. > > > > 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? > > > So in your terms: > > virtual address is what we call the "load address". > file address means address as it is found in the object file you loaded it > from. > > Many object files speak of a virtual address when they are speaking of file > addresses, so I didn't think "virtual address" made as much sense as "load > address". For example the mach-o segments have a "vmaddr" and "vmsize" fields > when parsing the segments which stand for virtual address and virtual size. > > Hope that clears things up. > > > 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 > >> [email protected] > >> 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. > _______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
