<div dir="ltr">For the Linux 64-bit hello_world, it looks like the below. Is this what you would expect?<div><div><br></div><div><div>(lldb) disassemble -n main</div><div>hello_world`main at hello_world.cpp:5:</div><div> 0x400770: pushq %rbp</div>
<div> 0x400771: movq %rsp, %rbp</div><div> 0x400774: subq $0x20, %rsp</div><div> 0x400778: leaq 0x40089c, %rax</div><div> 0x400780: movl %edi, -0x4(%rbp)</div><div> 0x400783: movq %rsi, -0x10(%rbp)</div>
<div>-> 0x400787: movq %rax, %rdi</div><div> 0x40078a: movb $0x0, %al</div><div> 0x40078c: callq 0x400660 ; symbol stub for: printf</div><div> 0x400791: movl $0x0, %ecx</div><div> 0x400796: movl %eax, -0x14(%rbp)</div>
<div> 0x400799: movl %ecx, %eax</div><div> 0x40079b: addq $0x20, %rsp</div><div> 0x40079f: popq %rbp</div><div> 0x4007a0: ret </div><div><br></div><div>(lldb) disassemble -a 0x400660</div><div>hello_world`symbol stub for: printf:</div>
<div> 0x400660: jmpq *0x20099a(%rip) ; _GLOBAL_OFFSET_TABLE_ + 24</div><div> 0x400666: pushq $0x0</div><div> 0x40066b: jmpq 0x400650 ; hello_world..plt + 0</div><div><br></div><div>
For reference, gdb 7.6 looks like this:</div><div><br></div><div><div>(gdb) disassemble main</div><div>Dump of assembler code for function main(int, char**):</div><div> 0x0000000000400770 <+0>: push rbp</div>
<div> 0x0000000000400771 <+1>: mov rbp,rsp</div><div> 0x0000000000400774: sub rsp,0x20</div><div> 0x0000000000400778: lea rax,ds:0x40089c</div><div> 0x0000000000400780: mov DWORD PTR [rbp-0x4],edi</div>
<div> 0x0000000000400783: mov QWORD PTR [rbp-0x10],rsi</div><div>=> 0x0000000000400787: mov rdi,rax</div><div> 0x000000000040078a: mov al,0x0</div><div> 0x000000000040078c: call 0x400660 <printf@plt></div>
<div> 0x0000000000400791: mov ecx,0x0</div><div> 0x0000000000400796: mov DWORD PTR [rbp-0x14],eax</div><div> 0x0000000000400799: mov eax,ecx</div><div> 0x000000000040079b: add rsp,0x20</div><div> 0x000000000040079f: pop rbp</div>
<div> 0x00000000004007a0: ret</div><div>End of assembler dump.</div><div><br></div><div>(gdb) disassemble 0x400660</div><div>Dump of assembler code for function printf@plt:</div><div> 0x0000000000400660 <+0>: jmp QWORD PTR [rip+0x20099a] # 0x601000 <printf@got.plt></div>
<div> 0x0000000000400666: push 0x0</div><div> 0x000000000040066b: jmp 0x400650</div><div>End of assembler dump.</div></div><div><br></div><div><br></div><div class="gmail_extra">On Fri, Aug 9, 2013 at 5:58 PM, Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>></span> wrote:<br>
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">In the ObjectFileMachO, we tend to make up symbols for all of the PLT stubs that we have and we give them a type of eSymbolTypeTrampoline. We do this by parsing the data in the mach-o binary and making synthetic symbols. We actually take all undefined symbols (which are useless to us in the debugger) and turn them into trampoline symbols to make the symbols useful. This sounds like a fix that needs to happen in ObjectFileELF.cpp.<br>
<span class=""><font color="#888888"><br>
Greg<br>
</font></span><div class=""><div class="h5"><br>
On Aug 9, 2013, at 5:39 PM, Michael Sartain <<a href="mailto:mikesart@gmail.com">mikesart@gmail.com</a>> wrote:<br>
<br>
> I'm starting to look at this now. I think there are some symbol issues on 32-bit as well. When running the code below in x64, the "disassemble -n main" recognizes the symbol stub for printf for the call statement, and the "disassemble -a addr" works as well.<br>
><br>
> I'll continue looking at this next week. Thanks Andy.<br>
> -Mike<br>
><br>
> mikesart@mikesart64:~/data/src/blah/build$ lldb -- hello_world<br>
> Current executable set to 'hello_world' (i386).<br>
><br>
> (lldb) b main<br>
> Breakpoint 1: where = hello_world`main + 24 at hello_world.cpp:6, address = 0x080485b8<br>
><br>
> (lldb) r<br>
> Process 5933 launched: '/home/mikesart/data/src/blah/build/hello_world' (i386)<br>
> Process 5933 stopped<br>
> * thread #1: tid = 5933, 0x080485b8 hello_world`main(argc=1, argv=0xffe770f4) + 24 at hello_world.cpp:6, name = 'hello_world', stop reason = breakpoint 1.1<br>
> frame #0: 0x080485b8 hello_world`main(argc=1, argv=0xffe770f4) + 24 at hello_world.cpp:6<br>
> 3<br>
> 4 int main( int argc, char *argv[] )<br>
> 5 {<br>
> -> 6 printf("hello world.\n");<br>
> 7 }<br>
><br>
> (lldb) disassemble -n main<br>
> hello_world`main at hello_world.cpp:5:<br>
> 0x80485a0: pushl %ebp<br>
> 0x80485a1: movl %esp, %ebp<br>
> 0x80485a3: subl $0x18, %esp<br>
> 0x80485a6: movl 0xc(%ebp), %eax<br>
> 0x80485a9: movl 0x8(%ebp), %ecx<br>
> 0x80485ac: leal 0x80486a0, %edx<br>
> 0x80485b2: movl %ecx, -0x4(%ebp)<br>
> 0x80485b5: movl %eax, -0x8(%ebp)<br>
> -> 0x80485b8: movl %edx, (%esp)<br>
> 0x80485bb: calll 0x80484d0<br>
> 0x80485c0: movl $0x0, %ecx<br>
> 0x80485c5: movl %eax, -0xc(%ebp)<br>
> 0x80485c8: movl %ecx, %eax<br>
> 0x80485ca: addl $0x18, %esp<br>
> 0x80485cd: popl %ebp<br>
> 0x80485ce: ret<br>
><br>
> (lldb) disassemble -a 0x80484d0<br>
> error: Could not find function bounds for address 0x80484d0<br>
><br>
> (lldb) disassemble -s 0x80484d0<br>
> 0x80484d0: jmpl *0x804a008<br>
> 0x80484d6: pushl $0x10<br>
> 0x80484db: jmp 0x80484a0 ; hello_world..plt + 0<br>
> hello_world`_start + 64:<br>
> 0x80484e0: xorl %ebp, %ebp<br>
><br>
> On Tue, Jul 23, 2013 at 2:55 PM, Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com">andrew.kaylor@intel.com</a>> wrote:<br>
> Hi Mike,<br>
><br>
><br>
><br>
> I investigated this a little further and it seems that the problem is that when LLDB tries to unwind the stack from the point of the ‘jmp’ instruction in the printf stub it incorrectly calculates the call frame address. The log output indicates that it is using ESP+12 as the call frame address based on information from the FDE table. Consequently, it is looking for the return address at ESP+8, but that’s wrong. (I believe it’s actually at ESP-4.) It’s possible that this is still a matter of the register context getting some registers confused because of the 32-bit mapping but if so the point of failure is less obvious.<br>
><br>
><br>
><br>
> It turns out that the variation of the code that I had that seemed to be working was actually working for the wrong reason. It was still looking for the frame 1 pc in the wrong location, but that location just happened to contain a non-zero value so the validity check passed over it.<br>
><br>
><br>
><br>
> That’s as far as I’ve gotten in my investigation. I’m going to be on vacation for a week after tomorrow and I have some other things I need to get done before then, so if you want to pick this up from here feel free to do so. If not, I’ll try to get back to it in early August.<br>
><br>
><br>
><br>
> -Andy<br>
><br>
><br>
><br>
><br>
><br>
> From: Michael Sartain [mailto:<a href="mailto:mikesart@gmail.com">mikesart@gmail.com</a>]<br>
><br>
> Sent: Friday, July 19, 2013 4:24 PM<br>
> To: Kaylor, Andrew<br>
> Cc: <a href="mailto:lldb-dev@cs.uiuc.edu">lldb-dev@cs.uiuc.edu</a>; Malea, Daniel; Kopec, Matt; Thirumurthi, Ashok<br>
> Subject: Re: lldb test failures on 32bit<br>
><br>
><br>
><br>
> I applied both patches, and the 'expr (int)printf("blah\n")' statement now works, but "n" over the printf() statement in the code still throws me somewhere else entirely. I'm on the call printf() asm instruction down below, I type "ni", and I wind up at address 0x80486f0.<br>
><br>
><br>
><br>
> Is this working for you?<br>
><br>
><br>
><br>
> And thanks for looking at this Andrew. Very cool we can call functions now in 32-bit targets...<br>
><br>
> -Mike<br>
><br>
><br>
><br>
> (lldb) ni<br>
><br>
> Process 18815 stopped<br>
><br>
> * thread #1: tid = 0x497f, 0x08048855 blah`main(argc=1, argv=0xff985674) + 37 at blah.cpp:29, name = 'blah, stop reason = instruction step over<br>
><br>
> frame #0: 0x08048855 blah`main(argc=1, argv=0xff985674) + 37 at blah.cpp:29<br>
><br>
> 26<br>
><br>
> 27 int main( int argc, char *argv[] )<br>
><br>
> 28 {<br>
><br>
> -> 29 printf("hello world.\n");<br>
><br>
> 30<br>
><br>
> 31 Set *foo = new Set();<br>
><br>
> 32<br>
><br>
> (lldb) disassemble<br>
><br>
> blah`main at blah.cpp:28:<br>
><br>
> 0x8048830: push EBP<br>
><br>
> 0x8048831: mov EBP, ESP<br>
><br>
> 0x8048833: push ESI<br>
><br>
> 0x8048834: sub ESP, 32820<br>
><br>
> 0x804883a: mov EAX, DWORD PTR [EBP + 12]<br>
><br>
> 0x804883d: mov ECX, DWORD PTR [EBP + 8]<br>
><br>
> 0x8048840: mov DWORD PTR [EBP - 8], 0<br>
><br>
> 0x8048847: mov DWORD PTR [EBP - 12], ECX<br>
><br>
> 0x804884a: mov DWORD PTR [EBP - 16], EAX<br>
><br>
> 0x804884d: mov EAX, ESP<br>
><br>
> 0x804884f: mov DWORD PTR [EAX], 134515168<br>
><br>
> -> 0x8048855: call 0x80486f0<br>
><br>
> 0x804885a: mov ECX, ESP<br>
><br>
> 0x804885c: mov DWORD PTR [ECX], 1<br>
><br>
> 0x8048862: mov DWORD PTR [EBP - 32804], EAX<br>
><br>
> 0x8048868: call 0x8048700<br>
><br>
> 0x804886d: mov ECX, EAX<br>
><br>
> 0x804886f: mov EDX, EAX<br>
><br>
> 0x8048871: mov ESI, ESP<br>
><br>
> 0x8048873: mov DWORD PTR [ESI], EAX<br>
><br>
> 0x8048875: mov DWORD PTR [EBP - 32808], EDX<br>
><br>
> 0x804887b: mov DWORD PTR [EBP - 32812], ECX<br>
><br>
> 0x8048881: call 0x8048800 ; Set at blah.cpp:23<br>
><br>
> 0x8048886: jmp 0x804888b ; main + 91 at blah.cpp:31<br>
><br>
> 0x804888b: mov EAX, DWORD PTR [EBP - 32812]<br>
><br>
> 0x8048891: mov DWORD PTR [EBP - 20], EAX<br>
><br>
> 0x8048894: mov DWORD PTR [EBP - 32800], 0<br>
><br>
> 0x804889e: cmp DWORD PTR [EBP - 32800], 8192<br>
><br>
> 0x80488a8: jae 0x80488ef ; main + 191 at blah.cpp:38<br>
><br>
> 0x80488ae: call 0x8048710<br>
><br>
> 0x80488b3: mov ECX, DWORD PTR [EBP - 32800]<br>
><br>
> 0x80488b9: mov DWORD PTR [EBP + 4*ECX - 32796], EAX<br>
><br>
> 0x80488c0: mov EAX, DWORD PTR [EBP - 32800]<br>
><br>
> 0x80488c6: add EAX, 1<br>
><br>
> 0x80488cb: mov DWORD PTR [EBP - 32800], EAX<br>
><br>
> 0x80488d1: jmp 0x804889e ; main + 110 at blah.cpp:34<br>
><br>
> 0x80488d6: mov DWORD PTR [EBP - 24], EAX<br>
><br>
> 0x80488d9: mov DWORD PTR [EBP - 28], EDX<br>
><br>
> 0x80488dc: mov EAX, DWORD PTR [EBP - 32808]<br>
><br>
> 0x80488e2: mov DWORD PTR [ESP], EAX<br>
><br>
> 0x80488e5: call 0x80486d0 ; symbol stub for: _Unwind_Resume<br>
><br>
> 0x80488ea: jmp 0x80488fb ; main + 203 at blah.cpp:31<br>
><br>
> 0x80488ef: mov EAX, DWORD PTR [EBP - 8]<br>
><br>
> 0x80488f2: add ESP, 32820<br>
><br>
> 0x80488f8: pop ESI<br>
><br>
> 0x80488f9: pop EBP<br>
><br>
> 0x80488fa: ret<br>
><br>
> 0x80488fb: mov EAX, DWORD PTR [EBP - 24]<br>
><br>
> 0x80488fe: mov DWORD PTR [ESP], EAX<br>
><br>
> 0x8048901: call 0x8048730<br>
><br>
> (lldb) ni<br>
><br>
> Process 18815 stopped<br>
><br>
> * thread #1: tid = 0x497f, 0x080486f0 blah, name = 'blah, stop reason = instruction step over<br>
><br>
> frame #0: 0x080486f0 blah<br>
><br>
> -> 0x80486f0: jmp DWORD PTR [134520844]<br>
><br>
> 0x80486f6: push 24<br>
><br>
> 0x80486fb: jmp 0x80486b0 ; blah..plt + 0<br>
><br>
> 0x8048700: jmp DWORD PTR [134520848]<br>
><br>
><br>
><br>
> On Fri, Jul 19, 2013 at 3:34 PM, Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com">andrew.kaylor@intel.com</a>> wrote:<br>
><br>
> Hi Mike,<br>
><br>
><br>
><br>
> I think I’ve tracked down the sources of both of these problems.<br>
><br>
><br>
><br>
> The problem with not being able to call functions in the target seems to be a failure in the MCJIT relocation mechanism. Because LLDB is generating IR with absolute addresses for function calls, the JITed code contains relocations with absolute values rather than symbols. This is a problem I fixed a short time ago, but it seems to have come undone again (at least in this particular case). The attached ‘reloc-fix-32.patch’ (to be applied to the LLVM repository) should fix that.<br>
><br>
><br>
><br>
> I need to do a bit of investigation to settle some questions about why this condition came back or was specific to the 32-bit case before I commit this, but I think this is correct.<br>
><br>
><br>
><br>
> The problem where you lose source after stepping seems to be a matter of incorrect stack unwinding. There were two problems lurking here.<br>
><br>
><br>
><br>
> First, the RegisterContext::ConvertBetweenRegisterKinds() function wasn’t making any provision for a 32-bit inferior running on a 64-bit target. The way the x86-64 register context class is implemented it defines 64-bit registers and 32-bit registers in the same RegisterInfo structure, and there is some overlap in how these get mapped to DWARF/GDB/GCC register numbers. RegisterContext::ConvertBetweenRegisterKinds() was just iterating through the list and returning the first match it found, which was the 64-bit register.<br>
><br>
><br>
><br>
> I added a special case to call RegisterContext::ConvertRegisterKindToRegisterNumber() when the target kind is eRegisterKindLLDB. This invokes the RegisterContext_x86_64 overload of that method which knows how to distinguish the 32-bit and 64-bit registers. I’m not convinced that this is the best way to solve this problem, but it works.<br>
><br>
><br>
><br>
> The second issue was that the ABIMacOSX_i386 plug-in (which also gets used for 32-bit inferiors on Linux) was rejecting call frame addresses that weren’t 8-byte aligned whereas, at least on Linux, 4-byte alignment is allowed. If 32-bit processes on MacOSX require 8-byte alignment then we’ll need to do some additional checking, but for now I just modified it to only check for 4-byte alignment.<br>
><br>
><br>
><br>
> Both of the stack unwinding issues should be fixed by the attached ‘stack-fix-32.patch’ file.<br>
><br>
><br>
><br>
> Can you try out these patches and verify that they work for you?<br>
><br>
><br>
><br>
> Thanks,<br>
><br>
> Andy<br>
><br>
><br>
><br>
> From: Michael Sartain [mailto:<a href="mailto:mikesart@gmail.com">mikesart@gmail.com</a>]<br>
><br>
> Sent: Tuesday, July 16, 2013 6:14 PM<br>
> To: Malea, Daniel; Kaylor, Andrew; Kopec, Matt; Thirumurthi, Ashok<br>
> Cc: Matthew Sorrels<br>
><br>
> Subject: Fwd: lldb test failures on 32bit<br>
><br>
><br>
><br>
> I think the below are the largest 32-bit blocking issues right now.<br>
><br>
><br>
><br>
> Is this something any of you have any familiarity with and have time to look at?<br>
><br>
><br>
><br>
> If not, let me know and I'll start investigating...<br>
><br>
><br>
><br>
> Thanks much!<br>
><br>
> -Mike<br>
><br>
><br>
><br>
> #################################<br>
><br>
> ## Can't call functions in target<br>
><br>
> #################################<br>
><br>
> mikesart@mikesart-rad:~/data/src/blah2/build$ lldb -x -- blah<br>
><br>
> Current executable set to 'blah' (i386).<br>
><br>
> (lldb) b main<br>
><br>
> Breakpoint 1: where = blah`main + 29 at blah.cpp:29, address = 0x0804884d<br>
><br>
> (lldb) r<br>
><br>
> Process 6745 launched: '/home/mikesart/data/src/blah2/build/blah' (i386)<br>
><br>
> Process 6745 stopped<br>
><br>
> * thread #1: tid = 0x1a59, 0x0804884d blah`main(argc=1, argv=0xfffc8c54) + 29 at blah.cpp:29, name = 'blah, stop reason = breakpoint 1.1<br>
><br>
> frame #0: 0x0804884d blah`main(argc=1, argv=0xfffc8c54) + 29 at blah.cpp:29<br>
><br>
> 26<br>
><br>
> 27 int main( int argc, char *argv[] )<br>
><br>
> 28 {<br>
><br>
> -> 29 printf("hello world.\n");<br>
><br>
> 30<br>
><br>
> 31 Set *foo = new Set();<br>
><br>
> 32<br>
><br>
> (lldb) expr (int)printf("hi there!\n");<br>
><br>
> error: Execution was interrupted, reason: invalid address (fault address: 0xeef60020).<br>
><br>
> The process has been returned to the state before expression evaluation.<br>
><br>
> (lldb) n<br>
><br>
> Process 6745 exited with status = -1 (0xffffffff)<br>
><br>
><br>
><br>
> #################################<br>
><br>
> ## Lose source with first next command<br>
><br>
> #################################<br>
><br>
> mikesart@mikesart-rad:~/data/src/blah2/build$ lldb -x -- blah<br>
><br>
> Current executable set to 'blah' (i386).<br>
><br>
> (lldb) b main<br>
><br>
> Breakpoint 1: where = blah`main + 29 at blah.cpp:29, address = 0x0804884d<br>
><br>
> (lldb) r<br>
><br>
> Process 7471 launched: '/home/mikesart/data/src/blah2/build/blah' (i386)<br>
><br>
> Process 7471 stopped<br>
><br>
> * thread #1: tid = 0x1d2f, 0x0804884d blah`main(argc=1, argv=0xffb36464) + 29 at blah.cpp:29, name = 'blah, stop reason = breakpoint 1.1<br>
><br>
> frame #0: 0x0804884d blah`main(argc=1, argv=0xffb36464) + 29 at blah.cpp:29<br>
><br>
> 26<br>
><br>
> 27 int main( int argc, char *argv[] )<br>
><br>
> 28 {<br>
><br>
> -> 29 printf("hello world.\n");<br>
><br>
> 30<br>
><br>
> 31 Set *foo = new Set();<br>
><br>
> 32<br>
><br>
> (lldb) n<br>
><br>
> Process 7471 stopped<br>
><br>
> * thread #1: tid = 0x1d2f, 0x080486f0 blah, name = 'blah, stop reason = step over<br>
><br>
> frame #0: 0x080486f0 blah<br>
><br>
> -> 0x80486f0: jmpl *134520844<br>
><br>
> 0x80486f6: pushl $24<br>
><br>
> 0x80486fb: jmp 0x80486b0 ; blah..plt + 0<br>
><br>
> 0x8048700: jmpl *134520848<br>
><br>
> (lldb)<br>
><br>
><br>
><br>
><br>
</div></div><div class=""><div class="h5">> _______________________________________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@cs.uiuc.edu">lldb-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
<br>
</div></div></blockquote></div><br></div></div></div></div>