[Ltrace-devel] [PATCH] Fix SIGSEGV on MIPS big endian

Oliver Spornitz ospornit at rz-online.de
Sat Jan 26 22:59:32 UTC 2013


Hello,
on MIPS big endian, ltrace produces a SIGSEGV and only the first argument is decoded.

ltrace -iS hello looks like this:

[0x7706267c] SYS_mmap(0, , , )     = 0x77075000
[0x77064218] SYS_open(0x7fc3ffe0, , , ) = 3
[0x77064254] SYS_fstat(3, , , )      = 0
[0x77064328] SYS_mmap(0, , , )     = 0x77074000
[0x77064398] SYS_read(3, , , )    = 4096
[0x770645b8] SYS_mmap(0, , , )       = 0x77024000
[0x77064778] SYS_mmap(0x77024000, , , ) = 0x77024000
[0x770613d4] SYS_mmap(0x7705f000, , , )   = 0x7705f000
[0x77064938] SYS_close(3, , , ) = 0
[0x77064b00] SYS_munmap(0x77074000, , , ) = 0
[0x77064218] SYS_open(0x7fc3ffd0, , , ) = 3
[0x77064254] SYS_fstat(3, , , )      = 0
[0x77064328] SYS_mmap(0, , , )     = 0x77074000
[0x77064398] SYS_read(3, , , )    = 4096
[0x770645b8] SYS_mmap(0, , , )       = 0x76fb5000
[0x77064778] SYS_mmap(0x76fb5000, , , ) = 0x76fb5000
[0x770613d4] SYS_mmap(0x7701d000, , , )   = 0x7701d000
[0x770614c8] SYS_mmap(0x7701f000, , , ) = 0x7701f000
[0x77064938] SYS_close(3, , , ) = 0
[0x77064b00] SYS_munmap(0x77074000, , , ) = 0
[0x77064218] SYS_open(0x7fc3ffc0, , , ) = 3
[0x77064254] SYS_fstat(3, , , )      = 0
[0x770642f0] SYS_close(3, , , )      = 0
[0x77063eac] SYS_stat(0x77075544, , , ) = 0
[0x7706267c] SYS_mmap(0, , , )     = 0x77074000
[0x77062ed0] SYS_set_thread_area(0x7707b450, , , ) = 0
[0x77062570] SYS_mprotect(0x7701d000, , , ) = 0
[0x77062570] SYS_mprotect(0x77076000, , , ) = 0
[0x76fc143c] SYS_ioctl(0, , , ) = 0
[0x76fc143c] SYS_ioctl(1, , , ) = -1
[0x4000000] --- SIGSEGV (Segmentation fault) ---
[0xffffffff] +++ killed by SIGSEGV +++

This patch sets up the correct breakpoint opcode and endianness.
After applying the patch, it is necessary to run autoreconf.

Regards 
OS

diff --git a/configure.ac b/configure.ac
index 47bd87e..7aeac31 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,8 +41,12 @@ AC_SUBST(HOST_OS)
 case "${host_cpu}" in
     arm*|sa110)		HOST_CPU="arm" ;;
     cris*)		HOST_CPU="cris" ;;
-    mips*el)		HOST_CPU="mipsel" ;;
-    mips*)		HOST_CPU="mips" ;;
+    mips*el)		HOST_CPU="mipsel" 
+			AC_DEFINE([HAVE_ENDIAN_LITTLE], [1], [we have a little endian machine])                        
+			;;
+    mips*)		HOST_CPU="mips"
+			AC_DEFINE([HAVE_ENDIAN_BIG], [1], [we have a big endian machine])                                                 
+			;;
     powerpc|powerpc64)	HOST_CPU="ppc" ;;
     sun4u|sparc64)	HOST_CPU="sparc" ;;
     s390x)		HOST_CPU="s390" ;;
diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h
index ba1220d..6513c26 100644
--- a/sysdeps/linux-gnu/mipsel/arch.h
+++ b/sysdeps/linux-gnu/mipsel/arch.h
@@ -22,13 +22,24 @@
 #ifndef LTRACE_MIPS_ARCH_H
 #define LTRACE_MIPS_ARCH_H
 
+#include "config.h"
+
 #include <stddef.h>
 #include <gelf.h>
 
-#define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 }
+#ifdef HAVE_ENDIAN_LITTLE
+	#define BREAKPOINT_VALUE { 0x0d, 0x00, 0x00, 0x00 }
+	#define ARCH_ENDIAN_LITTLE
+#elif defined (HAVE_ENDIAN_BIG)
+	#define BREAKPOINT_VALUE { 0x00, 0x00, 0x00, 0x0d }
+	#define ARCH_ENDIAN_BIG
+#else
+	#error HAVE_ENDIAN_LITTLE or HAVE_ENDIAN_BIG must be defined
+#endif
+
 #define BREAKPOINT_LENGTH 4
 #define DECR_PC_AFTER_BREAK 0
-#define ARCH_ENDIAN_LITTLE
+
 
 #define LT_ELFCLASS	ELFCLASS32
 #define LT_ELF_MACHINE	EM_MIPS




More information about the Ltrace-devel mailing list