https://sourceware.org/bugzilla/show_bug.cgi?id=19735
Bug ID: 19735 Summary: Incorrect handling of 0-PC-range FDEs Product: binutils Version: 2.27 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gold Assignee: ccoutant at gmail dot com Reporter: gluk47 at gmail dot com CC: ian at airs dot com Target Milestone: --- Created attachment 9044 --> https://sourceware.org/bugzilla/attachment.cgi?id=9044&action=edit Suggested solution There is a case in which gold produces binaries with broken exception handling, while ld.bfd produces correct binaries. If a function is of a non-void return type and its body is completely empty, then clang optimizer marks this function as unreachable and later shrinks its address range to zero (generates no assembly code, if using at least -O1). The FDEs (stack frame unwinder information entries) for such shrunk functions are not deleted, though, but instead, pc_begin and pc_end values for these FDEs are adjusted to be the same values, and PC range of the resulting FDE is 0. ld.bfd discards 0-range FDEs while reading object files (the code for it is in the file 'elf-eh-frame.c', function '_bfd_elf_parse_eh_frame'), while gold includes such entries as-is. Since these FDEs actually belong to the shrunk functions, there usually is another valid function starting with the address which is listed as PC_begin of the 0-range FDE, with its own FDE, containing valid unwinding information. However, the GCC's unwinder (from libgcc_s.so) uses only one FDE for a given PC_begin value (since normally no two different functions share the same starting address), which sometimes happens to be the 0-range FDE depending on the assembler layout. This FDE cannot be applied to any address because of its range; the valid FDE for the stack frame is ignored; the exception is not caught by the corresponding catch clause and eventually triggers std::terminate. It is not clear whether clang behavior is completely sane here; however, it appears reasonable to add a rather simple fix to gold to improve its compatibility with ld.bfd, and to improve its robustness. The original Android test case fixed by the supposed patch is here: https://android.googlesource.com/platform/ndk/+/master/tests/device/test-stlport_static-exception/jni/dyncast2_1.cpp To see the issue reproduced, you can compile the code below using ld.gold and ld.bfd and examine the result with 'readelf -wf'. In the gold-produced binary there will be a potentially faulty entry with zero range like 'pc=00000a10..00000a10' and later an FDE with the same starting address. int f() {} int main () { try { throw 1; return 1; } catch (int) { return 0; } return 2; } -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils