From 423d0643b91c946fe9820e2a14b80f402fc94d66 Mon Sep 17 00:00:00 2001 From: Dejan Jevtic Date: Fri, 27 Dec 2013 09:06:55 +0000 Subject: [PATCH] mips32: Adding mips32/Android support to Valgrind. Necessary changes to Valgrind to support mips32 on Android. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13767 --- README.android | 21 ++++++++++++++++ configure.ac | 6 ++--- coregrind/launcher-linux.c | 4 +++- coregrind/m_coredump/coredump-elf.c | 18 +++++++++----- coregrind/m_debuginfo/readstabs.c | 3 ++- coregrind/m_initimg/initimg-linux.c | 7 ++++-- coregrind/m_options.c | 3 ++- coregrind/m_replacemalloc/vg_replace_malloc.c | 8 ++++--- coregrind/m_syswrap/syswrap-linux.c | 9 ++++--- coregrind/m_syswrap/syswrap-main.c | 10 +++++++- coregrind/m_ume/main.c | 3 ++- coregrind/vg_preloaded.c | 3 ++- coregrind/vgdb.c | 3 ++- include/vki/vki-linux.h | 3 ++- shared/vg_replace_strmem.c | 24 ++++++++++++------- 15 files changed, 92 insertions(+), 33 deletions(-) diff --git a/README.android b/README.android index 82acd8d3c..2feb42b9a 100644 --- a/README.android +++ b/README.android @@ -13,6 +13,12 @@ ARM: x86: Android 4.0.3 running on android x86 emulator. +mips32: + Android 4.1.2 running on android mips emulator. + Android 4.2.2 running on android mips emulator. + Android 4.3 running on android mips emulator. + Android 4.0.4 running on BROADCOM bcm7425 + On android-arm, GDBserver might insert breaks at wrong addresses. Feedback on this welcome. @@ -70,6 +76,10 @@ export AR=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linu export LD=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linux-ld export CC=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linux-gcc +# For MIPS32 +export AR=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin/mipsel-linux-android-ar +export LD=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin/mipsel-linux-android-ld +export CC=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin/mipsel-linux-android-gcc # Do configuration stuff. Don't mess with the --prefix in the # configure command below, even if you think it's wrong. @@ -97,6 +107,13 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86 -DANDROID_HARDWARE_$HW --host=i686-android-linux --target=i686-android-linux \ --with-tmpdir=/sdcard +# for MIPS32 +CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips -DANDROID_HARDWARE_$HWKIND" \ + CFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ + ./configure --prefix=/data/local/Inst \ + --host=mipsel-linux-android --target=mipsel-linux-android \ + --with-tmpdir=/sdcard + # At the end of the configure run, a few lines of details # are printed. Make sure that you see these two lines: # @@ -108,6 +125,10 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86 -DANDROID_HARDWARE_$HW # Platform variant: android # Primary -DVGPV string: -DVGPV_x86_linux_android=1 # +# For mips32: +# Platform variant: android +# Primary -DVGPV string: -DVGPV_mips32_linux_android=1 +# # If you see anything else at this point, something is wrong, and # either the build will fail, or will succeed but you'll get something # which won't work. diff --git a/configure.ac b/configure.ac index 691c5b458..933b11bf4 100644 --- a/configure.ac +++ b/configure.ac @@ -957,9 +957,9 @@ DEFAULT_SUPP="exp-sgcheck.supp ${DEFAULT_SUPP}" # Normally the PLAT = (ARCH, OS) characterisation of the platform is enough. # But there are times where we need a bit more control. The motivating # and currently only case is Android: this is almost identical to -# {x86,arm}-linux, but not quite. So this introduces the concept of platform -# variant tags, which get passed in the compile as -DVGPV___ -# along with the main -DVGP__ definition. +# {x86,arm,mips}-linux, but not quite. So this introduces the concept of +# platform variant tags, which get passed in the compile as +# -DVGPV___ along with the main -DVGP__ definition. # # In almost all cases, the bit is "vanilla". But for Android # it is "android" instead. diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c index 8384564db..eafdb2b4f 100644 --- a/coregrind/launcher-linux.c +++ b/coregrind/launcher-linux.c @@ -222,7 +222,9 @@ static const char *select_platform(const char *clientname) platform = "mips64-linux"; } } else if (header[EI_DATA] == ELFDATA2MSB) { -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) \ + && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) if (ehdr->e_machine == EM_PPC64 && (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV || ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) { diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c index 65b706104..d5d64fbfd 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -136,7 +136,8 @@ static void fill_phdr(ESZ(Phdr) *phdr, const NSegment *seg, UInt off, Bool write phdr->p_align = VKI_PAGE_SIZE; } -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) /* Android's libc doesn't provide a definition for this. Hence: */ typedef struct { @@ -159,7 +160,8 @@ static UInt note_size(const struct note *n) + VG_ROUNDUP(n->note.n_descsz, 4); } -#if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +#if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) static void add_note(struct note **list, const HChar *name, UInt type, const void *data, UInt datasz) { @@ -605,7 +607,8 @@ void make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, ULong max_size) continue; # if defined(VGP_x86_linux) -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) { vki_elf_fpxregset_t xfpu; fill_xfpu(&VG_(threads)[i], &xfpu); @@ -615,18 +618,21 @@ void make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, ULong max_size) # endif fill_fpu(&VG_(threads)[i], &fpu); -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) add_note(¬elist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu)); # endif fill_prstatus(&VG_(threads)[i], &prstatus, si); -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) add_note(¬elist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus)); # endif } fill_prpsinfo(&VG_(threads)[tid], &prpsinfo); -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) add_note(¬elist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo)); # endif diff --git a/coregrind/m_debuginfo/readstabs.c b/coregrind/m_debuginfo/readstabs.c index 70ad31944..736ae820f 100644 --- a/coregrind/m_debuginfo/readstabs.c +++ b/coregrind/m_debuginfo/readstabs.c @@ -36,7 +36,8 @@ /* "on Linux (except android), or on Darwin" */ #if (defined(VGO_linux) && \ - !(defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)) \ + !(defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android)) \ || defined(VGO_darwin)) #include "pub_core_basics.h" diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 9bcc05cd2..2040cd52d 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -640,7 +640,9 @@ Addr setup_client_stack( void* init_sp, case AT_GID: case AT_EGID: case AT_CLKTCK: -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) \ + && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) case AT_FPUCW: /* missing on android */ # endif /* All these are pointerless, so we don't need to do @@ -670,7 +672,8 @@ Addr setup_client_stack( void* init_sp, So, keep the AT_BASE on android for now. ??? Need to dig in depth about AT_BASE/GDB interaction */ # if !defined(VGPV_arm_linux_android) \ - && !defined(VGPV_x86_linux_android) + && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) auxv->a_type = AT_IGNORE; # endif auxv->u.a_val = info->interp_base; diff --git a/coregrind/m_options.c b/coregrind/m_options.c index 4eb215c96..2163ebe31 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -47,7 +47,8 @@ VexControl VG_(clo_vex_control); Bool VG_(clo_error_limit) = True; Int VG_(clo_error_exitcode) = 0; -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) VgVgdb VG_(clo_vgdb) = Vg_VgdbNo; // currently disabled on Android #else VgVgdb VG_(clo_vgdb) = Vg_VgdbYes; diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index 8b53e88ab..85edbdafc 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -116,7 +116,7 @@ __attribute__ ((__noreturn__)) static inline void my_exit ( int x ) { -# if defined(VGPV_arm_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) __asm__ __volatile__(".word 0xFFFFFFFF"); while (1) {} # elif defined(VGPV_x86_linux_android) @@ -131,7 +131,8 @@ static inline void my_exit ( int x ) /* Same problem with getpagesize. */ static inline int my_getpagesize ( void ) { -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) return 4096; /* kludge - link failure on Android, for some reason */ # else extern int getpagesize (void); @@ -939,7 +940,8 @@ static inline void trigger_memcheck_error_if_undefined ( ULong x ) MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_usable_size); MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size); MALLOC_USABLE_SIZE(SO_SYN_MALLOC, malloc_size); -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size); MALLOC_USABLE_SIZE(SO_SYN_MALLOC, dlmalloc_usable_size); # endif diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index e91b2a90f..e8b516c2a 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -6764,7 +6764,8 @@ PRE(sys_ioctl) /* These just take an int by value */ break; -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) /* ashmem */ case VKI_ASHMEM_GET_SIZE: case VKI_ASHMEM_SET_SIZE: @@ -6957,7 +6958,8 @@ POST(sys_ioctl) /* --- BEGIN special IOCTL handlers for specific Android hardware --- */ -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) # if defined(ANDROID_HARDWARE_nexus_s) @@ -7875,7 +7877,8 @@ POST(sys_ioctl) } break; -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) /* ashmem */ case VKI_ASHMEM_GET_SIZE: case VKI_ASHMEM_SET_SIZE: diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 02e81a740..3cb20e184 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -467,7 +467,15 @@ void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical, #elif defined(VGP_mips32_linux) VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla; canonical->sysno = gst->guest_r2; // v0 - if (canonical->sysno != __NR_syscall) { + if (canonical->sysno == __NR_exit) { + canonical->arg1 = gst->guest_r4; // a0 + canonical->arg2 = 0; + canonical->arg3 = 0; + canonical->arg4 = 0; + canonical->arg5 = 0; + canonical->arg6 = 0; + canonical->arg8 = 0; + } else if (canonical->sysno != __NR_syscall) { canonical->arg1 = gst->guest_r4; // a0 canonical->arg2 = gst->guest_r5; // a1 canonical->arg3 = gst->guest_r6; // a2 diff --git a/coregrind/m_ume/main.c b/coregrind/m_ume/main.c index d40e216a2..7be6df101 100644 --- a/coregrind/m_ume/main.c +++ b/coregrind/m_ume/main.c @@ -199,7 +199,8 @@ static Bool is_binary_file(const HChar* f) // will refuse to (eg. scripts lacking a "#!" prefix). static Int do_exec_shell_followup(Int ret, const HChar* exe_name, ExeInfo* info) { -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) const HChar* default_interp_name = "/system/bin/sh"; # else const HChar* default_interp_name = "/bin/sh"; diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c index 263c61476..dba321408 100644 --- a/coregrind/vg_preloaded.c +++ b/coregrind/vg_preloaded.c @@ -57,7 +57,8 @@ void VG_NOTIFY_ON_LOAD(freeres)( void ); void VG_NOTIFY_ON_LOAD(freeres)( void ) { # if !defined(__UCLIBC__) \ - && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) + && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) extern void __libc_freeres(void); __libc_freeres(); # endif diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c index 08633bbc4..94b961662 100644 --- a/coregrind/vgdb.c +++ b/coregrind/vgdb.c @@ -689,7 +689,8 @@ void received_signal (int signum) sigpipe++; } else if (signum == SIGALRM) { sigalrm++; -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) /* Android has no pthread_cancel. As it also does not have an invoker implementation, there is no need for cleanup action. So, we just do nothing. */ diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index b3e2bd610..b78c9f547 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -2865,7 +2865,8 @@ struct vki_getcpu_cache { // From kernel/common/include/linux/ashmem.h //---------------------------------------------------------------------- -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) #define VKI_ASHMEM_NAME_LEN 256 diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c index a95634b8e..3dd5f80eb 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -144,7 +144,8 @@ Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen ) __attribute__ ((__noreturn__)) static inline void my_exit ( int x ) { -# if defined(VGPV_arm_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \ + || defined(VGPV_mips32_linux_android) __asm__ __volatile__(".word 0xFFFFFFFF"); while (1) {} # elif defined(VGPV_x86_linux_android) @@ -192,7 +193,8 @@ static inline void my_exit ( int x ) STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf) STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42) STRRCHR(VG_Z_LD_LINUX_SO_2, rindex) -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */ #endif @@ -414,7 +416,8 @@ static inline void my_exit ( int x ) STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42) STRLEN(VG_Z_LD_LINUX_SO_2, strlen) STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen) -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */ # endif @@ -527,7 +530,8 @@ static inline void my_exit ( int x ) #if defined(VGO_linux) -#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) STRLCPY(VG_Z_LIBC_SONAME, strlcpy); #endif @@ -599,7 +603,8 @@ static inline void my_exit ( int x ) } #if defined(VGO_linux) -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp) STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp) # endif @@ -636,7 +641,8 @@ static inline void my_exit ( int x ) } #if defined(VGO_linux) -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp) STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp) # endif @@ -748,7 +754,8 @@ static inline void my_exit ( int x ) STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42) STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp) STRCMP(VG_Z_LD64_SO_1, strcmp) -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) +# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ + || defined(VGPV_mips32_linux_android) STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */ # endif @@ -1612,7 +1619,8 @@ static inline void my_exit ( int x ) } #if defined(VGO_linux) -# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) +# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \ + && !defined(VGPV_mips32_linux_android) STRCASESTR(VG_Z_LIBC_SONAME, strcasestr) # endif