This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Exception Handling address comparison implementation error
- To: gcc at gcc dot gnu dot org
- Subject: Exception Handling address comparison implementation error
- From: David Edelsohn <dje at watson dot ibm dot com>
- Date: Sun, 30 Sep 2001 01:48:13 -0400
I finally tracked down why the revised C++ exception handling does
not work on AIX. The problem is not due to assumptions about sharing, but
assumptions about address ranges, which means the problem could affect any
port.
The revised Dwarf2 unwinding implementation sorts the FDEs. It
performs this using signed arithmetic on addresses:
(gcc/unwind-dw2-fde.c)
typedef int saddr __attribute__ ((mode (pointer)));
static saddr
fde_unencoded_compare (struct object *ob __attribute__((unused)),
fde *x, fde *y)
{
return *(saddr *)x->pc_begin - *(saddr *)y->pc_begin;
}
Later, fde_compare is invoked testing the sign of the result for
sorting:
fde_compare (ob, linear->array[i], *probe) < 0
fde_compare (ob, v1->array[i1-1], fde2) > 0
On AIX, the application text normally is loaded beginning at
0x10000000 and shared libraries text are loaded beginning at 0xd0000000.
When addresses in this range are compared and the result cast to a signed
integer, the values appear to have the wrong sign:
(gdb) print/x 0xd0b96608 - 0x10000340
$138 = 0xc0b962c8
(gdb) print (int) 0xd0b96608 - 0x10000340
$139 = -1061592376
This causes the current EH implementation to mis-sort the FDE list
which prevents it from finding the FDE for a particular range using a
binary search of an assumed-sorted list.
Assuming that text addresses do not flip the sign-bit is not a
safe assumption.
David
P.S. Loading the AIX shared libraries in the process private
segment covers up the problem by moving the shared library addresses into
the 0x20000000 range.