Non-returning functions and calls to them are not being processed properly by Dyninst on ppc/be. As a consequence, in the analysis results produced by Dyninst for a binary for AMG 2013, two functions and a long branch trampoline are fused into a single function, which leads to confusion in HPCToolkitâs hpcstruct.
The problem report below refers to two binaries: one called ungetc.ppc, which is a dynamic ppc/be binary for a main program that contains a single call to ungetc and a second binary amg2013.gnu.ppc, which is a statically linked binary for bg/q (ppc/be).
The binaries can be found here:
First a case that works: The call at 0x1001cd0 in the ungetc.ppc binary at the end of ._IO_ungetc is labeled as non-returning by the following line in Parser.C at line 1012 in my copy of Dyninst source:
is_nonret = obj().cs()->nonReturning(target);
The function nonReturning resolves the address to a ParseAPI::Function and then determines that a mangled name of that function (_Unwind_Resume) is in the table of names of non_returning_funcs defined in CodeSource.C
1001cd0: 48 07 20 71 bl 1073d40 <._Unwind_Resume> 1001cd4: 60 00 00 00 nop _IO_ungetc(): 1001cd8: 00 00 00 00 .long 0x0 1001cdc: 00 00 00 01 .long 0x1 1001ce0: 80 03 00 00 lwz r0,0(r3) __vmx__sigsetjmp_ent(): 1001ce4: 60 00 00 00 nop 1001ce8: 60 00 00 00 nop 1001cec: 60 00 00 00 nop
Now a case that doesnât work:
In the amg2013.gnu.ppc binary, the branch at 0x158d6b0, which is at the same spot in ._IO_ungetc, goes to a ppc long_branch trampoline that makes a tail call to _Unwind_Resume. This call is not classified as non-returning. As a result, there is a fall through edge that joins it to the branch trampoline for _IO_vfscanf that that follows ._IO_ungetc.
... 158d6b0: 4b ff fb 41 bl 158d1f0 <00008345.long_branch_r2off._Unwind_Resume+0> 158d6b4: e8 41 00 28 ld r2,40(r1) _IO_ungetc(): 158d6b8: 00 00 00 00 .long 0x0 158d6bc: 00 00 00 01 .long 0x1 158d6c0: 80 03 00 00 lwz r0,0(r3)
000000000158d6c4 <00008368.long_branch_r2off._IO_vfscanf+0>: 00008368.long_branch_r2off._IO_vfscanf+0(): 158d6c4: f8 41 00 28 std r2,40(r1) 158d6c8: 3c 42 00 01 addis r2,r2,1 158d6cc: 38 42 ff f8 addi r2,r2,-8 158d6d0: 48 05 a1 00 b 15e77d0 <._IO_vfscanf> 158d6d4: 60 00 00 00 nop 158d6d8: 60 00 00 00 nop 158d6dc: 60 00 00 00 nop
In fact, the same issue at then end of ._IO_setvbuf, which precedes ._IO_ungetc causes a fall through edge between ._IO_setvbuf and ._IO_ungetc.
The long_branch trampoline that is the target of the call at 0x158d6b0 is included below:
000000000158d1f0 <00008345.long_branch_r2off._Unwind_Resume+0>: 00008345.long_branch_r2off._Unwind_Resume+0(): 158d1f0: f8 41 00 28 std r2,40(r1) 158d1f4: 3c 42 ff ff addis r2,r2,-1 158d1f8: 38 42 00 08 addi r2,r2,8 158d1fc: 4b fd b0 f4 b 15682f0 <._Unwind_Resume>
It seems that non-returning status isn't properly being computed for functions. When I dump dyninst parseAPI functions and print their return status, I find that both _Unwind_Resume is listed as returning and the long branch trampoline at 0x158d1f0 that goes to ._Unwind_Resume is also listed as returning as well.
function targ158d1f0 RETURN [158d1f0,158d200) DIRECT --> 15682f0
function _Unwind_Resume RETURN [15682f0,15683b4) COND_TAKEN --> 15683b8 COND_NOT_TAKEN --> 15683b4 [15683b4,15683b8) FALLTHROUGH --> 15683b8 [15683b8,15683d8) CALL --> 1567970 CALL_FT --> 15683d8 ...
It seems that the ParseAPI::Function for _Unwind_Resume should be marked as non-returning since the name is identified as a non-returning function. If I understand the logic and how this should propagate, marking the parseAPI function for _Unwind_Resume as non-returning should cause the long-branch trampoline that ends in a tail call to it to be seen as non-returning, which would then cause the call to the long-branch trampoline as having no CALL_FT edge.
While the branch trampolines may contribute to bad propagation of knowledge about non-returning functions on ppc, the fact that the ParseAPI::Function for _Unwind_Resume is not marked as non-returning seems like a problem that transcends architecture.
-- John Mellor-Crummey Professor Dept of Computer Science Rice University email: johnmc@xxxxxxxx phone: 713-348-5179
|