Retro68/gcc/libgloss/sparc/fixctors.c
2012-03-27 01:51:53 +02:00

55 lines
1.3 KiB
C

/* Code to byte-swap static constructor/destructor tables on
broken a.out little-endian targets. The startup code should call
__fix_ctors just before calling main. It is safe to use on non-broken
or big-endian targets. */
extern long __CTOR_LIST__[];
extern long __DTOR_LIST__[];
static void
byte_swap (long *entry)
{
unsigned char *p = (unsigned char *)entry;
unsigned char tmp;
tmp = p[0];
p[0] = p[3];
p[3] = tmp;
tmp = p[1];
p[1] = p[2];
p[2] = tmp;
}
static void
fix_table (long *table)
{
long len = table[0];
/* The heuristic for deciding if a table is broken is to examine
the word at the start of the table, which contains the number
of function pointers immediately following. If the low word
is zero, and the high word is non-zero, it's very likely that
it is byte-swapped. This test will fail if the program has
an exact multiple of 64K static constructors or destructors, a very
unlikely situation. */
if ((len & 0xffff) == 0 && (len & 0xffff0000) != 0)
{
/* The table looks broken. Byte-swap all the words in the table, up
to a NULL entry, which marks the end of the table. */
do
{
byte_swap (table);
table++;
}
while (*table);
}
}
void
__fix_ctors (void)
{
fix_table (__CTOR_LIST__);
fix_table (__DTOR_LIST__);
}