[git commit 0_9_30] The attached patches fixes the problems found bringing up uclibc on coldfire M5485 processor

Khem Raj kraj at mvista.com
Sat Oct 10 16:44:02 UTC 2009


commit: http://git.uclibc.org/uClibc/commit/?id=9974db095b31a2dbef231c0437c0a7ea1d46dfd8
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/0_9_30

1.  Disable mmap2() if we're compiling for coldfire and fall back to mmap().
    It seems to map a different file area on a 2.6.25 linux kernel.

2.  Uses pc-relative addresing[1], computes ADDR_ALIGN, PAGE_ALIGN
    and OFFSET_ALIGN relatively to _dl_pagesize[3].
    On coldfire/M5485 _dl_pagesize is 0x2000.

Signed-off-by: Groleo Marius <groleo at gmail.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
---
 ldso/include/dl-syscall.h                          |    4 ++--
 ldso/ldso/m68k/dl-startup.h                        |   15 +++++++++++++--
 ldso/ldso/m68k/dl-sysdep.h                         |   20 +++++++++++++++-----
 .../linuxthreads.old/sysdeps/m68k/pt-machine.h     |    2 +-
 4 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index 1cbbbad..0b0b0ef 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -152,7 +152,7 @@ static __always_inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
 # define __NR__dl_mmap __NR_mmap
 static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
                         int, prot, int, flags, int, fd, off_t, offset);
-
+#if !defined (__mcoldfire__) // Might be a kernel problem. failed on 2.6.25
 /* then try mmap2() */
 #elif defined(__NR_mmap2)
 
@@ -176,7 +176,7 @@ static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot
 	return __syscall_mmap2(addr, size, prot, flags,
 	                       fd, (off_t) (offset >> MMAP2_PAGE_SHIFT));
 }
-
+#endif
 /* finally, fall back to mmap(), syscall1() style */
 #elif defined(__NR_mmap)
 
diff --git a/ldso/ldso/m68k/dl-startup.h b/ldso/ldso/m68k/dl-startup.h
index 2ed9ead..29b1ff3 100644
--- a/ldso/ldso/m68k/dl-startup.h
+++ b/ldso/ldso/m68k/dl-startup.h
@@ -4,6 +4,17 @@
  * Copyright (C) 2005 by Erik Andersen <andersen at codepoet.org>
  */
 
+/* Perform operation OP with PC-relative SRC as the first operand and
+ * DST as the second.  TMP is available as a temporary if needed.  */
+
+#ifdef __mcoldfire__
+#define PCREL_OP(OP, SRC, DST, TMP, PC) \
+  "move.l #" SRC " - ., " TMP "\n\t" OP " (-8, " PC ", " TMP "), " DST
+#else
+#define PCREL_OP(OP, SRC, DST, TMP, PC) \
+  OP " " SRC "(" PC "), " DST
+#endif
+
 __asm__ ("\
 	.text\n\
 	.globl _start\n\
@@ -21,7 +32,7 @@ _dl_start_user:\n\
 	move.l %d0, %a4\n\
 	# See if we were run as a command with the executable file\n\
 	# name as an extra leading argument.\n\
-	move.l _dl_skip_args(%pc), %d0\n\
+	" PCREL_OP ("move.l", "_dl_skip_args", "%d0", "%d0", "%pc") "\n\
 	# Pop the original argument count\n\
 	move.l (%sp)+, %d1\n\
 	# Subtract _dl_skip_args from it.\n\
@@ -31,7 +42,7 @@ _dl_start_user:\n\
 	# Push back the modified argument count.\n\
 	move.l %d1, -(%sp)\n\
 	# Pass our finalizer function to the user in %a1.\n\
-	lea _dl_fini(%pc), %a1\n\
+	" PCREL_OP ("lea", "_dl_fini", "%a1", "%a1", "%pc") "\n\
 	# Initialize %fp with the stack pointer.\n\
 	move.l %sp, %fp\n\
 	# Jump to the user's entry point.\n\
diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h
index c0e529e..af5cbdd 100644
--- a/ldso/ldso/m68k/dl-sysdep.h
+++ b/ldso/ldso/m68k/dl-sysdep.h
@@ -39,19 +39,29 @@ extern unsigned long _dl_linux_resolver (struct elf_resolve *, int);
 static __always_inline Elf32_Addr
 elf_machine_dynamic (void)
 {
-	register Elf32_Addr *got __asm__ ("%a5");
-	return *got;
+	Elf32_Addr got;
+
+	__asm__ ("move.l _DYNAMIC at GOT.w(%%a5), %0"
+			: "=a" (got));
+	return got;
 }
 
+#ifdef __mcoldfire__
+#define PCREL_OP(OP, SRC, DST, TMP, PC) \
+  "move.l #" SRC " - ., " TMP "\n\t" OP " (-8, " PC ", " TMP "), " DST
+#else
+#define PCREL_OP(OP, SRC, DST, TMP, PC) \
+  OP " " SRC "(" PC "), " DST
+#endif
 
 /* Return the run-time load address of the shared object.  */
 static __always_inline Elf32_Addr
 elf_machine_load_address (void)
 {
 	Elf32_Addr addr;
-	__asm__ ("lea _dl_start(%%pc), %0\n\t"
-	     "sub.l _dl_start at GOT.w(%%a5), %0"
-	     : "=a" (addr));
+	__asm__ (PCREL_OP ("lea", "_dl_start", "%0", "%0", "%%pc") "\n\t"
+			"sub.l _dl_start at GOT.w(%%a5), %0"
+			: "=a" (addr));
 	return addr;
 }
 
diff --git a/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h
index 295495b..f9cf530 100644
--- a/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h
+++ b/libpthread/linuxthreads.old/sysdeps/m68k/pt-machine.h
@@ -40,7 +40,7 @@ testandset (int *spinlock)
 #else
          "bset #7,%1; sne %0"
 #endif
-       : "=dm"(ret), "=m"(*spinlock)
+       : "=&dm"(ret), "=m"(*spinlock)
        : "m"(*spinlock)
        : "cc");
 
-- 
1.6.3.3



More information about the uClibc-cvs mailing list