[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug gold/19735] New: Incorrect handling of 0-PC-range FDEs
From: |
gluk47 at gmail dot com |
Subject: |
[Bug gold/19735] New: Incorrect handling of 0-PC-range FDEs |
Date: |
Fri, 26 Feb 2016 12:19:42 +0000 |
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 gold/19735] New: Incorrect handling of 0-PC-range FDEs,
gluk47 at gmail dot com <=