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.