Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libgloss/sparc/fixctors.c')
-rw-r--r--libgloss/sparc/fixctors.c54
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__);
+}