Hi,
Currently C++ exceptions don't work on PowerPC64 when compiled with clang. I
looked at why and discovered the following.
With the default gcc unwinder and libstdc++ this simple test program:
#include <iostream>
int main()
{
try {
std::cout << "Before\n";
throw std::exception();
std::cout << "After\n";
} catch (...) {
std::cout << "Exception\n";
}
}
segfaults right after printing "Before\n". This is because the .eh_frame is
corrupted and
the personality relocation is wrong:
< 1> version 1
cie section offset 56 0x00000038
augmentation zPLR
code_alignment_factor 4
data_alignment_factor -8
return_address_register 65
eh aug data len 0xb bytes 0x94 00 00 00 01 00 01 02 ed 14 1b
bytes of initial instructions 3
cie length 28
initial instructions
0 DW_CFA_def_cfa r1 0
the personality relocation is "00 00 00 01 00 01 02 ed" encoded as pc relative.
The program segfaults
because this address is wrong. The 33rd bit is incorrect, the real address
should be "00 00 00 00 00 01 02 ed".
The same problem applies for LDSA encoding. Both personality and LDSA
relocations are produced by CFI instructions
in the assembler source code.
I verified this theory by hacking the gcc unwinder and libsupc++ &= the address
with 0xffffffff; and that made
the application work. (the full patch can be found at
http://www.vlakno.cz/~rdivacky/ppc64.exceptions.hack.patch).
I checked why this relocation is wrong and it turns out it's our old in-tree ld
that (wrongly) produces this.
Our old gcc does not use CFI to produce these and hardcodes the CIE manually
and produces correct address. And for
some reason ld is fine with that.
When I compile and assemble the above source code using clang++ and only use
newer ld linker from ports the resulting
binary is correct and works as expected.
So this is a bug in our in-tree ld linker. I don't know why ld has this bug but
given Mark Millard's report of ld
being broken for other stuff (kernel iirc) I am not going to bother trying to
fix it. I suspect it might be related
to comdats but I didn't really investigate.
I didn't try the situation with the LLVM unwinder and libcxxrt, but I hope it
might be the same.
Thank you, Roman
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to "[email protected]"