https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60406

--- Comment #9 from boger at us dot ibm.com ---
The patch to fix the recover.go problem causes significant regression in gccgo
when built for ppc64 (BE).  There are 32 unexpected failures in the gcc go
testsuite with the patch 32 unexpected failures in the gcc libgo testsuite. 
Without this patch on trunk there are 2 failures in the go testsuites and 1
failure in the libgo testsuite.

I did some debugging on one of the regression failures:  bug113.go.  I found
that the problem occurs in the new code in the patch in
go/gofrontend/statements.cc when creating the expression tree to call
__go_set_defering_fn.  The argument that is being passed is generated through a
call to make_func_code_reference:


      Expression* arg =
        Expression::make_func_code_reference(function, location);
      Expression* call = Runtime::make_call(Runtime::SET_DEFERING_FN,
                                            location, 1, arg);
      Statement* s = Statement::make_statement(call, true);
      s->determine_types();
      gogo->add_statement(s);


On ppc64le, this works as expected but on ppc64(be) the code that is generated
from this is not the address of the function but the address of the .opd entry
that is used to call the function.  As a result the setting of the deferring
function is incorrect and it does not appear as if it can recover because of
the way __go_can_recover uses the deferring function's address to see if it is
in the correct range.

When I debug this using gdb:

Breakpoint 1, __go_set_defering_fn (defering_fn=0x10020150 <main.$thunk0>) at
/home/boger/gccgo.work/140922/src/libgo/runtime/go-defer.c:78
78      {
Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7.ppc64
(gdb) info reg $r3
r3             0x10020150       268566864

>From the objdump, I see this address is in the .opd:
0000000010020150 <main.$thunk0>:
    10020150:   00 00 00 00     .long 0x0
    10020154:   10 00 1c 4c     vsro    v0,v0,v3
    10020158:   00 00 00 00     .long 0x0
    1002015c:   10 02 81 c0     .long 0x100281c0

but the code is actually here, which is the address that should be passed to
__go_set_defering_fn:
0000000010001c4c <.main.$thunk0>:
main.$thunk0():
    10001c4c:   7c 08 02 a6     mflr    r0
    10001c50:   f8 01 00 10     std     r0,16(r1)
    10001c54:   fb e1 ff f8     std     r31,-8(r1)
    10001c58:   f8 21 ff 71     stdu    r1,-144(r1)

Note that the actual function code address is in the first 8 bytes of the .opd
entry for the function.

Reply via email to