Fixed dynamic linking on x86
authorAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Sat, 5 Nov 2011 02:05:10 +0000 (19:05 -0700)
committerAndrew Waterman <waterman@s144.Millennium.Berkeley.EDU>
Sat, 5 Nov 2011 02:05:10 +0000 (19:05 -0700)
Some changes in binutils made ld.so reject
our libraries as having an invalid ABI.
Also, we have to avoid using recursive
spinlocks (which use __thread) while inside
ld.so before __thread is valid.

tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/bits/libc-lock.h
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/ldsodefs.h [new file with mode: 0644]

index a77da81..39943b9 100644 (file)
@@ -107,6 +107,8 @@ do {\
        ({ lll_lock (NAME, LLL_PRIVATE); 0; })
 
 /* Lock the recursive named lock variable.  */
        ({ lll_lock (NAME, LLL_PRIVATE); 0; })
 
 /* Lock the recursive named lock variable.  */
+#ifndef IS_IN_rtld
+
 # define __libc_lock_lock_recursive(NAME)\
 do {\
        void *self = THREAD_SELF;\
 # define __libc_lock_lock_recursive(NAME)\
 do {\
        void *self = THREAD_SELF;\
@@ -117,6 +119,23 @@ do {\
        ++(NAME).count;\
 } while (0)
 
        ++(NAME).count;\
 } while (0)
 
+/* Unlock the recursive named lock variable.  */
+/* We do no error checking here.  */
+# define __libc_lock_unlock_recursive(NAME)\
+       do {\
+               if(--(NAME).count == 0) {\
+                       (NAME).owner = NULL;\
+                       lll_unlock((NAME).lock, LLL_PRIVATE);\
+               }\
+       } while (0)
+
+#else /* Ignore recursive locks within rtld */
+
+# define __libc_lock_lock_recursive(NAME) do { } while(0)
+# define __libc_lock_unlock_recursive(NAME) do { } while(0)
+
+#endif
+
 /* Try to lock the named lock variable.  */
 #define __libc_lock_trylock(NAME)\
        lll_trylock(NAME)
 /* Try to lock the named lock variable.  */
 #define __libc_lock_trylock(NAME)\
        lll_trylock(NAME)
@@ -143,16 +162,6 @@ do {\
 #define __libc_lock_unlock(NAME)\
        lll_unlock (NAME, LLL_PRIVATE)
 
 #define __libc_lock_unlock(NAME)\
        lll_unlock (NAME, LLL_PRIVATE)
 
-/* Unlock the recursive named lock variable.  */
-/* We do no error checking here.  */
-# define __libc_lock_unlock_recursive(NAME)\
-       do {\
-               if(--(NAME).count == 0) {\
-                       (NAME).owner = NULL;\
-                       lll_unlock((NAME).lock, LLL_PRIVATE);\
-               }\
-       } while (0)
-
 #define __libc_lock_default_lock_recursive(lock)\
        ++((__libc_lock_recursive_t *)(lock))->count;
 #define __libc_lock_default_unlock_recursive(lock)\
 #define __libc_lock_default_lock_recursive(lock)\
        ++((__libc_lock_recursive_t *)(lock))->count;
 #define __libc_lock_default_unlock_recursive(lock)\
diff --git a/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/ldsodefs.h b/tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/ldsodefs.h
new file mode 100644 (file)
index 0000000..1ee849d
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _ROS_LDSODEFS_H
+#define _ROS_LDSODEFS_H
+
+#define HAVE_AUX_VECTOR
+
+/* More recent versions of binutils mark SysV objects as Linux objects
+ * if they use certain GNU extensions (which we do).  We could solve
+ * this problem directly by declaring and using ELFOSABI_AKAROS,
+ * but that requires changes to all of GCC, BFD, GAS and GLIBC.
+ * Instead, we take the easy way out: accept all SysV and Linux objects.
+ * Most importantly, both Kevin and Andrew concur on this matter. */
+
+#define VALID_ELF_HEADER(hdr, exp, size) \
+  ({                                                              \
+    static const unsigned char ros_expected[EI_NIDENT] =          \
+    {                                                             \
+      [EI_MAG0] = ELFMAG0,                                        \
+      [EI_MAG1] = ELFMAG1,                                        \
+      [EI_MAG2] = ELFMAG2,                                        \
+      [EI_MAG3] = ELFMAG3,                                        \
+      [EI_CLASS] = ELFW(CLASS),                                   \
+      [EI_DATA] = byteorder,                                      \
+      [EI_VERSION] = EV_CURRENT,                                  \
+      [EI_OSABI] = ELFOSABI_LINUX,                                \
+      [EI_ABIVERSION] = 0                                         \
+    };                                                            \
+    !memcmp(hdr, ros_expected, size) || !memcmp(hdr, exp, size);  \
+  })
+
+#define VALID_ELF_OSABI(osabi) \
+  ((osabi) == ELFOSABI_SYSV || (osabi) == ELFOSABI_LINUX)
+
+#define VALID_ELF_ABIVERSION(osabi,ver) (ver == 0)
+
+#include_next <ldsodefs.h>
+
+#endif