Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible slicing/frame issue #44

Closed
jdetter opened this issue May 12, 2016 · 3 comments
Closed

Possible slicing/frame issue #44

jdetter opened this issue May 12, 2016 · 3 comments
Labels

Comments

@jdetter
Copy link
Contributor

jdetter commented May 12, 2016

While dissassembling stdlibc++.so on Fedora 21, I ran into an issue with an instruction (non VEX) we didn't have implemented (rdrand). I implemented that instruction and now it appears dyninst is running into a slicing issue.

The binary I am disassembling is available here.

The function that contains the issue starts at 0x8d710. Dyninst knows that this function starts at 0x8d710, however the disassembly for that function starts at 0x8d6f0, which doesn't seem right to me.

Dyninst (dyn_dump) output:

000000000008d700 <targ8d700>:
    0x8d6f0 48 8b 7         mov RAX, [RDI]
    0x8d6f3 48 85 c0        test RAX, RAX
    0x8d6f6 74 5            jz 5 + RIP + 2
    0x8d6f8 f0 83 40 80 1   add [RAX + ffffffffffffff80], 1
    0x8d6fd f3 c3           REP ret near [RSP]
    0x8d700 48 89 37        mov [RDI], RSI
    0x8d703 e9 e8 ff ff ff  jmp ffffffe8 + RIP + 5

000000000008d710 <std::__exception_ptr::exception_ptr::exception_ptr>:
    0x8d6f0 48 8b 7         mov RAX, [RDI]
    0x8d6f3 48 85 c0        test RAX, RAX
    0x8d6f6 74 5            jz 5 + RIP + 2
    0x8d6f8 f0 83 40 80 1   add [RAX + ffffffffffffff80], 1
    0x8d6fd f3 c3           REP ret near [RSP]
    0x8d710 48 8b 6         mov RAX, [RSI]
    0x8d713 48 89 7         mov [RDI], RAX
    0x8d716 e9 d5 ff ff ff  jmp ffffffd5 + RIP + 5

000000000008d760 <std::__exception_ptr::exception_ptr::~exception_ptr>:
    0x8d720 48 8b 7         mov RAX, [RDI]
    0x8d723 48 85 c0        test RAX, RAX
    0x8d726 74 29           jz 29 + RIP + 2
    0x8d728 f0 83 68 80 1   No_Entry [RAX + ffffffffffffff80], 1  (I'm working on this right now)
    0x8d751 f3 c3           REP ret near [RSP]
    0x8d760 e9 bb ff ff ff  jmp ffffffbb + RIP + 5

The objdump output is a little strange as well, because the function should only really be the first 3 lines because of the unconditional jump. Not sure what's going on here either. Objdump however does start at the correct address, 0x8d710.

objdump output:

000000000008d710 <_ZNSt15__exception_ptr13exception_ptrC1ERKS0_>:
   8d710:   48 8b 06                mov    rax,QWORD PTR [rsi]
   8d713:   48 89 07                mov    QWORD PTR [rdi],rax
   8d716:   e9 d5 ff ff ff          jmp    8d6f0 <_ZNSt15__exception_ptr13exception_ptrC1EMS0_FvvE+0x10>
   8d71b:   0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]
   8d720:   48 8b 07                mov    rax,QWORD PTR [rdi]
   8d723:   48 85 c0                test   rax,rax
   8d726:   74 29                   je     8d751 <_ZNSt15__exception_ptr13exception_ptrC1ERKS0_+0x41>
   8d728:   f0 83 68 80 01          lock sub DWORD PTR [rax-0x80],0x1
   8d72d:   75 22                   jne    8d751 <_ZNSt15__exception_ptr13exception_ptrC1ERKS0_+0x41>
   8d72f:   53                      push   rbx
   8d730:   48 8b 40 98             mov    rax,QWORD PTR [rax-0x68]
   8d734:   48 89 fb                mov    rbx,rdi
   8d737:   48 85 c0                test   rax,rax
   8d73a:   74 05                   je     8d741 <_ZNSt15__exception_ptr13exception_ptrC1ERKS0_+0x31>
   8d73c:   48 8b 3f                mov    rdi,QWORD PTR [rdi]
   8d73f:   ff d0                   call   rax
   8d741:   48 8b 3b                mov    rdi,QWORD PTR [rbx]
   8d744:   e8 57 97 ff ff          call   86ea0 <__cxa_free_exception@plt>
   8d749:   48 c7 03 00 00 00 00    mov    QWORD PTR [rbx],0x0
   8d750:   5b                      pop    rbx
   8d751:   f3 c3                   repz ret
   8d753:   66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
   8d75a:   00 00 00
   8d75d:   0f 1f 00                nop    DWORD PTR [rax]

If this is intentional behavior that I'm unaware of, this can be closed.

@mxz297
Copy link
Member

mxz297 commented May 12, 2016

After some careful looking, I don't believe this is an issue. The function truly starts at 0x8d710 and then it jumps to 0x8d6f0. This jump at 0x8d6f0 may or may not in fact be a tail call, but at least our current tail call identification code says it is not a tail call. Therefore, code at 0x8d6f0 is also considered parts of the function starting at 0x8d710.

The takeaway is that Dyninst allows the cases where the function entry is not the lowest address of a function, while objdump does not.

@mxz297 mxz297 closed this as completed May 12, 2016
@cuviper
Copy link
Contributor

cuviper commented May 12, 2016

The objdump output is a little strange as well, because the function should only really be the first 3 lines because of the unconditional jump.

Well, objdump is not trying to be clever about where the function ends. It just splits based on the symbol table, and the stripped binary doesn't tell about unexported symbols. Your file has one symbol at 8d710 and another at 8d760, so that's all objdump considers.

So I guess dyn_dump is trying to be more clever. It doesn't know that 8d6f0 was originally an unexported function, but from the unconditional jump it associates that block as part of the 8d710 function, rather than realizing this is a tail-call jump.

However it did synthesize targ8d700, so maybe it should have called 8d710 a tail-call into that.

@cuviper
Copy link
Contributor

cuviper commented May 12, 2016

If you had libstdc++.so's debuginfo, from gcc-base-debuginfo, then hopefully dyn_dump would now see those unexported functions and realize all of the tail calls.
(But objdump doesn't implicitly read debuginfo, only the object at hand.)

@wrwilliams wrwilliams added the bug label Apr 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants