aboutsummaryrefslogtreecommitdiffstats
path: root/recipes
diff options
context:
space:
mode:
authorTom Rini <tom_rini@mentor.com>2011-06-16 10:35:13 -0700
committerTom Rini <tom_rini@mentor.com>2011-06-16 10:37:51 -0700
commit54a91b395715d1daf0970fece9bb9a048c8517df (patch)
treebf43ec064d52ca041850a6c501e8c0f813768109 /recipes
parent814c44486da264ac865b63952e2e41069aa7ca6e (diff)
downloadopenembedded-54a91b395715d1daf0970fece9bb9a048c8517df.tar.gz
valgrind: Add patch for PowerPC target support, update recipe
The support patch has been merged upstream. Patch found via oe-lite: http://git.doredevelopment.dk/?p=oe-lite/base.git;a=commitdiff;h=6b00807cadec3dd8978d0297181c67f81ec37706 Signed-off-by: Tom Rini <tom_rini@mentor.com>
Diffstat (limited to 'recipes')
-rw-r--r--recipes/valgrind/valgrind-3.6.1/vg-ppc-feature.patch390
-rw-r--r--recipes/valgrind/valgrind.inc3
-rw-r--r--recipes/valgrind/valgrind_3.6.1.bb6
3 files changed, 397 insertions, 2 deletions
diff --git a/recipes/valgrind/valgrind-3.6.1/vg-ppc-feature.patch b/recipes/valgrind/valgrind-3.6.1/vg-ppc-feature.patch
new file mode 100644
index 0000000000..dd2962126b
--- /dev/null
+++ b/recipes/valgrind/valgrind-3.6.1/vg-ppc-feature.patch
@@ -0,0 +1,390 @@
+This comes from http://bugs.kde.org/show_bug.cgi?id=259977 and is merged
+upstream.
+
+diff -paur valgrind/coregrind/m_machine.c vg-ppc-feature-fix/coregrind/m_machine.c
+--- valgrind/coregrind/m_machine.c 2010-12-10 08:47:00.000000000 -0600
++++ vg-ppc-feature-fix/coregrind/m_machine.c 2010-12-10 11:35:57.410487338 -0600
+@@ -387,20 +387,102 @@ Int VG_(machine_arm_archlevel) = 4;
+ /* For hwcaps detection on ppc32/64 and arm we'll need to do SIGILL
+ testing, so we need a jmp_buf. */
+ #if defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm)
+-#include <setjmp.h> // For jmp_buf
+-static jmp_buf env_unsup_insn;
+-static void handler_unsup_insn ( Int x ) { __builtin_longjmp(env_unsup_insn,1); }
++#include <elf.h>
++#include <link.h>
++#include <unistd.h>
++#include "pub_tool_libcproc.h"
++
++#ifndef AT_BASE_PLATFORM
++#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
++#endif
++
++ #define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */
++ #define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */
++ #define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */
++ #define PPC_FEATURE_HAS_ALTIVEC 0x10000000 /* SIMD/Vector Unit. */
++ #define PPC_FEATURE_HAS_FPU 0x08000000 /* Floating Point Unit. */
++ #define PPC_FEATURE_HAS_MMU 0x04000000 /* Memory Management Unit. */
++ #define PPC_FEATURE_HAS_4xxMAC 0x02000000 /* 4xx Multiply Accumulator. */
++ #define PPC_FEATURE_UNIFIED_CACHE 0x01000000 /* Unified I/D cache. */
++ #define PPC_FEATURE_HAS_SPE 0x00800000 /* Signal Processing ext. */
++ #define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 /* SPE Float. */
++ #define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 /* SPE Double. */
++ #define PPC_FEATURE_NO_TB 0x00100000 /* 601/403gx have no timebase. */
++ #define PPC_FEATURE_POWER4 0x00080000 /* POWER4 ISA 2.01. */
++ #define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02. */
++ #define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03. */
++ #define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */
++ #define PPC_FEATURE_BOOKE 0x00008000 /* ISA Embedded Category. */
++ #define PPC_FEATURE_SMT 0x00004000 /* Simultaneous Multi-Threading. */
++ #define PPC_FEATURE_ICACHE_SNOOP 0x00002000
++ #define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05. */
++ #define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core. */
++ #define PPC_FEATURE_HAS_DFP 0x00000400 /* Decimal FP Unit. */
++ #define PPC_FEATURE_POWER6_EXT 0x00000200 /* P6 + mffgpr/mftgpr. */
++ #define PPC_FEATURE_ARCH_2_06 0x00000100 /* ISA 2.06. */
++ #define PPC_FEATURE_HAS_VSX 0x00000080 /* P7 Vector Scalar Extension. */
++
++/* Scan the env to find the aux vector. */
++static inline Char** __auxv_find(void)
++{
++ Char **result = VG_(client_envp);
++ /* Scan over the env vector looking for the ending NULL */
++ for (; *result != NULL; ++result)
++ {
++ }
++ /* Bump the pointer one more step, which should be the auxv. */
++ return ++result;
++}
++
++static unsigned long fetch_at_hwcap(void)
++{
++ static unsigned long auxv_hwcap = 0;
++ Int i;
++ ElfW(auxv_t) *auxv_buf = NULL;
++
++ if (auxv_hwcap)
++ return auxv_hwcap;
++
++ auxv_buf = (ElfW(auxv_t)*) __auxv_find();
++ /* If someone has done a setenv() the __environ pointer may
++ have been moved and the assumption that the auxv follows is
++ not true. So look at the first entry and verify that it is
++ an auxv entry. */
++ if (!auxv_buf || auxv_buf->a_type == AT_NULL)
++ return 0;
++
++ for (i = 0; auxv_buf[i].a_type != AT_NULL; i++)
++ if (auxv_buf[i].a_type == AT_HWCAP)
++ {
++ auxv_hwcap = auxv_buf[i].a_un.a_val;
++ break;
++ }
++
++ return auxv_hwcap;
++}
++
++static Bool has_powerpc_feature(unsigned long feature)
++{
++ unsigned long hwcap = fetch_at_hwcap();
++
++ return (hwcap & feature) ? True : False;
++}
++
+ #endif
+
+
+-/* Helper function for VG_(machine_get_hwcaps), assumes the SIGILL/etc
+- * handlers are installed. Determines the the sizes affected by dcbz
+- * and dcbzl instructions and updates the given VexArchInfo structure
+- * accordingly.
++/* Helper function for VG_(machine_get_hwcaps) to determine the
++ * the sizes affected by dcbz and dcbzl instructions and updates the
++ * given VexArchInfo structure accordingly.
++ *
++ * According to former PowerPC kernel maintainer, Paul Mackerras:
++ * "The dcbzl instruction is dcbz with bit 10 set to 1. It's an Apple-specific
++ * hack in the PPC970 family. There is a bit in a HID register to make the normal
++ * dcbz instruction clear only 32 bytes, and then the dcbz with bit 10 set to 1
++ * would clear a whole cache line (128 bytes). Since bit 10 is in a reserved field
++ * in the dcbz instruction, other processors should ignore it."
+ *
+- * Not very defensive: assumes that as long as the dcbz/dcbzl
+- * instructions don't raise a SIGILL, that they will zero an aligned,
+- * contiguous block of memory of a sensible size. */
++ */
+ #if defined(VGA_ppc32) || defined(VGA_ppc64)
+ static void find_ppc_dcbz_sz(VexArchInfo *arch_info)
+ {
+@@ -428,24 +510,22 @@ static void find_ppc_dcbz_sz(VexArchInfo
+ }
+ vg_assert(dcbz_szB == 32 || dcbz_szB == 64 || dcbz_szB == 128);
+
+- /* dcbzl clears 128B on G5/PPC970, and usually 32B on other platforms */
+- if (__builtin_setjmp(env_unsup_insn)) {
+- dcbzl_szB = 0; /* indicates unsupported */
+- }
+- else {
+- VG_(memset)(test_block, 0xff, sizeof(test_block));
+- /* some older assemblers won't understand the dcbzl instruction
+- * variant, so we directly emit the instruction ourselves */
+- __asm__ __volatile__("mr 9, %0 ; .long 0x7C204FEC" /*dcbzl 0,9*/
+- : /*out*/
+- : "r" (aligned) /*in*/
+- : "memory", "r9" /*clobber*/);
+- for (dcbzl_szB = 0, i = 0; i < sizeof(test_block); ++i) {
+- if (!test_block[i])
+- ++dcbzl_szB;
+- }
+- vg_assert(dcbzl_szB == 32 || dcbzl_szB == 64 || dcbzl_szB == 128);
++ VG_(memset)(test_block, 0xff, sizeof(test_block));
++ /* some older assemblers won't understand the dcbzl instruction
++ * variant, so we directly emit the instruction ourselves.
++ * This is done on the assumption that ALL processors other than
++ * ppc970-based Apples should ignore bit 10 being set for the
++ * dcbz instruction.
++ * */
++ __asm__ __volatile__("mr 9, %0 ; .long 0x7C204FEC" /*dcbzl 0,9*/
++ : /*out*/
++ : "r" (aligned) /*in*/
++ : "memory", "r9" /*clobber*/);
++ for (dcbzl_szB = 0, i = 0; i < sizeof(test_block); ++i) {
++ if (!test_block[i])
++ ++dcbzl_szB;
+ }
++ vg_assert(dcbzl_szB == 32 || dcbzl_szB == 64 || dcbzl_szB == 128);
+
+ arch_info->ppc_dcbz_szB = dcbz_szB;
+ arch_info->ppc_dcbzl_szB = dcbzl_szB;
+@@ -605,106 +685,28 @@ Bool VG_(machine_get_hwcaps)( void )
+
+ #elif defined(VGA_ppc32)
+ {
+- /* Find out which subset of the ppc32 instruction set is supported by
+- verifying whether various ppc32 instructions generate a SIGILL
+- or a SIGFPE. An alternative approach is to check the AT_HWCAP and
+- AT_PLATFORM entries in the ELF auxiliary table -- see also
+- the_iifii.client_auxv in m_main.c.
+- */
+- vki_sigset_t saved_set, tmp_set;
+- vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
+- vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act;
+-
+- volatile Bool have_F, have_V, have_FX, have_GX;
+- Int r;
+-
+- /* This is a kludge. Really we ought to back-convert saved_act
+- into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
+- since that's a no-op on all ppc32 platforms so far supported,
+- it's not worth the typing effort. At least include most basic
+- sanity check: */
+- vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
+-
+- VG_(sigemptyset)(&tmp_set);
+- VG_(sigaddset)(&tmp_set, VKI_SIGILL);
+- VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
+
+- r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+- vg_assert(r == 0);
+-
+- r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
+- vg_assert(r == 0);
+- tmp_sigill_act = saved_sigill_act;
+-
+- r = VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
+- vg_assert(r == 0);
+- tmp_sigfpe_act = saved_sigfpe_act;
+-
+- /* NODEFER: signal handler does not return (from the kernel's point of
+- view), hence if it is to successfully catch a signal more than once,
+- we need the NODEFER flag. */
+- tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
+- tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
+- tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
+- tmp_sigill_act.ksa_handler = handler_unsup_insn;
+- r = VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
+- vg_assert(r == 0);
+-
+- tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
+- tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
+- tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER;
+- tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
+- r = VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
+- vg_assert(r == 0);
+-
+- /* standard FP insns */
+- have_F = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_F = False;
+- } else {
+- __asm__ __volatile__(".long 0xFC000090"); /*fmr 0,0 */
+- }
+-
+- /* Altivec insns */
+- have_V = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_V = False;
+- } else {
+- /* Unfortunately some older assemblers don't speak Altivec (or
+- choose not to), so to be safe we directly emit the 32-bit
+- word corresponding to "vor 0,0,0". This fixes a build
+- problem that happens on Debian 3.1 (ppc32), and probably
+- various other places. */
+- __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
+- }
+-
+- /* General-Purpose optional (fsqrt, fsqrts) */
+- have_FX = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_FX = False;
+- } else {
+- __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0 */
+- }
++ Bool have_F, have_V, have_FX, have_GX;
+
+- /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
+- have_GX = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_GX = False;
+- } else {
+- __asm__ __volatile__(".long 0xFC000034"); /* frsqrte 0,0 */
+- }
++ if (has_powerpc_feature(PPC_FEATURE_ARCH_2_06)) {
++ VG_(printf)("********** WARNING **********\n");
++ VG_(printf)("You are running valgrind on a POWER7 system. Be aware\n");
++ VG_(printf)("that POWER7 instructions are NOT yet supported by valgrind.\n");
++ VG_(printf)("*****************************\n");
++}
+
+- /* determine dcbz/dcbzl sizes while we still have the signal
+- * handlers registered */
+ find_ppc_dcbz_sz(&vai);
+
+- r = VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
+- vg_assert(r == 0);
+- r = VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
+- vg_assert(r == 0);
+- r = VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
+- vg_assert(r == 0);
+- VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
++ have_F = has_powerpc_feature(PPC_FEATURE_HAS_FPU);
++ have_V = has_powerpc_feature(PPC_FEATURE_HAS_ALTIVEC);
++ have_FX =
++ has_powerpc_feature(PPC_FEATURE_POWER4 | PPC_FEATURE_POWER5 |
++ PPC_FEATURE_POWER5_PLUS | PPC_FEATURE_ARCH_2_05
++ | PPC_FEATURE_ARCH_2_06 | PPC_FEATURE_POWER6_EXT);
++ have_GX = has_powerpc_feature(PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06
++ | PPC_FEATURE_POWER6_EXT);
++
++ VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
+ (Int)have_F, (Int)have_V, (Int)have_FX, (Int)have_GX);
+ /* Make FP a prerequisite for VMX (bogusly so), and for FX and GX. */
+ if (have_V && !have_F)
+@@ -732,90 +734,27 @@ Bool VG_(machine_get_hwcaps)( void )
+
+ #elif defined(VGA_ppc64)
+ {
+- /* Same instruction set detection algorithm as for ppc32. */
+- vki_sigset_t saved_set, tmp_set;
+- vki_sigaction_fromK_t saved_sigill_act, saved_sigfpe_act;
+- vki_sigaction_toK_t tmp_sigill_act, tmp_sigfpe_act;
+-
+- volatile Bool have_F, have_V, have_FX, have_GX;
+- Int r;
+-
+- /* This is a kludge. Really we ought to back-convert saved_act
+- into a toK_t using VG_(convert_sigaction_fromK_to_toK), but
+- since that's a no-op on all ppc64 platforms so far supported,
+- it's not worth the typing effort. At least include most basic
+- sanity check: */
+- vg_assert(sizeof(vki_sigaction_fromK_t) == sizeof(vki_sigaction_toK_t));
+-
+- VG_(sigemptyset)(&tmp_set);
+- VG_(sigaddset)(&tmp_set, VKI_SIGILL);
+- VG_(sigaddset)(&tmp_set, VKI_SIGFPE);
+-
+- r = VG_(sigprocmask)(VKI_SIG_UNBLOCK, &tmp_set, &saved_set);
+- vg_assert(r == 0);
+-
+- r = VG_(sigaction)(VKI_SIGILL, NULL, &saved_sigill_act);
+- vg_assert(r == 0);
+- tmp_sigill_act = saved_sigill_act;
+-
+- VG_(sigaction)(VKI_SIGFPE, NULL, &saved_sigfpe_act);
+- tmp_sigfpe_act = saved_sigfpe_act;
+-
+- /* NODEFER: signal handler does not return (from the kernel's point of
+- view), hence if it is to successfully catch a signal more than once,
+- we need the NODEFER flag. */
+- tmp_sigill_act.sa_flags &= ~VKI_SA_RESETHAND;
+- tmp_sigill_act.sa_flags &= ~VKI_SA_SIGINFO;
+- tmp_sigill_act.sa_flags |= VKI_SA_NODEFER;
+- tmp_sigill_act.ksa_handler = handler_unsup_insn;
+- VG_(sigaction)(VKI_SIGILL, &tmp_sigill_act, NULL);
+-
+- tmp_sigfpe_act.sa_flags &= ~VKI_SA_RESETHAND;
+- tmp_sigfpe_act.sa_flags &= ~VKI_SA_SIGINFO;
+- tmp_sigfpe_act.sa_flags |= VKI_SA_NODEFER;
+- tmp_sigfpe_act.ksa_handler = handler_unsup_insn;
+- VG_(sigaction)(VKI_SIGFPE, &tmp_sigfpe_act, NULL);
+-
+- /* standard FP insns */
+- have_F = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_F = False;
+- } else {
+- __asm__ __volatile__("fmr 0,0");
+- }
+-
+- /* Altivec insns */
+- have_V = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_V = False;
+- } else {
+- __asm__ __volatile__(".long 0x10000484"); /*vor 0,0,0*/
+- }
+-
+- /* General-Purpose optional (fsqrt, fsqrts) */
+- have_FX = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_FX = False;
+- } else {
+- __asm__ __volatile__(".long 0xFC00002C"); /*fsqrt 0,0*/
+- }
++ Bool have_F, have_V, have_FX, have_GX;
+
+- /* Graphics optional (stfiwx, fres, frsqrte, fsel) */
+- have_GX = True;
+- if (__builtin_setjmp(env_unsup_insn)) {
+- have_GX = False;
+- } else {
+- __asm__ __volatile__(".long 0xFC000034"); /*frsqrte 0,0*/
++ if (has_powerpc_feature(PPC_FEATURE_ARCH_2_06)) {
++ VG_(printf)("********** WARNING **********\n");
++ VG_(printf)("You are running valgrind on a POWER7 system. Be aware\n");
++ VG_(printf)("that POWER7 instructions are NOT yet supported by valgrind.\n");
++ VG_(printf)("*****************************\n");
+ }
+
+- /* determine dcbz/dcbzl sizes while we still have the signal
+- * handlers registered */
+ find_ppc_dcbz_sz(&vai);
+
+- VG_(sigaction)(VKI_SIGILL, &saved_sigill_act, NULL);
+- VG_(sigaction)(VKI_SIGFPE, &saved_sigfpe_act, NULL);
+- VG_(sigprocmask)(VKI_SIG_SETMASK, &saved_set, NULL);
+- VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
++ have_F = has_powerpc_feature(PPC_FEATURE_HAS_FPU);
++ have_V = has_powerpc_feature(PPC_FEATURE_HAS_ALTIVEC);
++ have_FX =
++ has_powerpc_feature(PPC_FEATURE_POWER4 | PPC_FEATURE_POWER5 |
++ PPC_FEATURE_POWER5_PLUS | PPC_FEATURE_ARCH_2_05
++ | PPC_FEATURE_ARCH_2_06 | PPC_FEATURE_POWER6_EXT);
++ have_GX = has_powerpc_feature(PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_ARCH_2_06
++ | PPC_FEATURE_POWER6_EXT);
++
++ VG_(debugLog)(1, "machine", "F %d V %d FX %d GX %d\n",
+ (Int)have_F, (Int)have_V, (Int)have_FX, (Int)have_GX);
+ /* on ppc64, if we don't even have FP, just give up. */
+ if (!have_F)
diff --git a/recipes/valgrind/valgrind.inc b/recipes/valgrind/valgrind.inc
index 9c38d70fe5..4946e94222 100644
--- a/recipes/valgrind/valgrind.inc
+++ b/recipes/valgrind/valgrind.inc
@@ -14,5 +14,4 @@ EXTRA_OECONF = "--enable-tls"
PARALLEL_MAKE=""
COMPATIBLE_HOST = "^(i.86|x86_64).*-linux"
-FILES_${PN}-dbg += "/usr/lib/valgrind/x86-linux/.debug"
-FILES_${PN}-dbg += "/usr/lib/valgrind/amd64-linux/.debug"
+FILES_${PN}-dbg += "/usr/lib/valgrind/*/.debug"
diff --git a/recipes/valgrind/valgrind_3.6.1.bb b/recipes/valgrind/valgrind_3.6.1.bb
index 9484c43028..0c83f42bcf 100644
--- a/recipes/valgrind/valgrind_3.6.1.bb
+++ b/recipes/valgrind/valgrind_3.6.1.bb
@@ -1,4 +1,10 @@
require valgrind.inc
+PR = "r1"
+
+SRC_URI += "file://vg-ppc-feature.patch"
+
+COMPATIBLE_HOST = "^(i.86|x86_64|powerpc).*-linux"
+
SRC_URI[md5sum] = "2c3aa122498baecc9d69194057ca88f5"
SRC_URI[sha256sum] = "49bdcc4fbcf060049b5f0dcfd8a187a6e90e0b0e57309f633b64e44430726a0e"