diff options
author | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
---|---|---|
committer | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
commit | 03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch) | |
tree | 7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/sparc/fixctors.c | |
parent | fae4c299f14fc23e2829c8656992eba21f79242a (diff) | |
download | cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2 cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip |
20000317 sourceware import
Diffstat (limited to 'libgloss/sparc/fixctors.c')
-rw-r--r-- | libgloss/sparc/fixctors.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/libgloss/sparc/fixctors.c b/libgloss/sparc/fixctors.c new file mode 100644 index 000000000..484023c7a --- /dev/null +++ b/libgloss/sparc/fixctors.c @@ -0,0 +1,54 @@ +/* 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__); +} |