[valgrind-variant] r138 committed - Merge with trunk Valgrind r13132 VEX r2564

69 views
Skip to first unread message

valgrind...@googlecode.com

unread,
Nov 22, 2012, 8:26:06 AM11/22/12
to valgrind-var...@googlegroups.com
Revision: 138
Author: ramosian.glider
Date: Thu Nov 22 04:55:39 2012
Log: Merge with trunk Valgrind r13132 VEX r2564

http://code.google.com/p/valgrind-variant/source/detail?r=138

Added:
/trunk/valgrind/NEWS.old
/trunk/valgrind/README.android_emulator
/trunk/valgrind/README.mips
/trunk/valgrind/VEX/priv/guest_mips_defs.h
/trunk/valgrind/VEX/priv/guest_mips_helpers.c
/trunk/valgrind/VEX/priv/guest_mips_toIR.c
/trunk/valgrind/VEX/priv/host_mips_defs.c
/trunk/valgrind/VEX/priv/host_mips_defs.h
/trunk/valgrind/VEX/priv/host_mips_isel.c
/trunk/valgrind/VEX/priv/ir_inject.c
/trunk/valgrind/VEX/priv/s390_disasm.c
/trunk/valgrind/VEX/priv/s390_disasm.h
/trunk/valgrind/VEX/pub/libvex_emnote.h
/trunk/valgrind/VEX/pub/libvex_guest_mips32.h
/trunk/valgrind/auxprogs/s390-check-opcodes.pl
/trunk/valgrind/configure.in.orig
/trunk/valgrind/coregrind/link_tool_exe_darwin.in.orig
/trunk/valgrind/coregrind/m_aspacemgr/aspacemgr-linux.c.orig
/trunk/valgrind/coregrind/m_cache.c
/trunk/valgrind/coregrind/m_debuginfo/readelf.c.orig
/trunk/valgrind/coregrind/m_debuginfo/readelf.c.rej
/trunk/valgrind/coregrind/m_debuginfo/readpdb.c.orig
/trunk/valgrind/coregrind/m_dispatch/dispatch-mips32-linux.S
/trunk/valgrind/coregrind/m_errormgr.c.orig
/trunk/valgrind/coregrind/m_gdbserver/64bit-avx-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-avx-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-avx.xml
/trunk/valgrind/coregrind/m_gdbserver/amd64-avx-coresse-valgrind.xml
/trunk/valgrind/coregrind/m_gdbserver/amd64-avx-coresse.xml
/trunk/valgrind/coregrind/m_gdbserver/amd64-avx-linux-valgrind.xml
/trunk/valgrind/coregrind/m_gdbserver/amd64-avx-linux.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cp0-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cp0-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cp0.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cpu-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cpu-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-cpu.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-fpu-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-fpu-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-fpu.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-linux-valgrind.xml
/trunk/valgrind/coregrind/m_gdbserver/mips-linux.xml
/trunk/valgrind/coregrind/m_gdbserver/power-core-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/power-core-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-acr-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-acr-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-acr.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-fpr-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-fpr-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/s390-fpr.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-core64-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-core64-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-core64.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-generic-valgrind.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-generic.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-linux64-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-linux64-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/s390x-linux64.xml
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-mips32.c
/trunk/valgrind/coregrind/m_libcfile.c.orig
/trunk/valgrind/coregrind/m_libcproc.c.orig
/trunk/valgrind/coregrind/m_main.c.orig
/trunk/valgrind/coregrind/m_main.c.rej
/trunk/valgrind/coregrind/m_mallocfree.c.orig
/trunk/valgrind/coregrind/m_options.c.orig
/trunk/valgrind/coregrind/m_poolalloc.c
/trunk/valgrind/coregrind/m_replacemalloc/vg_replace_malloc.c.orig
/trunk/valgrind/coregrind/m_scheduler/scheduler.c.orig
/trunk/valgrind/coregrind/m_scheduler/scheduler.c.rej
/trunk/valgrind/coregrind/m_sigframe/sigframe-mips32-linux.c
/trunk/valgrind/coregrind/m_stacktrace.c.orig
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-xen.h
/trunk/valgrind/coregrind/m_syswrap/syscall-mips32-linux.S
/trunk/valgrind/coregrind/m_syswrap/syswrap-generic.c.orig
/trunk/valgrind/coregrind/m_syswrap/syswrap-generic.c.rej
/trunk/valgrind/coregrind/m_syswrap/syswrap-mips32-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-x86-darwin.c.orig
/trunk/valgrind/coregrind/m_syswrap/syswrap-xen.c
/trunk/valgrind/coregrind/m_ume/elf.c.orig
/trunk/valgrind/coregrind/m_ume/macho.c.orig
/trunk/valgrind/coregrind/m_ume/macho.c.rej
/trunk/valgrind/coregrind/pub_core_aspacemgr.h.orig
/trunk/valgrind/coregrind/pub_core_libcfile.h.orig
/trunk/valgrind/coregrind/pub_core_options.h.orig
/trunk/valgrind/coregrind/pub_core_options.h.rej
/trunk/valgrind/coregrind/pub_core_tooliface.h.orig
/trunk/valgrind/darwin12.supp
/trunk/valgrind/docs/internals/3_7_BUGSTATUS.txt
/trunk/valgrind/docs/internals/3_8_BUGSTATUS.txt
/trunk/valgrind/docs/internals/avx-notes.txt
/trunk/valgrind/docs/internals/s390-opcodes.csv
/trunk/valgrind/docs/internals/t-chaining-notes.txt
/trunk/valgrind/drd/tests/fp_race_xml.stderr.exp
/trunk/valgrind/drd/tests/fp_race_xml.stderr.exp.orig
/trunk/valgrind/drd/tests/fp_race_xml.stderr.exp.rej
/trunk/valgrind/drd/tests/fp_race_xml.vgtest
/trunk/valgrind/drd/tests/fp_race_xml.vgtest.orig
/trunk/valgrind/drd/tests/fp_race_xml.vgtest.rej
/trunk/valgrind/drd/tests/sem_wait.cpp
/trunk/valgrind/drd/tests/sem_wait.stderr.exp
/trunk/valgrind/drd/tests/sem_wait.vgtest
/trunk/valgrind/drd/tests/tc04_free_lock.stderr.exp-ppc
/trunk/valgrind/drd/tests/tc04_free_lock.stderr.exp-s390
/trunk/valgrind/drd/tests/tc04_free_lock.stderr.exp-x86
/trunk/valgrind/drd/tests/tc09_bad_unlock.stderr.exp-ppc
/trunk/valgrind/drd/tests/tc09_bad_unlock.stderr.exp-s390
/trunk/valgrind/drd/tests/tc09_bad_unlock.stderr.exp-x86
/trunk/valgrind/exp-sgcheck/Makefile.in
/trunk/valgrind/exp-sgcheck/tests/Makefile.in
/trunk/valgrind/gdbserver_tests/gone.c
/trunk/valgrind/gdbserver_tests/mcblocklistsearch.stderrB.exp
/trunk/valgrind/gdbserver_tests/mcblocklistsearch.stdinB.gdb
/trunk/valgrind/gdbserver_tests/mcblocklistsearch.vgtest
/trunk/valgrind/gdbserver_tests/nlgone_abrt.stderr.exp
/trunk/valgrind/gdbserver_tests/nlgone_abrt.stderrB.exp
/trunk/valgrind/gdbserver_tests/nlgone_abrt.stdinB.gdb
/trunk/valgrind/gdbserver_tests/nlgone_abrt.stdoutB.exp
/trunk/valgrind/gdbserver_tests/nlgone_abrt.vgtest
/trunk/valgrind/gdbserver_tests/nlgone_exit.stderr.exp
/trunk/valgrind/gdbserver_tests/nlgone_exit.stderrB.exp
/trunk/valgrind/gdbserver_tests/nlgone_exit.stdinB.gdb
/trunk/valgrind/gdbserver_tests/nlgone_exit.stdoutB.exp
/trunk/valgrind/gdbserver_tests/nlgone_exit.vgtest
/trunk/valgrind/gdbserver_tests/nlgone_return.stderr.exp
/trunk/valgrind/gdbserver_tests/nlgone_return.stderrB.exp
/trunk/valgrind/gdbserver_tests/nlgone_return.stdinB.gdb
/trunk/valgrind/gdbserver_tests/nlgone_return.stdoutB.exp
/trunk/valgrind/gdbserver_tests/nlgone_return.vgtest
/trunk/valgrind/helgrind/tests/pth_destroy_cond.c
/trunk/valgrind/helgrind/tests/pth_destroy_cond.stderr.exp
/trunk/valgrind/helgrind/tests/pth_destroy_cond.stdout.exp
/trunk/valgrind/helgrind/tests/pth_destroy_cond.vgtest
/trunk/valgrind/helgrind/tests/tc18_semabuse.stderr.exp-linux-mips32
/trunk/valgrind/helgrind/tests/tc19_shadowmem.stderr.exp-mips32
/trunk/valgrind/helgrind/tests/tc20_verifywrap.stderr.exp-mips32
/trunk/valgrind/helgrind/tests/tc20_verifywrap.stderr.exp-s390x
/trunk/valgrind/helgrind/tests/tc23_bogus_condwait.stderr.exp-mips32
/trunk/valgrind/include/pub_tool_inner.h
/trunk/valgrind/include/pub_tool_libcfile.h.orig
/trunk/valgrind/include/pub_tool_libcfile.h.rej
/trunk/valgrind/include/pub_tool_poolalloc.h
/trunk/valgrind/include/pub_tool_redir.h.orig
/trunk/valgrind/include/vki/vki-linux.h.orig
/trunk/valgrind/include/vki/vki-mips32-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-mips32-linux.h
/trunk/valgrind/include/vki/vki-scnums-mips32-linux.h
/trunk/valgrind/include/vki/vki-xen-domctl.h
/trunk/valgrind/include/vki/vki-xen-evtchn.h
/trunk/valgrind/include/vki/vki-xen-gnttab.h
/trunk/valgrind/include/vki/vki-xen-hvm.h
/trunk/valgrind/include/vki/vki-xen-memory.h
/trunk/valgrind/include/vki/vki-xen-mmuext.h
/trunk/valgrind/include/vki/vki-xen-sysctl.h
/trunk/valgrind/include/vki/vki-xen-version.h
/trunk/valgrind/include/vki/vki-xen-x86.h
/trunk/valgrind/include/vki/vki-xen.h
/trunk/valgrind/massif/tests/overloaded-new.post.exp-mips32
/trunk/valgrind/massif/tests/pages_as_heap.c
/trunk/valgrind/massif/tests/pages_as_heap.stderr.exp
/trunk/valgrind/massif/tests/pages_as_heap.vgtest
/trunk/valgrind/memcheck/mc_errors.c.orig
/trunk/valgrind/memcheck/mc_include.h.orig
/trunk/valgrind/memcheck/mc_include.h.rej
/trunk/valgrind/memcheck/mc_leakcheck.c.orig
/trunk/valgrind/memcheck/mc_leakcheck.c.rej
/trunk/valgrind/memcheck/mc_main.c.orig
/trunk/valgrind/memcheck/mc_malloc_wrappers.c.orig
/trunk/valgrind/memcheck/mc_malloc_wrappers.c.rej
/trunk/valgrind/memcheck/mc_replace_strmem.c.orig
/trunk/valgrind/memcheck/mc_replace_strmem.c.rej
/trunk/valgrind/memcheck/tests/Makefile.am.orig
/trunk/valgrind/memcheck/tests/accounting.c
/trunk/valgrind/memcheck/tests/accounting.stderr.exp
/trunk/valgrind/memcheck/tests/accounting.vgtest
/trunk/valgrind/memcheck/tests/amd64/insn-bsfl.c
/trunk/valgrind/memcheck/tests/amd64/insn-bsfl.stderr.exp
/trunk/valgrind/memcheck/tests/amd64/insn-bsfl.stdout.exp
/trunk/valgrind/memcheck/tests/amd64/insn-bsfl.vgtest
/trunk/valgrind/memcheck/tests/amd64/insn-pcmpistri.c
/trunk/valgrind/memcheck/tests/amd64/insn-pcmpistri.stderr.exp
/trunk/valgrind/memcheck/tests/amd64/insn-pcmpistri.stdout.exp
/trunk/valgrind/memcheck/tests/amd64/insn-pcmpistri.vgtest
/trunk/valgrind/memcheck/tests/amd64/insn-pmovmskb.c
/trunk/valgrind/memcheck/tests/amd64/insn-pmovmskb.stderr.exp
/trunk/valgrind/memcheck/tests/amd64/insn-pmovmskb.stdout.exp
/trunk/valgrind/memcheck/tests/amd64/insn-pmovmskb.vgtest
/trunk/valgrind/memcheck/tests/bug287260.c
/trunk/valgrind/memcheck/tests/bug287260.stderr.exp
/trunk/valgrind/memcheck/tests/bug287260.vgtest
/trunk/valgrind/memcheck/tests/clireq_nofill.c
/trunk/valgrind/memcheck/tests/clireq_nofill.stderr.exp
/trunk/valgrind/memcheck/tests/clireq_nofill.stdout.exp
/trunk/valgrind/memcheck/tests/clireq_nofill.vgtest
/trunk/valgrind/memcheck/tests/clo_redzone.c
/trunk/valgrind/memcheck/tests/clo_redzone_128.stderr.exp
/trunk/valgrind/memcheck/tests/clo_redzone_128.vgtest
/trunk/valgrind/memcheck/tests/clo_redzone_default.stderr.exp
/trunk/valgrind/memcheck/tests/clo_redzone_default.vgtest
/trunk/valgrind/memcheck/tests/custom_alloc.stderr.exp-s390x-mvc
/trunk/valgrind/memcheck/tests/custom_alloc.stderr.exp-s390x-mvc.orig
/trunk/valgrind/memcheck/tests/custom_alloc.stderr.exp-s390x-mvc.rej
/trunk/valgrind/memcheck/tests/deep-backtrace.c
/trunk/valgrind/memcheck/tests/deep-backtrace.stderr.exp
/trunk/valgrind/memcheck/tests/deep-backtrace.vgtest
/trunk/valgrind/memcheck/tests/dw4.c
/trunk/valgrind/memcheck/tests/dw4.stderr.exp
/trunk/valgrind/memcheck/tests/dw4.vgtest
/trunk/valgrind/memcheck/tests/filter_memcpy
/trunk/valgrind/memcheck/tests/leak-segv-jmp.c
/trunk/valgrind/memcheck/tests/leak-segv-jmp.stderr.exp
/trunk/valgrind/memcheck/tests/leak-segv-jmp.vgtest
/trunk/valgrind/memcheck/tests/linux/getregset.c
/trunk/valgrind/memcheck/tests/linux/getregset.stdout.exp
/trunk/valgrind/memcheck/tests/linux/getregset.vgtest
/trunk/valgrind/memcheck/tests/linux/proc-auxv.c
/trunk/valgrind/memcheck/tests/linux/proc-auxv.stderr.exp
/trunk/valgrind/memcheck/tests/linux/proc-auxv.vgtest
/trunk/valgrind/memcheck/tests/linux/syscalls-2007.c
/trunk/valgrind/memcheck/tests/linux/syscalls-2007.stderr.exp
/trunk/valgrind/memcheck/tests/linux/syscalls-2007.vgtest
/trunk/valgrind/memcheck/tests/linux/syslog-syscall.c
/trunk/valgrind/memcheck/tests/linux/syslog-syscall.stderr.exp
/trunk/valgrind/memcheck/tests/linux/syslog-syscall.vgtest
/trunk/valgrind/memcheck/tests/ppc32/power_ISA2_05.stdout.exp.orig
/trunk/valgrind/memcheck/tests/s390x
/trunk/valgrind/memcheck/tests/s390x/Makefile.am
/trunk/valgrind/memcheck/tests/s390x/cds.c
/trunk/valgrind/memcheck/tests/s390x/cds.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/cds.vgtest
/trunk/valgrind/memcheck/tests/s390x/cdsg.c
/trunk/valgrind/memcheck/tests/s390x/cdsg.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/cdsg.vgtest
/trunk/valgrind/memcheck/tests/s390x/cs.c
/trunk/valgrind/memcheck/tests/s390x/cs.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/cs.vgtest
/trunk/valgrind/memcheck/tests/s390x/csg.c
/trunk/valgrind/memcheck/tests/s390x/csg.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/csg.vgtest
/trunk/valgrind/memcheck/tests/s390x/cu21.c
/trunk/valgrind/memcheck/tests/s390x/cu21.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/cu21.vgtest
/trunk/valgrind/memcheck/tests/s390x/cu42.c
/trunk/valgrind/memcheck/tests/s390x/cu42.stderr.exp
/trunk/valgrind/memcheck/tests/s390x/cu42.vgtest
/trunk/valgrind/memcheck/tests/s390x/filter_stderr
/trunk/valgrind/memcheck/tests/s390x/ltgjhe.c
/trunk/valgrind/memcheck/tests/s390x/ltgjhe.vgtest
/trunk/valgrind/memcheck/tests/sem.stderr.exp
/trunk/valgrind/memcheck/tests/sem.vgtest
/trunk/valgrind/memcheck/tests/sigkill.stderr.exp-mips32
/trunk/valgrind/memcheck/tests/static_malloc.c
/trunk/valgrind/memcheck/tests/static_malloc.stderr.exp
/trunk/valgrind/memcheck/tests/static_malloc.vgtest
/trunk/valgrind/memcheck/tests/strchr.stderr.exp3
/trunk/valgrind/memcheck/tests/suppfree.supp
/trunk/valgrind/memcheck/tests/test-plo-no.stderr.exp-le32
/trunk/valgrind/memcheck/tests/test-plo-no.stderr.exp-le64
/trunk/valgrind/memcheck/tests/test-plo-no.stderr.exp-s390x-mvc
/trunk/valgrind/memcheck/tests/test-plo-no.vgtest
/trunk/valgrind/memcheck/tests/test-plo-yes.stderr.exp-le32
/trunk/valgrind/memcheck/tests/test-plo-yes.stderr.exp-le64
/trunk/valgrind/memcheck/tests/test-plo-yes.vgtest
/trunk/valgrind/memcheck/tests/test-plo.c
/trunk/valgrind/memcheck/tests/vbit-test
/trunk/valgrind/memcheck/tests/vbit-test/Makefile.am
/trunk/valgrind/memcheck/tests/vbit-test/README
/trunk/valgrind/memcheck/tests/vbit-test/TODO
/trunk/valgrind/memcheck/tests/vbit-test/binary.c
/trunk/valgrind/memcheck/tests/vbit-test/filter_stderr
/trunk/valgrind/memcheck/tests/vbit-test/irops.c
/trunk/valgrind/memcheck/tests/vbit-test/main.c
/trunk/valgrind/memcheck/tests/vbit-test/qernary.c
/trunk/valgrind/memcheck/tests/vbit-test/ternary.c
/trunk/valgrind/memcheck/tests/vbit-test/unary.c
/trunk/valgrind/memcheck/tests/vbit-test/util.c
/trunk/valgrind/memcheck/tests/vbit-test/valgrind.c
/trunk/valgrind/memcheck/tests/vbit-test/vbit-test.vgtest
/trunk/valgrind/memcheck/tests/vbit-test/vbits.c
/trunk/valgrind/memcheck/tests/vbit-test/vbits.h
/trunk/valgrind/memcheck/tests/vbit-test/vtest.h
/trunk/valgrind/nightly/conf/z10-ec.conf
/trunk/valgrind/nightly/conf/z10-ec.sendmail
/trunk/valgrind/none/tests/amd64/aes.c
/trunk/valgrind/none/tests/amd64/aes.stdout.exp
/trunk/valgrind/none/tests/amd64/aes.vgtest
/trunk/valgrind/none/tests/amd64/avx-1.c
/trunk/valgrind/none/tests/amd64/avx-1.stdout.exp
/trunk/valgrind/none/tests/amd64/avx-1.vgtest
/trunk/valgrind/none/tests/amd64/lzcnt64.c
/trunk/valgrind/none/tests/amd64/lzcnt64.stderr.exp
/trunk/valgrind/none/tests/amd64/lzcnt64.stdout.exp
/trunk/valgrind/none/tests/amd64/lzcnt64.vgtest
/trunk/valgrind/none/tests/amd64/movbe.c
/trunk/valgrind/none/tests/amd64/movbe.stdout.exp
/trunk/valgrind/none/tests/amd64/movbe.vgtest
/trunk/valgrind/none/tests/amd64/nan80and64.c
/trunk/valgrind/none/tests/amd64/nan80and64.stderr.exp
/trunk/valgrind/none/tests/amd64/nan80and64.stdout.exp
/trunk/valgrind/none/tests/amd64/nan80and64.vgtest
/trunk/valgrind/none/tests/amd64/pcmpstr64.c.orig
/trunk/valgrind/none/tests/amd64/pcmpstr64.stderr.exp
/trunk/valgrind/none/tests/amd64/pcmpstr64w.c
/trunk/valgrind/none/tests/amd64/pcmpstr64w.stderr.exp
/trunk/valgrind/none/tests/amd64/pcmpstr64w.stdout.exp
/trunk/valgrind/none/tests/amd64/pcmpstr64w.vgtest
/trunk/valgrind/none/tests/amd64/pcmpxstrx64.stderr.exp
/trunk/valgrind/none/tests/amd64/pcmpxstrx64w.c
/trunk/valgrind/none/tests/amd64/pcmpxstrx64w.stderr.exp
/trunk/valgrind/none/tests/amd64/pcmpxstrx64w.stdout.exp
/trunk/valgrind/none/tests/amd64/pcmpxstrx64w.vgtest
/trunk/valgrind/none/tests/arm/v6intARM.c.orig
/trunk/valgrind/none/tests/arm/v6intARM.stdout.exp.orig
/trunk/valgrind/none/tests/arm/v6intThumb.c.orig
/trunk/valgrind/none/tests/arm/v6intThumb.stdout.exp.orig
/trunk/valgrind/none/tests/arm/v6media.stdout.exp.orig
/trunk/valgrind/none/tests/arm/vcvt_fixed_float_VFP.c
/trunk/valgrind/none/tests/arm/vcvt_fixed_float_VFP.stdout.exp
/trunk/valgrind/none/tests/arm/vcvt_fixed_float_VFP.vgtest
/trunk/valgrind/none/tests/async-sigs.stderr.exp-mips32
/trunk/valgrind/none/tests/ifunc.c
/trunk/valgrind/none/tests/ifunc.stderr.exp
/trunk/valgrind/none/tests/ifunc.stdout.exp
/trunk/valgrind/none/tests/ifunc.vgtest
/trunk/valgrind/none/tests/linux/mremap3.c
/trunk/valgrind/none/tests/linux/mremap3.stderr.exp
/trunk/valgrind/none/tests/linux/mremap3.stdout.exp
/trunk/valgrind/none/tests/linux/mremap3.vgtest
/trunk/valgrind/none/tests/mips32
/trunk/valgrind/none/tests/mips32/FPUarithmetic.c
/trunk/valgrind/none/tests/mips32/FPUarithmetic.stdout.exp
/trunk/valgrind/none/tests/mips32/FPUarithmetic.stdout.exp-mips32
/trunk/valgrind/none/tests/mips32/FPUarithmetic.vgtest
/trunk/valgrind/none/tests/mips32/LoadStore.c
/trunk/valgrind/none/tests/mips32/LoadStore.stdout.exp
/trunk/valgrind/none/tests/mips32/LoadStore.stdout.exp-BE
/trunk/valgrind/none/tests/mips32/LoadStore.vgtest
/trunk/valgrind/none/tests/mips32/LoadStore1.c
/trunk/valgrind/none/tests/mips32/LoadStore1.stdout.exp
/trunk/valgrind/none/tests/mips32/LoadStore1.stdout.exp-LE
/trunk/valgrind/none/tests/mips32/LoadStore1.vgtest
/trunk/valgrind/none/tests/mips32/MIPS32int.c
/trunk/valgrind/none/tests/mips32/MIPS32int.stdout.exp
/trunk/valgrind/none/tests/mips32/MIPS32int.stdout.exp-BE
/trunk/valgrind/none/tests/mips32/MIPS32int.stdout.exp-mips32
/trunk/valgrind/none/tests/mips32/MIPS32int.vgtest
/trunk/valgrind/none/tests/mips32/Makefile.am
/trunk/valgrind/none/tests/mips32/MemCpyTest.c
/trunk/valgrind/none/tests/mips32/MemCpyTest.stdout.exp
/trunk/valgrind/none/tests/mips32/MemCpyTest.vgtest
/trunk/valgrind/none/tests/mips32/MoveIns.c
/trunk/valgrind/none/tests/mips32/MoveIns.stdout.exp
/trunk/valgrind/none/tests/mips32/MoveIns.stdout.exp-BE
/trunk/valgrind/none/tests/mips32/MoveIns.vgtest
/trunk/valgrind/none/tests/mips32/SignalException.c
/trunk/valgrind/none/tests/mips32/SignalException.stderr.exp
/trunk/valgrind/none/tests/mips32/SignalException.vgtest
/trunk/valgrind/none/tests/mips32/allexec.c
/trunk/valgrind/none/tests/mips32/branches.c
/trunk/valgrind/none/tests/mips32/branches.stdout.exp
/trunk/valgrind/none/tests/mips32/branches.vgtest
/trunk/valgrind/none/tests/mips32/filter_stderr
/trunk/valgrind/none/tests/mips32/round.c
/trunk/valgrind/none/tests/mips32/round.stdout.exp
/trunk/valgrind/none/tests/mips32/round.vgtest
/trunk/valgrind/none/tests/mips32/vfp.c
/trunk/valgrind/none/tests/mips32/vfp.stdout.exp
/trunk/valgrind/none/tests/mips32/vfp.stdout.exp-BE
/trunk/valgrind/none/tests/mips32/vfp.stdout.exp-mips32
/trunk/valgrind/none/tests/mips32/vfp.vgtest
/trunk/valgrind/none/tests/nodir.stderr.exp
/trunk/valgrind/none/tests/nodir.vgtest
/trunk/valgrind/none/tests/ppc32/jm-vmx.stdout.exp_Minus_nan
/trunk/valgrind/none/tests/ppc32/jm-vmx.stdout.exp_Minus_nan.orig
/trunk/valgrind/none/tests/ppc32/jm-vmx.stdout.exp_Minus_nan.rej
/trunk/valgrind/none/tests/ppc32/test_dfp1.c
/trunk/valgrind/none/tests/ppc32/test_dfp1.stderr.exp
/trunk/valgrind/none/tests/ppc32/test_dfp1.stdout.exp
/trunk/valgrind/none/tests/ppc32/test_dfp1.vgtest
/trunk/valgrind/none/tests/ppc32/test_dfp2.c
/trunk/valgrind/none/tests/ppc32/test_dfp2.stderr.exp
/trunk/valgrind/none/tests/ppc32/test_dfp2.stdout.exp
/trunk/valgrind/none/tests/ppc32/test_dfp2.stdout.exp_Without_dcffix
/trunk/valgrind/none/tests/ppc32/test_dfp2.vgtest
/trunk/valgrind/none/tests/ppc32/test_dfp3.c
/trunk/valgrind/none/tests/ppc32/test_dfp3.stderr.exp
/trunk/valgrind/none/tests/ppc32/test_dfp3.stdout.exp
/trunk/valgrind/none/tests/ppc32/test_dfp3.vgtest
/trunk/valgrind/none/tests/ppc32/test_dfp4.c
/trunk/valgrind/none/tests/ppc32/test_dfp4.stderr.exp
/trunk/valgrind/none/tests/ppc32/test_dfp4.stdout.exp
/trunk/valgrind/none/tests/ppc32/test_dfp4.vgtest
/trunk/valgrind/none/tests/ppc32/test_dfp5.c
/trunk/valgrind/none/tests/ppc32/test_dfp5.stderr.exp
/trunk/valgrind/none/tests/ppc32/test_dfp5.stdout.exp
/trunk/valgrind/none/tests/ppc32/test_dfp5.vgtest
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part1.c
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part1.c.orig
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part1.c.rej
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part2.c
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part2.c.orig
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part2.c.rej
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part3.c
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part3.c.orig
/trunk/valgrind/none/tests/ppc32/test_isa_2_06_part3.c.rej
/trunk/valgrind/none/tests/ppc64/jm-vmx.stdout.exp_Minus_nan
/trunk/valgrind/none/tests/ppc64/jm-vmx.stdout.exp_Minus_nan.orig
/trunk/valgrind/none/tests/ppc64/jm-vmx.stdout.exp_Minus_nan.rej
/trunk/valgrind/none/tests/ppc64/test_dfp1.c
/trunk/valgrind/none/tests/ppc64/test_dfp1.stderr.exp
/trunk/valgrind/none/tests/ppc64/test_dfp1.stdout.exp
/trunk/valgrind/none/tests/ppc64/test_dfp1.vgtest
/trunk/valgrind/none/tests/ppc64/test_dfp2.c
/trunk/valgrind/none/tests/ppc64/test_dfp2.stderr.exp
/trunk/valgrind/none/tests/ppc64/test_dfp2.stdout.exp
/trunk/valgrind/none/tests/ppc64/test_dfp2.stdout.exp_Without_dcffix
/trunk/valgrind/none/tests/ppc64/test_dfp2.vgtest
/trunk/valgrind/none/tests/ppc64/test_dfp3.c
/trunk/valgrind/none/tests/ppc64/test_dfp3.stderr.exp
/trunk/valgrind/none/tests/ppc64/test_dfp3.stdout.exp
/trunk/valgrind/none/tests/ppc64/test_dfp3.vgtest
/trunk/valgrind/none/tests/ppc64/test_dfp4.c
/trunk/valgrind/none/tests/ppc64/test_dfp4.stderr.exp
/trunk/valgrind/none/tests/ppc64/test_dfp4.stdout.exp
/trunk/valgrind/none/tests/ppc64/test_dfp4.vgtest
/trunk/valgrind/none/tests/ppc64/test_dfp5.c
/trunk/valgrind/none/tests/ppc64/test_dfp5.stderr.exp
/trunk/valgrind/none/tests/ppc64/test_dfp5.stdout.exp
/trunk/valgrind/none/tests/ppc64/test_dfp5.vgtest
/trunk/valgrind/none/tests/process_vm_readv_writev.c
/trunk/valgrind/none/tests/process_vm_readv_writev.stderr.exp
/trunk/valgrind/none/tests/process_vm_readv_writev.vgtest
/trunk/valgrind/none/tests/rlimit64_nofile.c
/trunk/valgrind/none/tests/rlimit64_nofile.stderr.exp
/trunk/valgrind/none/tests/rlimit64_nofile.vgtest
/trunk/valgrind/none/tests/s390x/bfp-1.c
/trunk/valgrind/none/tests/s390x/bfp-1.stderr.exp
/trunk/valgrind/none/tests/s390x/bfp-1.stdout.exp
/trunk/valgrind/none/tests/s390x/bfp-1.vgtest
/trunk/valgrind/none/tests/s390x/bfp-2.c
/trunk/valgrind/none/tests/s390x/bfp-2.stderr.exp
/trunk/valgrind/none/tests/s390x/bfp-2.stdout.exp
/trunk/valgrind/none/tests/s390x/bfp-2.vgtest
/trunk/valgrind/none/tests/s390x/bfp-3.c
/trunk/valgrind/none/tests/s390x/bfp-3.stderr.exp
/trunk/valgrind/none/tests/s390x/bfp-3.stdout.exp
/trunk/valgrind/none/tests/s390x/bfp-3.vgtest
/trunk/valgrind/none/tests/s390x/bfp-4.c
/trunk/valgrind/none/tests/s390x/bfp-4.stderr.exp
/trunk/valgrind/none/tests/s390x/bfp-4.stdout.exp
/trunk/valgrind/none/tests/s390x/bfp-4.vgtest
/trunk/valgrind/none/tests/s390x/cds.c
/trunk/valgrind/none/tests/s390x/cds.stderr.exp
/trunk/valgrind/none/tests/s390x/cds.stdout.exp
/trunk/valgrind/none/tests/s390x/cds.vgtest
/trunk/valgrind/none/tests/s390x/cdsg.c
/trunk/valgrind/none/tests/s390x/cdsg.stderr.exp
/trunk/valgrind/none/tests/s390x/cdsg.stdout.exp
/trunk/valgrind/none/tests/s390x/cdsg.vgtest
/trunk/valgrind/none/tests/s390x/cgij.c
/trunk/valgrind/none/tests/s390x/cgij.stderr.exp
/trunk/valgrind/none/tests/s390x/cgij.stdout.exp
/trunk/valgrind/none/tests/s390x/cgij.vgtest
/trunk/valgrind/none/tests/s390x/cgrj.c
/trunk/valgrind/none/tests/s390x/cgrj.stderr.exp
/trunk/valgrind/none/tests/s390x/cgrj.stdout.exp
/trunk/valgrind/none/tests/s390x/cgrj.vgtest
/trunk/valgrind/none/tests/s390x/cij.c
/trunk/valgrind/none/tests/s390x/cij.stderr.exp
/trunk/valgrind/none/tests/s390x/cij.stdout.exp
/trunk/valgrind/none/tests/s390x/cij.vgtest
/trunk/valgrind/none/tests/s390x/clgij.c
/trunk/valgrind/none/tests/s390x/clgij.stderr.exp
/trunk/valgrind/none/tests/s390x/clgij.stdout.exp
/trunk/valgrind/none/tests/s390x/clgij.vgtest
/trunk/valgrind/none/tests/s390x/clgrj.c
/trunk/valgrind/none/tests/s390x/clgrj.stderr.exp
/trunk/valgrind/none/tests/s390x/clgrj.stdout.exp
/trunk/valgrind/none/tests/s390x/clgrj.vgtest
/trunk/valgrind/none/tests/s390x/clij.c
/trunk/valgrind/none/tests/s390x/clij.stderr.exp
/trunk/valgrind/none/tests/s390x/clij.stdout.exp
/trunk/valgrind/none/tests/s390x/clij.vgtest
/trunk/valgrind/none/tests/s390x/clrj.c
/trunk/valgrind/none/tests/s390x/clrj.stderr.exp
/trunk/valgrind/none/tests/s390x/clrj.stdout.exp
/trunk/valgrind/none/tests/s390x/clrj.vgtest
/trunk/valgrind/none/tests/s390x/clst.c
/trunk/valgrind/none/tests/s390x/clst.stderr.exp
/trunk/valgrind/none/tests/s390x/clst.stdout.exp
/trunk/valgrind/none/tests/s390x/clst.vgtest
/trunk/valgrind/none/tests/s390x/comp-1.c
/trunk/valgrind/none/tests/s390x/comp-1.stderr.exp
/trunk/valgrind/none/tests/s390x/comp-1.stdout.exp
/trunk/valgrind/none/tests/s390x/comp-1.vgtest
/trunk/valgrind/none/tests/s390x/comp-2.c
/trunk/valgrind/none/tests/s390x/comp-2.stderr.exp
/trunk/valgrind/none/tests/s390x/comp-2.stdout.exp
/trunk/valgrind/none/tests/s390x/comp-2.vgtest
/trunk/valgrind/none/tests/s390x/crj.c
/trunk/valgrind/none/tests/s390x/crj.stderr.exp
/trunk/valgrind/none/tests/s390x/crj.stdout.exp
/trunk/valgrind/none/tests/s390x/crj.vgtest
/trunk/valgrind/none/tests/s390x/cs.c
/trunk/valgrind/none/tests/s390x/cs.stderr.exp
/trunk/valgrind/none/tests/s390x/cs.stdout.exp
/trunk/valgrind/none/tests/s390x/cs.vgtest
/trunk/valgrind/none/tests/s390x/csg.c
/trunk/valgrind/none/tests/s390x/csg.stderr.exp
/trunk/valgrind/none/tests/s390x/csg.stdout.exp
/trunk/valgrind/none/tests/s390x/csg.vgtest
/trunk/valgrind/none/tests/s390x/cu12.c
/trunk/valgrind/none/tests/s390x/cu12.stderr.exp
/trunk/valgrind/none/tests/s390x/cu12.stdout.exp
/trunk/valgrind/none/tests/s390x/cu12.vgtest
/trunk/valgrind/none/tests/s390x/cu12_1.c
/trunk/valgrind/none/tests/s390x/cu12_1.stderr.exp
/trunk/valgrind/none/tests/s390x/cu12_1.stdout.exp
/trunk/valgrind/none/tests/s390x/cu12_1.vgtest
/trunk/valgrind/none/tests/s390x/cu14.c
/trunk/valgrind/none/tests/s390x/cu14.stderr.exp
/trunk/valgrind/none/tests/s390x/cu14.stdout.exp
/trunk/valgrind/none/tests/s390x/cu14.vgtest
/trunk/valgrind/none/tests/s390x/cu14_1.c
/trunk/valgrind/none/tests/s390x/cu14_1.stderr.exp
/trunk/valgrind/none/tests/s390x/cu14_1.stdout.exp
/trunk/valgrind/none/tests/s390x/cu14_1.vgtest
/trunk/valgrind/none/tests/s390x/cu21.c
/trunk/valgrind/none/tests/s390x/cu21.stderr.exp
/trunk/valgrind/none/tests/s390x/cu21.stdout.exp
/trunk/valgrind/none/tests/s390x/cu21.vgtest
/trunk/valgrind/none/tests/s390x/cu21_1.c
/trunk/valgrind/none/tests/s390x/cu21_1.stderr.exp
/trunk/valgrind/none/tests/s390x/cu21_1.stdout.exp
/trunk/valgrind/none/tests/s390x/cu21_1.vgtest
/trunk/valgrind/none/tests/s390x/cu24.c
/trunk/valgrind/none/tests/s390x/cu24.stderr.exp
/trunk/valgrind/none/tests/s390x/cu24.stdout.exp
/trunk/valgrind/none/tests/s390x/cu24.vgtest
/trunk/valgrind/none/tests/s390x/cu24_1.c
/trunk/valgrind/none/tests/s390x/cu24_1.stderr.exp
/trunk/valgrind/none/tests/s390x/cu24_1.stdout.exp
/trunk/valgrind/none/tests/s390x/cu24_1.vgtest
/trunk/valgrind/none/tests/s390x/cu41.c
/trunk/valgrind/none/tests/s390x/cu41.stderr.exp
/trunk/valgrind/none/tests/s390x/cu41.stdout.exp
/trunk/valgrind/none/tests/s390x/cu41.vgtest
/trunk/valgrind/none/tests/s390x/cu42.c
/trunk/valgrind/none/tests/s390x/cu42.stderr.exp
/trunk/valgrind/none/tests/s390x/cu42.stdout.exp
/trunk/valgrind/none/tests/s390x/cu42.vgtest
/trunk/valgrind/none/tests/s390x/dfp-1.c
/trunk/valgrind/none/tests/s390x/dfp-1.stderr.exp
/trunk/valgrind/none/tests/s390x/dfp-1.stdout.exp
/trunk/valgrind/none/tests/s390x/dfp-1.vgtest
/trunk/valgrind/none/tests/s390x/ecag.c
/trunk/valgrind/none/tests/s390x/ecag.stderr.exp
/trunk/valgrind/none/tests/s390x/ecag.stdout.exp
/trunk/valgrind/none/tests/s390x/ecag.stdout.exp-z10ec
/trunk/valgrind/none/tests/s390x/ecag.stdout.exp-z196
/trunk/valgrind/none/tests/s390x/ecag.vgtest
/trunk/valgrind/none/tests/s390x/ex.c
/trunk/valgrind/none/tests/s390x/ex.stderr.exp
/trunk/valgrind/none/tests/s390x/ex.stdout.exp
/trunk/valgrind/none/tests/s390x/ex.vgtest
/trunk/valgrind/none/tests/s390x/exrl.c
/trunk/valgrind/none/tests/s390x/exrl.stderr.exp
/trunk/valgrind/none/tests/s390x/exrl.stdout.exp
/trunk/valgrind/none/tests/s390x/exrl.vgtest
/trunk/valgrind/none/tests/s390x/fpconv.c
/trunk/valgrind/none/tests/s390x/fpconv.stderr.exp
/trunk/valgrind/none/tests/s390x/fpconv.stdout.exp
/trunk/valgrind/none/tests/s390x/fpconv.vgtest
/trunk/valgrind/none/tests/s390x/fpext.c
/trunk/valgrind/none/tests/s390x/fpext.stderr.exp
/trunk/valgrind/none/tests/s390x/fpext.stdout.exp
/trunk/valgrind/none/tests/s390x/fpext.vgtest
/trunk/valgrind/none/tests/s390x/fpext_fail.stderr.exp
/trunk/valgrind/none/tests/s390x/fpext_fail.vgtest
/trunk/valgrind/none/tests/s390x/fpext_warn.c
/trunk/valgrind/none/tests/s390x/fpext_warn.stderr.exp
/trunk/valgrind/none/tests/s390x/fpext_warn.stdout.exp
/trunk/valgrind/none/tests/s390x/fpext_warn.vgtest
/trunk/valgrind/none/tests/s390x/mvc.c
/trunk/valgrind/none/tests/s390x/mvc.stderr.exp
/trunk/valgrind/none/tests/s390x/mvc.stdout.exp
/trunk/valgrind/none/tests/s390x/mvc.vgtest
/trunk/valgrind/none/tests/s390x/rounding-1.c
/trunk/valgrind/none/tests/s390x/rounding-1.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-1.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-1.vgtest
/trunk/valgrind/none/tests/s390x/rounding-2.c
/trunk/valgrind/none/tests/s390x/rounding-2.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-2.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-2.vgtest
/trunk/valgrind/none/tests/s390x/rounding-3.c
/trunk/valgrind/none/tests/s390x/rounding-3.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-3.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-3.vgtest
/trunk/valgrind/none/tests/s390x/rounding-4.c
/trunk/valgrind/none/tests/s390x/rounding-4.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-4.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-4.vgtest
/trunk/valgrind/none/tests/s390x/rounding-5.c
/trunk/valgrind/none/tests/s390x/rounding-5.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-5.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-5.vgtest
/trunk/valgrind/none/tests/s390x/rounding-6.c
/trunk/valgrind/none/tests/s390x/rounding-6.stderr.exp
/trunk/valgrind/none/tests/s390x/rounding-6.stdout.exp
/trunk/valgrind/none/tests/s390x/rounding-6.vgtest
/trunk/valgrind/none/tests/s390x/rounding.h
/trunk/valgrind/none/tests/s390x/spechelper-algr.c
/trunk/valgrind/none/tests/s390x/spechelper-algr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-algr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-algr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-alr.c
/trunk/valgrind/none/tests/s390x/spechelper-alr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-alr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-alr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-clr.c
/trunk/valgrind/none/tests/s390x/spechelper-clr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-clr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-clr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-cr.c
/trunk/valgrind/none/tests/s390x/spechelper-cr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-cr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-cr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-icm-1.c
/trunk/valgrind/none/tests/s390x/spechelper-icm-1.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-icm-1.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-icm-1.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-icm-2.c
/trunk/valgrind/none/tests/s390x/spechelper-icm-2.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-icm-2.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-icm-2.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-ltr.c
/trunk/valgrind/none/tests/s390x/spechelper-ltr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-ltr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-ltr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-or.c
/trunk/valgrind/none/tests/s390x/spechelper-or.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-or.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-or.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-slgr.c
/trunk/valgrind/none/tests/s390x/spechelper-slgr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-slgr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-slgr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-slr.c
/trunk/valgrind/none/tests/s390x/spechelper-slr.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-slr.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-slr.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-tm.c
/trunk/valgrind/none/tests/s390x/spechelper-tm.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-tm.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-tm.vgtest
/trunk/valgrind/none/tests/s390x/spechelper-tmll.c
/trunk/valgrind/none/tests/s390x/spechelper-tmll.stderr.exp
/trunk/valgrind/none/tests/s390x/spechelper-tmll.stdout.exp
/trunk/valgrind/none/tests/s390x/spechelper-tmll.vgtest
/trunk/valgrind/none/tests/s390x/srnm.c
/trunk/valgrind/none/tests/s390x/srnm.stderr.exp
/trunk/valgrind/none/tests/s390x/srnm.stdout.exp
/trunk/valgrind/none/tests/s390x/srnm.vgtest
/trunk/valgrind/none/tests/s390x/srnmb.c
/trunk/valgrind/none/tests/s390x/srnmb.stderr.exp
/trunk/valgrind/none/tests/s390x/srnmb.stdout.exp
/trunk/valgrind/none/tests/s390x/srnmb.vgtest
/trunk/valgrind/none/tests/s390x/stmg.c
/trunk/valgrind/none/tests/s390x/stmg.stderr.exp
/trunk/valgrind/none/tests/s390x/stmg.stdout.exp
/trunk/valgrind/none/tests/s390x/stmg.vgtest
/trunk/valgrind/none/tests/s390x/svc.h
/trunk/valgrind/none/tests/s390x/table.h
/trunk/valgrind/none/tests/s390x/test_clone.c
/trunk/valgrind/none/tests/s390x/test_clone.stderr.exp
/trunk/valgrind/none/tests/s390x/test_clone.stdout.exp
/trunk/valgrind/none/tests/s390x/test_clone.vgtest
/trunk/valgrind/none/tests/s390x/test_fork.c
/trunk/valgrind/none/tests/s390x/test_fork.stderr.exp
/trunk/valgrind/none/tests/s390x/test_fork.stdout.exp
/trunk/valgrind/none/tests/s390x/test_fork.vgtest
/trunk/valgrind/none/tests/s390x/test_sig.c
/trunk/valgrind/none/tests/s390x/test_sig.stderr.exp
/trunk/valgrind/none/tests/s390x/test_sig.stdout.exp
/trunk/valgrind/none/tests/s390x/test_sig.vgtest
/trunk/valgrind/none/tests/s390x/tm.c
/trunk/valgrind/none/tests/s390x/tm.stderr.exp
/trunk/valgrind/none/tests/s390x/tm.stdout.exp
/trunk/valgrind/none/tests/s390x/tm.vgtest
/trunk/valgrind/none/tests/s390x/tmll.c
/trunk/valgrind/none/tests/s390x/tmll.stderr.exp
/trunk/valgrind/none/tests/s390x/tmll.stdout.exp
/trunk/valgrind/none/tests/s390x/tmll.vgtest
/trunk/valgrind/none/tests/s390x/tr.c
/trunk/valgrind/none/tests/s390x/tr.stderr.exp
/trunk/valgrind/none/tests/s390x/tr.stdout.exp
/trunk/valgrind/none/tests/s390x/tr.vgtest
/trunk/valgrind/none/tests/s390x/tre.c
/trunk/valgrind/none/tests/s390x/tre.stderr.exp
/trunk/valgrind/none/tests/s390x/tre.stdout.exp
/trunk/valgrind/none/tests/s390x/tre.vgtest
/trunk/valgrind/none/tests/s390x/troo.c
/trunk/valgrind/none/tests/s390x/troo.stderr.exp
/trunk/valgrind/none/tests/s390x/troo.stdout.exp
/trunk/valgrind/none/tests/s390x/troo.vgtest
/trunk/valgrind/none/tests/s390x/trot.c
/trunk/valgrind/none/tests/s390x/trot.stderr.exp
/trunk/valgrind/none/tests/s390x/trot.stdout.exp
/trunk/valgrind/none/tests/s390x/trot.vgtest
/trunk/valgrind/none/tests/s390x/trto.c
/trunk/valgrind/none/tests/s390x/trto.stderr.exp
/trunk/valgrind/none/tests/s390x/trto.stdout.exp
/trunk/valgrind/none/tests/s390x/trto.vgtest
/trunk/valgrind/none/tests/s390x/trtt.c
/trunk/valgrind/none/tests/s390x/trtt.stderr.exp
/trunk/valgrind/none/tests/s390x/trtt.stdout.exp
/trunk/valgrind/none/tests/s390x/trtt.vgtest
/trunk/valgrind/none/tests/shell.stderr.exp-dash2
/trunk/valgrind/none/tests/x86/lzcnt32.stderr.exp
/trunk/valgrind/none/tests/x86/movbe.c
/trunk/valgrind/none/tests/x86/movbe.stdout.exp
/trunk/valgrind/none/tests/x86/movbe.vgtest
/trunk/valgrind/perf/heap_pdb4.vgperf
/trunk/valgrind/perf/many-loss-records.c
/trunk/valgrind/perf/many-loss-records.vgperf
/trunk/valgrind/perf/many-xpts.c
/trunk/valgrind/perf/many-xpts.vgperf
/trunk/valgrind/tests/check_dfp_cap
/trunk/valgrind/tests/outer_inner.supp
Deleted:
/trunk/valgrind/cachegrind/cg-arm.c
/trunk/valgrind/cachegrind/cg-ppc32.c
/trunk/valgrind/cachegrind/cg-ppc64.c
/trunk/valgrind/cachegrind/cg-s390x.c
/trunk/valgrind/cachegrind/cg-x86-amd64.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low.c
/trunk/valgrind/drd/drd_bitmap2_node.c
/trunk/valgrind/drd/tests/tc04_free_lock.stderr.exp
/trunk/valgrind/drd/tests/tc09_bad_unlock.stderr.exp
/trunk/valgrind/include/pub_tool_cpuid.h
Modified:
/trunk/valgrind/AUTHORS
/trunk/valgrind/Makefile.all.am
/trunk/valgrind/Makefile.am
/trunk/valgrind/Makefile.tool-tests.am
/trunk/valgrind/Makefile.tool.am
/trunk/valgrind/Makefile.vex.am
/trunk/valgrind/NEWS
/trunk/valgrind/README
/trunk/valgrind/README.android
/trunk/valgrind/README.s390
/trunk/valgrind/README_DEVELOPERS
/trunk/valgrind/VEX/Makefile-gcc
/trunk/valgrind/VEX/Makefile-icc
/trunk/valgrind/VEX/auxprogs/genoffsets.c
/trunk/valgrind/VEX/priv/guest_amd64_defs.h
/trunk/valgrind/VEX/priv/guest_amd64_helpers.c
/trunk/valgrind/VEX/priv/guest_amd64_toIR.c
/trunk/valgrind/VEX/priv/guest_arm_defs.h
/trunk/valgrind/VEX/priv/guest_arm_helpers.c
/trunk/valgrind/VEX/priv/guest_arm_toIR.c
/trunk/valgrind/VEX/priv/guest_generic_bb_to_IR.c
/trunk/valgrind/VEX/priv/guest_generic_bb_to_IR.h
/trunk/valgrind/VEX/priv/guest_generic_x87.c
/trunk/valgrind/VEX/priv/guest_generic_x87.h
/trunk/valgrind/VEX/priv/guest_ppc_defs.h
/trunk/valgrind/VEX/priv/guest_ppc_helpers.c
/trunk/valgrind/VEX/priv/guest_ppc_toIR.c
/trunk/valgrind/VEX/priv/guest_s390_defs.h
/trunk/valgrind/VEX/priv/guest_s390_helpers.c
/trunk/valgrind/VEX/priv/guest_s390_toIR.c
/trunk/valgrind/VEX/priv/guest_x86_defs.h
/trunk/valgrind/VEX/priv/guest_x86_helpers.c
/trunk/valgrind/VEX/priv/guest_x86_toIR.c
/trunk/valgrind/VEX/priv/host_amd64_defs.c
/trunk/valgrind/VEX/priv/host_amd64_defs.h
/trunk/valgrind/VEX/priv/host_amd64_isel.c
/trunk/valgrind/VEX/priv/host_arm_defs.c
/trunk/valgrind/VEX/priv/host_arm_defs.h
/trunk/valgrind/VEX/priv/host_arm_isel.c
/trunk/valgrind/VEX/priv/host_generic_reg_alloc2.c
/trunk/valgrind/VEX/priv/host_generic_regs.c
/trunk/valgrind/VEX/priv/host_generic_regs.h
/trunk/valgrind/VEX/priv/host_generic_simd128.c
/trunk/valgrind/VEX/priv/host_generic_simd128.h
/trunk/valgrind/VEX/priv/host_generic_simd64.c
/trunk/valgrind/VEX/priv/host_generic_simd64.h
/trunk/valgrind/VEX/priv/host_ppc_defs.c
/trunk/valgrind/VEX/priv/host_ppc_defs.h
/trunk/valgrind/VEX/priv/host_ppc_isel.c
/trunk/valgrind/VEX/priv/host_s390_defs.c
/trunk/valgrind/VEX/priv/host_s390_defs.h
/trunk/valgrind/VEX/priv/host_s390_isel.c
/trunk/valgrind/VEX/priv/host_x86_defs.c
/trunk/valgrind/VEX/priv/host_x86_defs.h
/trunk/valgrind/VEX/priv/host_x86_isel.c
/trunk/valgrind/VEX/priv/ir_defs.c
/trunk/valgrind/VEX/priv/ir_match.c
/trunk/valgrind/VEX/priv/ir_match.h
/trunk/valgrind/VEX/priv/ir_opt.c
/trunk/valgrind/VEX/priv/ir_opt.h
/trunk/valgrind/VEX/priv/main_globals.c
/trunk/valgrind/VEX/priv/main_globals.h
/trunk/valgrind/VEX/priv/main_main.c
/trunk/valgrind/VEX/priv/main_util.c
/trunk/valgrind/VEX/priv/main_util.h
/trunk/valgrind/VEX/pub/libvex.h
/trunk/valgrind/VEX/pub/libvex_basictypes.h
/trunk/valgrind/VEX/pub/libvex_guest_amd64.h
/trunk/valgrind/VEX/pub/libvex_guest_arm.h
/trunk/valgrind/VEX/pub/libvex_guest_ppc32.h
/trunk/valgrind/VEX/pub/libvex_guest_ppc64.h
/trunk/valgrind/VEX/pub/libvex_guest_s390x.h
/trunk/valgrind/VEX/pub/libvex_guest_x86.h
/trunk/valgrind/VEX/pub/libvex_ir.h
/trunk/valgrind/VEX/pub/libvex_s390x_common.h
/trunk/valgrind/VEX/pub/libvex_trc_values.h
/trunk/valgrind/VEX/switchback/switchback.c
/trunk/valgrind/VEX/test_main.c
/trunk/valgrind/VEX/test_main.h
/trunk/valgrind/VEX/useful/cpuid.c
/trunk/valgrind/auxprogs/Makefile.am
/trunk/valgrind/auxprogs/change-copyright-year
/trunk/valgrind/auxprogs/gsl16test
/trunk/valgrind/auxprogs/valgrind-listener.c
/trunk/valgrind/cachegrind/Makefile.am
/trunk/valgrind/cachegrind/cg-arch.c
/trunk/valgrind/cachegrind/cg_arch.h
/trunk/valgrind/cachegrind/cg_branchpred.c
/trunk/valgrind/cachegrind/cg_main.c
/trunk/valgrind/cachegrind/cg_merge.c
/trunk/valgrind/cachegrind/cg_sim.c
/trunk/valgrind/cachegrind/docs/cg-manual.xml
/trunk/valgrind/cachegrind/tests/Makefile.am
/trunk/valgrind/cachegrind/tests/filter_stderr
/trunk/valgrind/callgrind/Makefile.am
/trunk/valgrind/callgrind/bb.c
/trunk/valgrind/callgrind/bbcc.c
/trunk/valgrind/callgrind/callgrind.h
/trunk/valgrind/callgrind/callstack.c
/trunk/valgrind/callgrind/clo.c
/trunk/valgrind/callgrind/context.c
/trunk/valgrind/callgrind/costs.c
/trunk/valgrind/callgrind/debug.c
/trunk/valgrind/callgrind/docs/cl-manual.xml
/trunk/valgrind/callgrind/dump.c
/trunk/valgrind/callgrind/events.c
/trunk/valgrind/callgrind/events.h
/trunk/valgrind/callgrind/fn.c
/trunk/valgrind/callgrind/global.h
/trunk/valgrind/callgrind/jumps.c
/trunk/valgrind/callgrind/main.c
/trunk/valgrind/callgrind/sim.c
/trunk/valgrind/callgrind/tests/filter_stderr
/trunk/valgrind/callgrind/threads.c
/trunk/valgrind/configure.in
/trunk/valgrind/coregrind/Makefile.am
/trunk/valgrind/coregrind/launcher-darwin.c
/trunk/valgrind/coregrind/launcher-linux.c
/trunk/valgrind/coregrind/link_tool_exe_darwin.in
/trunk/valgrind/coregrind/link_tool_exe_linux.in
/trunk/valgrind/coregrind/m_aspacehl.c
/trunk/valgrind/coregrind/m_aspacemgr/aspacemgr-common.c
/trunk/valgrind/coregrind/m_aspacemgr/aspacemgr-linux.c
/trunk/valgrind/coregrind/m_aspacemgr/priv_aspacemgr.h
/trunk/valgrind/coregrind/m_clientstate.c
/trunk/valgrind/coregrind/m_commandline.c
/trunk/valgrind/coregrind/m_coredump/coredump-elf.c
/trunk/valgrind/coregrind/m_cpuid.S
/trunk/valgrind/coregrind/m_debugger.c
/trunk/valgrind/coregrind/m_debuginfo/d3basics.c
/trunk/valgrind/coregrind/m_debuginfo/debuginfo.c
/trunk/valgrind/coregrind/m_debuginfo/misc.c
/trunk/valgrind/coregrind/m_debuginfo/priv_d3basics.h
/trunk/valgrind/coregrind/m_debuginfo/priv_misc.h
/trunk/valgrind/coregrind/m_debuginfo/priv_readdwarf.h
/trunk/valgrind/coregrind/m_debuginfo/priv_readdwarf3.h
/trunk/valgrind/coregrind/m_debuginfo/priv_readelf.h
/trunk/valgrind/coregrind/m_debuginfo/priv_readpdb.h
/trunk/valgrind/coregrind/m_debuginfo/priv_readstabs.h
/trunk/valgrind/coregrind/m_debuginfo/priv_storage.h
/trunk/valgrind/coregrind/m_debuginfo/priv_tytypes.h
/trunk/valgrind/coregrind/m_debuginfo/readdwarf.c
/trunk/valgrind/coregrind/m_debuginfo/readdwarf3.c
/trunk/valgrind/coregrind/m_debuginfo/readelf.c
/trunk/valgrind/coregrind/m_debuginfo/readmacho.c
/trunk/valgrind/coregrind/m_debuginfo/readpdb.c
/trunk/valgrind/coregrind/m_debuginfo/readstabs.c
/trunk/valgrind/coregrind/m_debuginfo/storage.c
/trunk/valgrind/coregrind/m_debuginfo/tytypes.c
/trunk/valgrind/coregrind/m_debuglog.c
/trunk/valgrind/coregrind/m_demangle/demangle.c
/trunk/valgrind/coregrind/m_demangle/vg_libciface.h
/trunk/valgrind/coregrind/m_dispatch/dispatch-amd64-darwin.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-amd64-linux.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-arm-linux.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-ppc32-linux.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-ppc64-linux.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-s390x-linux.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-x86-darwin.S
/trunk/valgrind/coregrind/m_dispatch/dispatch-x86-linux.S
/trunk/valgrind/coregrind/m_errormgr.c
/trunk/valgrind/coregrind/m_execontext.c
/trunk/valgrind/coregrind/m_gdbserver/32bit-core-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/32bit-core-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/32bit-sse-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/32bit-sse-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-core-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-core-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-sse-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/64bit-sse-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/README_DEVELOPERS
/trunk/valgrind/coregrind/m_gdbserver/arm-vfpv3-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/arm-vfpv3-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/m_gdbserver.c
/trunk/valgrind/coregrind/m_gdbserver/power-fpu-valgrind-s1.xml
/trunk/valgrind/coregrind/m_gdbserver/power-fpu-valgrind-s2.xml
/trunk/valgrind/coregrind/m_gdbserver/regcache.c
/trunk/valgrind/coregrind/m_gdbserver/regcache.h
/trunk/valgrind/coregrind/m_gdbserver/regdef.h
/trunk/valgrind/coregrind/m_gdbserver/remote-utils.c
/trunk/valgrind/coregrind/m_gdbserver/server.c
/trunk/valgrind/coregrind/m_gdbserver/server.h
/trunk/valgrind/coregrind/m_gdbserver/signals.c
/trunk/valgrind/coregrind/m_gdbserver/target.c
/trunk/valgrind/coregrind/m_gdbserver/target.h
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-amd64.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-arm.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-ppc32.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-ppc64.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-s390x.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind-low-x86.c
/trunk/valgrind/coregrind/m_gdbserver/valgrind_low.h
/trunk/valgrind/coregrind/m_hashtable.c
/trunk/valgrind/coregrind/m_initimg/initimg-darwin.c
/trunk/valgrind/coregrind/m_initimg/initimg-linux.c
/trunk/valgrind/coregrind/m_initimg/initimg-pathscan.c
/trunk/valgrind/coregrind/m_initimg/priv_initimg_pathscan.h
/trunk/valgrind/coregrind/m_libcassert.c
/trunk/valgrind/coregrind/m_libcbase.c
/trunk/valgrind/coregrind/m_libcfile.c
/trunk/valgrind/coregrind/m_libcprint.c
/trunk/valgrind/coregrind/m_libcproc.c
/trunk/valgrind/coregrind/m_libcsetjmp.c
/trunk/valgrind/coregrind/m_libcsignal.c
/trunk/valgrind/coregrind/m_mach/mach_basics.c
/trunk/valgrind/coregrind/m_mach/mach_traps-amd64-darwin.S
/trunk/valgrind/coregrind/m_mach/mach_traps-x86-darwin.S
/trunk/valgrind/coregrind/m_machine.c
/trunk/valgrind/coregrind/m_main.c
/trunk/valgrind/coregrind/m_mallocfree.c
/trunk/valgrind/coregrind/m_options.c
/trunk/valgrind/coregrind/m_oset.c
/trunk/valgrind/coregrind/m_redir.c
/trunk/valgrind/coregrind/m_replacemalloc/replacemalloc_core.c
/trunk/valgrind/coregrind/m_replacemalloc/vg_replace_malloc.c
/trunk/valgrind/coregrind/m_scheduler/priv_sched-lock-impl.h
/trunk/valgrind/coregrind/m_scheduler/priv_sched-lock.h
/trunk/valgrind/coregrind/m_scheduler/priv_sema.h
/trunk/valgrind/coregrind/m_scheduler/sched-lock-generic.c
/trunk/valgrind/coregrind/m_scheduler/sched-lock.c
/trunk/valgrind/coregrind/m_scheduler/scheduler.c
/trunk/valgrind/coregrind/m_scheduler/sema.c
/trunk/valgrind/coregrind/m_scheduler/ticket-lock-linux.c
/trunk/valgrind/coregrind/m_seqmatch.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-amd64-darwin.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-amd64-linux.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-arm-linux.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-ppc32-linux.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-ppc64-linux.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-s390x-linux.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-x86-darwin.c
/trunk/valgrind/coregrind/m_sigframe/sigframe-x86-linux.c
/trunk/valgrind/coregrind/m_signals.c
/trunk/valgrind/coregrind/m_sparsewa.c
/trunk/valgrind/coregrind/m_stacks.c
/trunk/valgrind/coregrind/m_stacktrace.c
/trunk/valgrind/coregrind/m_syscall.c
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-darwin.h
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-generic.h
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-linux-variants.h
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-linux.h
/trunk/valgrind/coregrind/m_syswrap/priv_syswrap-main.h
/trunk/valgrind/coregrind/m_syswrap/priv_types_n_macros.h
/trunk/valgrind/coregrind/m_syswrap/syscall-amd64-darwin.S
/trunk/valgrind/coregrind/m_syswrap/syscall-amd64-linux.S
/trunk/valgrind/coregrind/m_syswrap/syscall-arm-linux.S
/trunk/valgrind/coregrind/m_syswrap/syscall-ppc32-linux.S
/trunk/valgrind/coregrind/m_syswrap/syscall-ppc64-linux.S
/trunk/valgrind/coregrind/m_syswrap/syscall-s390x-linux.S
/trunk/valgrind/coregrind/m_syswrap/syscall-x86-darwin.S
/trunk/valgrind/coregrind/m_syswrap/syscall-x86-linux.S
/trunk/valgrind/coregrind/m_syswrap/syswrap-amd64-darwin.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-amd64-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-arm-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-darwin.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-generic.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-linux-variants.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-main.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-ppc32-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-ppc64-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-s390x-linux.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-x86-darwin.c
/trunk/valgrind/coregrind/m_syswrap/syswrap-x86-linux.c
/trunk/valgrind/coregrind/m_threadstate.c
/trunk/valgrind/coregrind/m_tooliface.c
/trunk/valgrind/coregrind/m_trampoline.S
/trunk/valgrind/coregrind/m_translate.c
/trunk/valgrind/coregrind/m_transtab.c
/trunk/valgrind/coregrind/m_ume/elf.c
/trunk/valgrind/coregrind/m_ume/macho.c
/trunk/valgrind/coregrind/m_ume/main.c
/trunk/valgrind/coregrind/m_ume/priv_ume.h
/trunk/valgrind/coregrind/m_ume/script.c
/trunk/valgrind/coregrind/m_vki.c
/trunk/valgrind/coregrind/m_vkiscnums.c
/trunk/valgrind/coregrind/m_wordfm.c
/trunk/valgrind/coregrind/m_xarray.c
/trunk/valgrind/coregrind/pub_core_aspacehl.h
/trunk/valgrind/coregrind/pub_core_aspacemgr.h
/trunk/valgrind/coregrind/pub_core_basics.h
/trunk/valgrind/coregrind/pub_core_basics_asm.h
/trunk/valgrind/coregrind/pub_core_clientstate.h
/trunk/valgrind/coregrind/pub_core_clreq.h
/trunk/valgrind/coregrind/pub_core_commandline.h
/trunk/valgrind/coregrind/pub_core_coredump.h
/trunk/valgrind/coregrind/pub_core_cpuid.h
/trunk/valgrind/coregrind/pub_core_debugger.h
/trunk/valgrind/coregrind/pub_core_debuginfo.h
/trunk/valgrind/coregrind/pub_core_debuglog.h
/trunk/valgrind/coregrind/pub_core_demangle.h
/trunk/valgrind/coregrind/pub_core_dispatch.h
/trunk/valgrind/coregrind/pub_core_dispatch_asm.h
/trunk/valgrind/coregrind/pub_core_errormgr.h
/trunk/valgrind/coregrind/pub_core_execontext.h
/trunk/valgrind/coregrind/pub_core_gdbserver.h
/trunk/valgrind/coregrind/pub_core_hashtable.h
/trunk/valgrind/coregrind/pub_core_initimg.h
/trunk/valgrind/coregrind/pub_core_libcassert.h
/trunk/valgrind/coregrind/pub_core_libcbase.h
/trunk/valgrind/coregrind/pub_core_libcfile.h
/trunk/valgrind/coregrind/pub_core_libcprint.h
/trunk/valgrind/coregrind/pub_core_libcproc.h
/trunk/valgrind/coregrind/pub_core_libcsetjmp.h
/trunk/valgrind/coregrind/pub_core_libcsignal.h
/trunk/valgrind/coregrind/pub_core_mach.h
/trunk/valgrind/coregrind/pub_core_machine.h
/trunk/valgrind/coregrind/pub_core_mallocfree.h
/trunk/valgrind/coregrind/pub_core_options.h
/trunk/valgrind/coregrind/pub_core_oset.h
/trunk/valgrind/coregrind/pub_core_redir.h
/trunk/valgrind/coregrind/pub_core_replacemalloc.h
/trunk/valgrind/coregrind/pub_core_scheduler.h
/trunk/valgrind/coregrind/pub_core_seqmatch.h
/trunk/valgrind/coregrind/pub_core_sigframe.h
/trunk/valgrind/coregrind/pub_core_signals.h
/trunk/valgrind/coregrind/pub_core_sparsewa.h
/trunk/valgrind/coregrind/pub_core_stacks.h
/trunk/valgrind/coregrind/pub_core_stacktrace.h
/trunk/valgrind/coregrind/pub_core_syscall.h
/trunk/valgrind/coregrind/pub_core_syswrap.h
/trunk/valgrind/coregrind/pub_core_threadstate.h
/trunk/valgrind/coregrind/pub_core_tooliface.h
/trunk/valgrind/coregrind/pub_core_trampoline.h
/trunk/valgrind/coregrind/pub_core_translate.h
/trunk/valgrind/coregrind/pub_core_transtab.h
/trunk/valgrind/coregrind/pub_core_transtab_asm.h
/trunk/valgrind/coregrind/pub_core_ume.h
/trunk/valgrind/coregrind/pub_core_vki.h
/trunk/valgrind/coregrind/pub_core_vkiscnums.h
/trunk/valgrind/coregrind/pub_core_vkiscnums_asm.h
/trunk/valgrind/coregrind/pub_core_wordfm.h
/trunk/valgrind/coregrind/pub_core_xarray.h
/trunk/valgrind/coregrind/vg_preloaded.c
/trunk/valgrind/coregrind/vgdb.c
/trunk/valgrind/darwin11.supp
/trunk/valgrind/docs/Makefile.am
/trunk/valgrind/docs/README
/trunk/valgrind/docs/internals/arm_thumb_notes_gdbserver.txt
/trunk/valgrind/docs/internals/register-uses.txt
/trunk/valgrind/docs/internals/release-HOWTO.txt
/trunk/valgrind/docs/xml/dist-docs.xml
/trunk/valgrind/docs/xml/manual-core-adv.xml
/trunk/valgrind/docs/xml/manual-core.xml
/trunk/valgrind/docs/xml/vg-entities.xml
/trunk/valgrind/drd/Makefile.am
/trunk/valgrind/drd/docs/drd-manual.xml
/trunk/valgrind/drd/drd.h
/trunk/valgrind/drd/drd_barrier.c
/trunk/valgrind/drd/drd_barrier.h
/trunk/valgrind/drd/drd_basics.h
/trunk/valgrind/drd/drd_bitmap.c
/trunk/valgrind/drd/drd_bitmap.h
/trunk/valgrind/drd/drd_clientobj.c
/trunk/valgrind/drd/drd_clientobj.h
/trunk/valgrind/drd/drd_clientreq.c
/trunk/valgrind/drd/drd_clientreq.h
/trunk/valgrind/drd/drd_cond.c
/trunk/valgrind/drd/drd_cond.h
/trunk/valgrind/drd/drd_darwin_intercepts.c
/trunk/valgrind/drd/drd_error.c
/trunk/valgrind/drd/drd_error.h
/trunk/valgrind/drd/drd_hb.c
/trunk/valgrind/drd/drd_hb.h
/trunk/valgrind/drd/drd_load_store.c
/trunk/valgrind/drd/drd_load_store.h
/trunk/valgrind/drd/drd_main.c
/trunk/valgrind/drd/drd_malloc_wrappers.c
/trunk/valgrind/drd/drd_malloc_wrappers.h
/trunk/valgrind/drd/drd_mutex.c
/trunk/valgrind/drd/drd_mutex.h
/trunk/valgrind/drd/drd_pthread_intercepts.c
/trunk/valgrind/drd/drd_qtcore_intercepts.c
/trunk/valgrind/drd/drd_rwlock.c
/trunk/valgrind/drd/drd_rwlock.h
/trunk/valgrind/drd/drd_segment.c
/trunk/valgrind/drd/drd_segment.h
/trunk/valgrind/drd/drd_semaphore.c
/trunk/valgrind/drd/drd_semaphore.h
/trunk/valgrind/drd/drd_strmem_intercepts.c
/trunk/valgrind/drd/drd_suppression.c
/trunk/valgrind/drd/drd_suppression.h
/trunk/valgrind/drd/drd_thread.c
/trunk/valgrind/drd/drd_thread.h
/trunk/valgrind/drd/drd_thread_bitmap.h
/trunk/valgrind/drd/drd_vc.c
/trunk/valgrind/drd/drd_vc.h
/trunk/valgrind/drd/pub_drd_bitmap.h
/trunk/valgrind/drd/tests/Makefile.am
/trunk/valgrind/drd/tests/annotate_trace_memory.c
/trunk/valgrind/drd/tests/filter_stderr
/trunk/valgrind/drd/tests/filter_xml_and_thread_no
/trunk/valgrind/drd/tests/pth_cancel_locked.c
/trunk/valgrind/drd/tests/pth_cancel_locked.stderr.exp
/trunk/valgrind/drd/tests/sigalrm.c
/trunk/valgrind/drd/tests/tc04_free_lock.vgtest
/trunk/valgrind/drd/tests/unit_bitmap.c
/trunk/valgrind/drd/tests/unit_vc.c
/trunk/valgrind/exp-bbv/bbv_main.c
/trunk/valgrind/exp-dhat/dh_main.c
/trunk/valgrind/exp-sgcheck/h_intercepts.c
/trunk/valgrind/exp-sgcheck/h_main.c
/trunk/valgrind/exp-sgcheck/h_main.h
/trunk/valgrind/exp-sgcheck/pc_common.c
/trunk/valgrind/exp-sgcheck/pc_common.h
/trunk/valgrind/exp-sgcheck/pc_main.c
/trunk/valgrind/exp-sgcheck/sg_main.c
/trunk/valgrind/exp-sgcheck/sg_main.h
/trunk/valgrind/exp-sgcheck/tests/Makefile.am
/trunk/valgrind/exp-sgcheck/tests/is_arch_supported
/trunk/valgrind/exp-sgcheck.supp
/trunk/valgrind/gdbserver_tests/Makefile.am
/trunk/valgrind/gdbserver_tests/README_DEVELOPERS
/trunk/valgrind/gdbserver_tests/filter_gdb
/trunk/valgrind/gdbserver_tests/mcbreak.stderrB.exp
/trunk/valgrind/gdbserver_tests/mchelp.stdoutB.exp
/trunk/valgrind/gdbserver_tests/mcleak.stderrB.exp
/trunk/valgrind/gdbserver_tests/mcleak.stdinB.gdb
/trunk/valgrind/gdbserver_tests/mcleak.stdoutB.exp
/trunk/valgrind/gdbserver_tests/mcmain_pic.stderrB.exp
/trunk/valgrind/gdbserver_tests/mcmain_pic.stdoutB.exp
/trunk/valgrind/gdbserver_tests/mcsignopass.vgtest
/trunk/valgrind/gdbserver_tests/mcsigpass.vgtest
/trunk/valgrind/gdbserver_tests/mcwatchpoints.stdinB.gdb
/trunk/valgrind/gdbserver_tests/mcwatchpoints.stdoutB.exp
/trunk/valgrind/gdbserver_tests/mssnapshot.stderrB.exp
/trunk/valgrind/gdbserver_tests/nlcontrolc.stdoutB.exp
/trunk/valgrind/gdbserver_tests/nlpasssigalrm.stderr.exp
/trunk/valgrind/gdbserver_tests/nlpasssigalrm.stderrB.exp
/trunk/valgrind/gdbserver_tests/nlpasssigalrm.stdinB.gdb
/trunk/valgrind/gdbserver_tests/nlpasssigalrm.stdoutB.exp
/trunk/valgrind/gdbserver_tests/passsigalrm.c
/trunk/valgrind/gdbserver_tests/simulate_control_c
/trunk/valgrind/glibc-2.34567-NPTL-helgrind.supp
/trunk/valgrind/glibc-2.X-drd.supp
/trunk/valgrind/glibc-2.X.supp.in
/trunk/valgrind/helgrind/docs/hg-manual.xml
/trunk/valgrind/helgrind/helgrind.h
/trunk/valgrind/helgrind/hg_basics.c
/trunk/valgrind/helgrind/hg_basics.h
/trunk/valgrind/helgrind/hg_errors.c
/trunk/valgrind/helgrind/hg_errors.h
/trunk/valgrind/helgrind/hg_intercepts.c
/trunk/valgrind/helgrind/hg_lock_n_thread.c
/trunk/valgrind/helgrind/hg_lock_n_thread.h
/trunk/valgrind/helgrind/hg_main.c
/trunk/valgrind/helgrind/hg_wordset.c
/trunk/valgrind/helgrind/hg_wordset.h
/trunk/valgrind/helgrind/libhb.h
/trunk/valgrind/helgrind/libhb_core.c
/trunk/valgrind/helgrind/tests/Makefile.am
/trunk/valgrind/helgrind/tests/annotate_hbefore.c
/trunk/valgrind/helgrind/tests/tc07_hbl1.c
/trunk/valgrind/helgrind/tests/tc08_hbl2.c
/trunk/valgrind/helgrind/tests/tc11_XCHG.c
/trunk/valgrind/include/Makefile.am
/trunk/valgrind/include/pub_tool_aspacehl.h
/trunk/valgrind/include/pub_tool_aspacemgr.h
/trunk/valgrind/include/pub_tool_basics.h
/trunk/valgrind/include/pub_tool_basics_asm.h
/trunk/valgrind/include/pub_tool_clientstate.h
/trunk/valgrind/include/pub_tool_clreq.h
/trunk/valgrind/include/pub_tool_debuginfo.h
/trunk/valgrind/include/pub_tool_errormgr.h
/trunk/valgrind/include/pub_tool_execontext.h
/trunk/valgrind/include/pub_tool_gdbserver.h
/trunk/valgrind/include/pub_tool_hashtable.h
/trunk/valgrind/include/pub_tool_libcassert.h
/trunk/valgrind/include/pub_tool_libcbase.h
/trunk/valgrind/include/pub_tool_libcfile.h
/trunk/valgrind/include/pub_tool_libcprint.h
/trunk/valgrind/include/pub_tool_libcproc.h
/trunk/valgrind/include/pub_tool_libcsetjmp.h
/trunk/valgrind/include/pub_tool_libcsignal.h
/trunk/valgrind/include/pub_tool_machine.h
/trunk/valgrind/include/pub_tool_mallocfree.h
/trunk/valgrind/include/pub_tool_options.h
/trunk/valgrind/include/pub_tool_oset.h
/trunk/valgrind/include/pub_tool_redir.h
/trunk/valgrind/include/pub_tool_replacemalloc.h
/trunk/valgrind/include/pub_tool_seqmatch.h
/trunk/valgrind/include/pub_tool_signals.h
/trunk/valgrind/include/pub_tool_sparsewa.h
/trunk/valgrind/include/pub_tool_stacktrace.h
/trunk/valgrind/include/pub_tool_threadstate.h
/trunk/valgrind/include/pub_tool_tooliface.h
/trunk/valgrind/include/pub_tool_vki.h
/trunk/valgrind/include/pub_tool_vkiscnums.h
/trunk/valgrind/include/pub_tool_vkiscnums_asm.h
/trunk/valgrind/include/pub_tool_wordfm.h
/trunk/valgrind/include/pub_tool_xarray.h
/trunk/valgrind/include/valgrind.h
/trunk/valgrind/include/vki/vki-amd64-linux.h
/trunk/valgrind/include/vki/vki-arm-linux.h
/trunk/valgrind/include/vki/vki-darwin.h
/trunk/valgrind/include/vki/vki-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-amd64-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-arm-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-ppc32-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-ppc64-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-s390x-linux.h
/trunk/valgrind/include/vki/vki-posixtypes-x86-linux.h
/trunk/valgrind/include/vki/vki-ppc32-linux.h
/trunk/valgrind/include/vki/vki-ppc64-linux.h
/trunk/valgrind/include/vki/vki-s390x-linux.h
/trunk/valgrind/include/vki/vki-scnums-amd64-linux.h
/trunk/valgrind/include/vki/vki-scnums-arm-linux.h
/trunk/valgrind/include/vki/vki-scnums-darwin.h
/trunk/valgrind/include/vki/vki-scnums-ppc32-linux.h
/trunk/valgrind/include/vki/vki-scnums-ppc64-linux.h
/trunk/valgrind/include/vki/vki-scnums-s390x-linux.h
/trunk/valgrind/include/vki/vki-scnums-x86-linux.h
/trunk/valgrind/include/vki/vki-x86-linux.h
/trunk/valgrind/lackey/lk_main.c
/trunk/valgrind/massif/Makefile.am
/trunk/valgrind/massif/ms_main.c
/trunk/valgrind/massif/tests/Makefile.am
/trunk/valgrind/memcheck/Makefile.am
/trunk/valgrind/memcheck/docs/mc-manual.xml
/trunk/valgrind/memcheck/mc_errors.c
/trunk/valgrind/memcheck/mc_include.h
/trunk/valgrind/memcheck/mc_leakcheck.c
/trunk/valgrind/memcheck/mc_machine.c
/trunk/valgrind/memcheck/mc_main.c
/trunk/valgrind/memcheck/mc_malloc_wrappers.c
/trunk/valgrind/memcheck/mc_replace_strmem.c
/trunk/valgrind/memcheck/mc_translate.c
/trunk/valgrind/memcheck/memcheck.h
/trunk/valgrind/memcheck/tests/Makefile.am
/trunk/valgrind/memcheck/tests/amd64/Makefile.am
/trunk/valgrind/memcheck/tests/amd64/bt_everything.c
/trunk/valgrind/memcheck/tests/atomic_incs.c
/trunk/valgrind/memcheck/tests/buflen_check.c
/trunk/valgrind/memcheck/tests/custom_alloc.c
/trunk/valgrind/memcheck/tests/custom_alloc.stderr.exp
/trunk/valgrind/memcheck/tests/linux/Makefile.am
/trunk/valgrind/memcheck/tests/match-overrun.supp
/trunk/valgrind/memcheck/tests/memalign2.c
/trunk/valgrind/memcheck/tests/memalign_test.c
/trunk/valgrind/memcheck/tests/mempool2.c
/trunk/valgrind/memcheck/tests/mempool2.stderr.exp
/trunk/valgrind/memcheck/tests/nanoleak.supp
/trunk/valgrind/memcheck/tests/overlap.vgtest
/trunk/valgrind/memcheck/tests/ppc32/power_ISA2_05.c
/trunk/valgrind/memcheck/tests/ppc32/power_ISA2_05.stdout.exp
/trunk/valgrind/memcheck/tests/ppc64/power_ISA2_05.c
/trunk/valgrind/memcheck/tests/ppc64/power_ISA2_05.stdout.exp
/trunk/valgrind/memcheck/tests/suppfree.vgtest
/trunk/valgrind/memcheck/tests/unit_libcbase.c
/trunk/valgrind/memcheck/tests/unit_oset.c
/trunk/valgrind/memcheck/tests/unit_oset.stdout.exp
/trunk/valgrind/memcheck/tests/x86/more_x86_fp.c
/trunk/valgrind/memcheck/tests/x86-linux/scalar.c
/trunk/valgrind/memcheck/tests/x86-linux/scalar.stderr.exp
/trunk/valgrind/mpi/Makefile.am
/trunk/valgrind/mpi/libmpiwrap.c
/trunk/valgrind/nightly/bin/nightly
/trunk/valgrind/none/nl_main.c
/trunk/valgrind/none/tests/Makefile.am
/trunk/valgrind/none/tests/allexec_prepare_prereq
/trunk/valgrind/none/tests/amd64/Makefile.am
/trunk/valgrind/none/tests/amd64/allexec.c
/trunk/valgrind/none/tests/amd64/pcmpstr64.c
/trunk/valgrind/none/tests/amd64/pcmpstr64.stdout.exp
/trunk/valgrind/none/tests/amd64/pcmpxstrx64.c
/trunk/valgrind/none/tests/amd64/sse4-64.c
/trunk/valgrind/none/tests/amd64/sse4-64.stdout.exp
/trunk/valgrind/none/tests/arm/Makefile.am
/trunk/valgrind/none/tests/arm/v6intARM.c
/trunk/valgrind/none/tests/arm/v6intARM.stdout.exp
/trunk/valgrind/none/tests/arm/v6intThumb.c
/trunk/valgrind/none/tests/arm/v6intThumb.stdout.exp
/trunk/valgrind/none/tests/arm/v6media.c
/trunk/valgrind/none/tests/arm/v6media.stdout.exp
/trunk/valgrind/none/tests/arm/vfp.stdout.exp
/trunk/valgrind/none/tests/cmdline1.stdout.exp
/trunk/valgrind/none/tests/cmdline2.stdout.exp
/trunk/valgrind/none/tests/execve.c
/trunk/valgrind/none/tests/fdleak_cmsg.c
/trunk/valgrind/none/tests/linux/Makefile.am
/trunk/valgrind/none/tests/mmap_fcntl_bug.c
/trunk/valgrind/none/tests/mq.c
/trunk/valgrind/none/tests/ppc32/Makefile.am
/trunk/valgrind/none/tests/ppc32/jm-fp.stdout.exp
/trunk/valgrind/none/tests/ppc32/jm-insns.c
/trunk/valgrind/none/tests/ppc32/jm-int.stdout.exp
/trunk/valgrind/none/tests/ppc32/jm-vmx.stdout.exp
/trunk/valgrind/none/tests/ppc32/power5+_round.c
/trunk/valgrind/none/tests/ppc32/round.c
/trunk/valgrind/none/tests/ppc64/Makefile.am
/trunk/valgrind/none/tests/ppc64/jm-fp.stdout.exp
/trunk/valgrind/none/tests/ppc64/jm-int.stdout.exp
/trunk/valgrind/none/tests/ppc64/jm-vmx.stdout.exp
/trunk/valgrind/none/tests/ppc64/round.c
/trunk/valgrind/none/tests/rlimit_nofile.c
/trunk/valgrind/none/tests/s390x/Makefile.am
/trunk/valgrind/none/tests/s390x/op00.stderr.exp1
/trunk/valgrind/none/tests/s390x/op00.stderr.exp2
/trunk/valgrind/none/tests/s390x/op_exception.stderr.exp
/trunk/valgrind/none/tests/s390x/opcodes.h
/trunk/valgrind/none/tests/s390x/test.h
/trunk/valgrind/none/tests/selfrun.vgtest
/trunk/valgrind/none/tests/sem.c
/trunk/valgrind/none/tests/sha1_test.c
/trunk/valgrind/none/tests/shell
/trunk/valgrind/none/tests/valgrind_cpp_test.cpp
/trunk/valgrind/none/tests/x86/Makefile.am
/trunk/valgrind/none/tests/x86/allexec.c
/trunk/valgrind/none/tests/x86/bug125959-x86.c
/trunk/valgrind/none/tests/x86/lzcnt32.c
/trunk/valgrind/none/tests/x86/lzcnt32.stdout.exp
/trunk/valgrind/none/tests/x86/lzcnt32.vgtest
/trunk/valgrind/perf/Makefile.am
/trunk/valgrind/perf/heap.c
/trunk/valgrind/perf/tinycc.c
/trunk/valgrind/perf/vg_perf.in
/trunk/valgrind/tests/Makefile.am
/trunk/valgrind/tests/arch_test.c
/trunk/valgrind/tests/platform_test
/trunk/valgrind/tests/s390x_features.c
/trunk/valgrind/tests/sys_mman.h
/trunk/valgrind/tests/vg_regtest.in
/trunk/valgrind/tests/x86_amd64_features.c
/trunk/valgrind/valgrind.pc.in
/trunk/valgrind/valgrind.spec.in

=======================================
--- /dev/null
+++ /trunk/valgrind/NEWS.old Thu Nov 22 04:55:39 2012
@@ -0,0 +1,2003 @@
+Release 3.3.1 (4 June 2008)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.3.1 fixes a bunch of bugs in 3.3.0, adds support for glibc-2.8 based
+systems (openSUSE 11, Fedora Core 9), improves the existing glibc-2.7
+support, and adds support for the SSSE3 (Core 2) instruction set.
+
+3.3.1 will likely be the last release that supports some very old
+systems. In particular, the next major release, 3.4.0, will drop
+support for the old LinuxThreads threading library, and for gcc
+versions prior to 3.0.
+
+The fixed bugs are as follows. Note that "n-i-bz" stands for "not in
+bugzilla" -- that is, a bug that was reported to us but never got a
+bugzilla entry. We encourage you to file bugs in bugzilla
+(http://bugs.kde.org/enter_valgrind_bug.cgi) rather than mailing the
+developers (or mailing lists) directly -- bugs that are not entered
+into bugzilla tend to get forgotten about or ignored.
+
+n-i-bz Massif segfaults at exit
+n-i-bz Memcheck asserts on Altivec code
+n-i-bz fix sizeof bug in Helgrind
+n-i-bz check fd on sys_llseek
+n-i-bz update syscall lists to kernel 2.6.23.1
+n-i-bz support sys_sync_file_range
+n-i-bz handle sys_sysinfo, sys_getresuid, sys_getresgid on ppc64-linux
+n-i-bz intercept memcpy in 64-bit ld.so's
+n-i-bz Fix wrappers for sys_{futimesat,utimensat}
+n-i-bz Minor false-error avoidance fixes for Memcheck
+n-i-bz libmpiwrap.c: add a wrapper for MPI_Waitany
+n-i-bz helgrind support for glibc-2.8
+n-i-bz partial fix for mc_leakcheck.c:698 assert:
+ 'lc_shadows[i]->data + lc_shadows[i] ...
+n-i-bz Massif/Cachegrind output corruption when programs fork
+n-i-bz register allocator fix: handle spill stores correctly
+n-i-bz add support for PA6T PowerPC CPUs
+126389 vex x86->IR: 0xF 0xAE (FXRSTOR)
+158525 ==126389
+152818 vex x86->IR: 0xF3 0xAC (repz lodsb)
+153196 vex x86->IR: 0xF2 0xA6 (repnz cmpsb)
+155011 vex x86->IR: 0xCF (iret)
+155091 Warning [...] unhandled DW_OP_ opcode 0x23
+156960 ==155901
+155528 support Core2/SSSE3 insns on x86/amd64
+155929 ms_print fails on massif outputs containing long lines
+157665 valgrind fails on shmdt(0) after shmat to 0
+157748 support x86 PUSHFW/POPFW
+158212 helgrind: handle pthread_rwlock_try{rd,wr}lock.
+158425 sys_poll incorrectly emulated when RES==0
+158744 vex amd64->IR: 0xF0 0x41 0xF 0xC0 (xaddb)
+160907 Support for a couple of recent Linux syscalls
+161285 Patch -- support for eventfd() syscall
+161378 illegal opcode in debug libm (FUCOMPP)
+160136 ==161378
+161487 number of suppressions files is limited to 10
+162386 ms_print typo in milliseconds time unit for massif
+161036 exp-drd: client allocated memory was never freed
+162663 signalfd_wrapper fails on 64bit linux
+
+(3.3.1.RC1: 2 June 2008, vex r1854, valgrind r8169).
+(3.3.1: 4 June 2008, vex r1854, valgrind r8180).
+
+
+
+Release 3.3.0 (7 December 2007)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.3.0 is a feature release with many significant improvements and the
+usual collection of bug fixes. This release supports X86/Linux,
+AMD64/Linux, PPC32/Linux and PPC64/Linux. Support for recent distros
+(using gcc 4.3, glibc 2.6 and 2.7) has been added.
+
+The main excitement in 3.3.0 is new and improved tools. Helgrind
+works again, Massif has been completely overhauled and much improved,
+Cachegrind now does branch-misprediction profiling, and a new category
+of experimental tools has been created, containing two new tools:
+Omega and DRD. There are many other smaller improvements. In detail:
+
+- Helgrind has been completely overhauled and works for the first time
+ since Valgrind 2.2.0. Supported functionality is: detection of
+ misuses of the POSIX PThreads API, detection of potential deadlocks
+ resulting from cyclic lock dependencies, and detection of data
+ races. Compared to the 2.2.0 Helgrind, the race detection algorithm
+ has some significant improvements aimed at reducing the false error
+ rate. Handling of various kinds of corner cases has been improved.
+ Efforts have been made to make the error messages easier to
+ understand. Extensive documentation is provided.
+
+- Massif has been completely overhauled. Instead of measuring
+ space-time usage -- which wasn't always useful and many people found
+ confusing -- it now measures space usage at various points in the
+ execution, including the point of peak memory allocation. Its
+ output format has also changed: instead of producing PostScript
+ graphs and HTML text, it produces a single text output (via the new
+ 'ms_print' script) that contains both a graph and the old textual
+ information, but in a more compact and readable form. Finally, the
+ new version should be more reliable than the old one, as it has been
+ tested more thoroughly.
+
+- Cachegrind has been extended to do branch-misprediction profiling.
+ Both conditional and indirect branches are profiled. The default
+ behaviour of Cachegrind is unchanged. To use the new functionality,
+ give the option --branch-sim=yes.
+
+- A new category of "experimental tools" has been created. Such tools
+ may not work as well as the standard tools, but are included because
+ some people will find them useful, and because exposure to a wider
+ user group provides tool authors with more end-user feedback. These
+ tools have a "exp-" prefix attached to their names to indicate their
+ experimental nature. Currently there are two experimental tools:
+
+ * exp-Omega: an instantaneous leak detector. See
+ exp-omega/docs/omega_introduction.txt.
+
+ * exp-DRD: a data race detector based on the happens-before
+ relation. See exp-drd/docs/README.txt.
+
+- Scalability improvements for very large programs, particularly those
+ which have a million or more malloc'd blocks in use at once. These
+ improvements mostly affect Memcheck. Memcheck is also up to 10%
+ faster for all programs, with x86-linux seeing the largest
+ improvement.
+
+- Works well on the latest Linux distros. Has been tested on Fedora
+ Core 8 (x86, amd64, ppc32, ppc64) and openSUSE 10.3. glibc 2.6 and
+ 2.7 are supported. gcc-4.3 (in its current pre-release state) is
+ supported. At the same time, 3.3.0 retains support for older
+ distros.
+
+- The documentation has been modestly reorganised with the aim of
+ making it easier to find information on common-usage scenarios.
+ Some advanced material has been moved into a new chapter in the main
+ manual, so as to unclutter the main flow, and other tidying up has
+ been done.
+
+- There is experimental support for AIX 5.3, both 32-bit and 64-bit
+ processes. You need to be running a 64-bit kernel to use Valgrind
+ on a 64-bit executable.
+
+- There have been some changes to command line options, which may
+ affect you:
+
+ * --log-file-exactly and
+ --log-file-qualifier options have been removed.
+
+ To make up for this --log-file option has been made more powerful.
+ It now accepts a %p format specifier, which is replaced with the
+ process ID, and a %q{FOO} format specifier, which is replaced with
+ the contents of the environment variable FOO.
+
+ * --child-silent-after-fork=yes|no [no]
+
+ Causes Valgrind to not show any debugging or logging output for
+ the child process resulting from a fork() call. This can make the
+ output less confusing (although more misleading) when dealing with
+ processes that create children.
+
+ * --cachegrind-out-file, --callgrind-out-file and --massif-out-file
+
+ These control the names of the output files produced by
+ Cachegrind, Callgrind and Massif. They accept the same %p and %q
+ format specifiers that --log-file accepts. --callgrind-out-file
+ replaces Callgrind's old --base option.
+
+ * Cachegrind's 'cg_annotate' script no longer uses the --<pid>
+ option to specify the output file. Instead, the first non-option
+ argument is taken to be the name of the output file, and any
+ subsequent non-option arguments are taken to be the names of
+ source files to be annotated.
+
+ * Cachegrind and Callgrind now use directory names where possible in
+ their output files. This means that the -I option to
+ 'cg_annotate' and 'callgrind_annotate' should not be needed in
+ most cases. It also means they can correctly handle the case
+ where two source files in different directories have the same
+ name.
+
+- Memcheck offers a new suppression kind: "Jump". This is for
+ suppressing jump-to-invalid-address errors. Previously you had to
+ use an "Addr1" suppression, which didn't make much sense.
+
+- Memcheck has new flags --malloc-fill=<hexnum> and
+ --free-fill=<hexnum> which free malloc'd / free'd areas with the
+ specified byte. This can help shake out obscure memory corruption
+ problems. The definedness and addressability of these areas is
+ unchanged -- only the contents are affected.
+
+- The behaviour of Memcheck's client requests VALGRIND_GET_VBITS and
+ VALGRIND_SET_VBITS have changed slightly. They no longer issue
+ addressability errors -- if either array is partially unaddressable,
+ they just return 3 (as before). Also, SET_VBITS doesn't report
+ definedness errors if any of the V bits are undefined.
+
+- The following Memcheck client requests have been removed:
+ VALGRIND_MAKE_NOACCESS
+ VALGRIND_MAKE_WRITABLE
+ VALGRIND_MAKE_READABLE
+ VALGRIND_CHECK_WRITABLE
+ VALGRIND_CHECK_READABLE
+ VALGRIND_CHECK_DEFINED
+ They were deprecated in 3.2.0, when equivalent but better-named client
+ requests were added. See the 3.2.0 release notes for more details.
+
+- The behaviour of the tool Lackey has changed slightly. First, the output
+ from --trace-mem has been made more compact, to reduce the size of the
+ traces. Second, a new option --trace-superblocks has been added, which
+ shows the addresses of superblocks (code blocks) as they are executed.
+
+- The following bugs have been fixed. Note that "n-i-bz" stands for
+ "not in bugzilla" -- that is, a bug that was reported to us but
+ never got a bugzilla entry. We encourage you to file bugs in
+ bugzilla (http://bugs.kde.org/enter_valgrind_bug.cgi) rather than
+ mailing the developers (or mailing lists) directly.
+
+ n-i-bz x86_linux_REDIR_FOR_index() broken
+ n-i-bz guest-amd64/toIR.c:2512 (dis_op2_E_G): Assertion `0' failed.
+ n-i-bz Support x86 INT insn (INT (0xCD) 0x40 - 0x43)
+ n-i-bz Add sys_utimensat system call for Linux x86 platform
+ 79844 Helgrind complains about race condition which does not exist
+ 82871 Massif output function names too short
+ 89061 Massif: ms_main.c:485 (get_XCon): Assertion `xpt->max_chi...'
+ 92615 Write output from Massif at crash
+ 95483 massif feature request: include peak allocation in report
+ 112163 MASSIF crashed with signal 7 (SIGBUS) after running 2 days
+ 119404 problems running setuid executables (partial fix)
+ 121629 add instruction-counting mode for timing
+ 127371 java vm giving unhandled instruction bytes: 0x26 0x2E 0x64 0x65
+ 129937 ==150380
+ 129576 Massif loses track of memory, incorrect graphs
+ 132132 massif --format=html output does not do html entity escaping
+ 132950 Heap alloc/usage summary
+ 133962 unhandled instruction bytes: 0xF2 0x4C 0xF 0x10
+ 134990 use -fno-stack-protector if possible
+ 136382 ==134990
+ 137396 I would really like helgrind to work again...
+ 137714 x86/amd64->IR: 0x66 0xF 0xF7 0xC6 (maskmovq, maskmovdq)
+ 141631 Massif: percentages don't add up correctly
+ 142706 massif numbers don't seem to add up
+ 143062 massif crashes on app exit with signal 8 SIGFPE
+ 144453 (get_XCon): Assertion 'xpt->max_children != 0' failed.
+ 145559 valgrind aborts when malloc_stats is called
+ 145609 valgrind aborts all runs with 'repeated section!'
+ 145622 --db-attach broken again on x86-64
+ 145837 ==149519
+ 145887 PPC32: getitimer() system call is not supported
+ 146252 ==150678
+ 146456 (update_XCon): Assertion 'xpt->curr_space >= -space_delta'...
+ 146701 ==134990
+ 146781 Adding support for private futexes
+ 147325 valgrind internal error on syscall (SYS_io_destroy, 0)
+ 147498 amd64->IR: 0xF0 0xF 0xB0 0xF (lock cmpxchg %cl,(%rdi))
+ 147545 Memcheck: mc_main.c:817 (get_sec_vbits8): Assertion 'n' failed.
+ 147628 SALC opcode 0xd6 unimplemented
+ 147825 crash on amd64-linux with gcc 4.2 and glibc 2.6 (CFI)
+ 148174 Incorrect type of freed_list_volume causes assertion [...]
+ 148447 x86_64 : new NOP codes: 66 66 66 66 2e 0f 1f
+ 149182 PPC Trap instructions not implemented in valgrind
+ 149504 Assertion hit on alloc_xpt->curr_space >= -space_delta
+ 149519 ppc32: V aborts with SIGSEGV on execution of a signal handler
+ 149892 ==137714
+ 150044 SEGV during stack deregister
+ 150380 dwarf/gcc interoperation (dwarf3 read problems)
+ 150408 ==148447
+ 150678 guest-amd64/toIR.c:3741 (dis_Grp5): Assertion `sz == 4' failed
+ 151209 V unable to execute programs for users with UID > 2^16
+ 151938 help on --db-command= misleading
+ 152022 subw $0x28, %%sp causes assertion failure in memcheck
+ 152357 inb and outb not recognized in 64-bit mode
+ 152501 vex x86->IR: 0x27 0x66 0x89 0x45 (daa)
+ 152818 vex x86->IR: 0xF3 0xAC 0xFC 0x9C (rep lodsb)
+
+Developer-visible changes:
+
+- The names of some functions and types within the Vex IR have
+ changed. Run 'svn log -r1689 VEX/pub/libvex_ir.h' for full details.
+ Any existing standalone tools will have to be updated to reflect
+ these changes. The new names should be clearer. The file
+ VEX/pub/libvex_ir.h is also much better commented.
+
+- A number of new debugging command line options have been added.
+ These are mostly of use for debugging the symbol table and line
+ number readers:
+
+ --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>
+ --trace-cfi=no|yes show call-frame-info details? [no]
+ --debug-dump=syms mimic /usr/bin/readelf --syms
+ --debug-dump=line mimic /usr/bin/readelf --debug-dump=line
+ --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames
+ --sym-offsets=yes|no show syms in form 'name+offset' ? [no]
+
+- Internally, the code base has been further factorised and
+ abstractified, particularly with respect to support for non-Linux
+ OSs.
+
+(3.3.0.RC1: 2 Dec 2007, vex r1803, valgrind r7268).
+(3.3.0.RC2: 5 Dec 2007, vex r1804, valgrind r7282).
+(3.3.0.RC3: 9 Dec 2007, vex r1804, valgrind r7288).
+(3.3.0: 10 Dec 2007, vex r1804, valgrind r7290).
+
+
+
+Release 3.2.3 (29 Jan 2007)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Unfortunately 3.2.2 introduced a regression which can cause an
+assertion failure ("vex: the `impossible' happened: eqIRConst") when
+running obscure pieces of SSE code. 3.2.3 fixes this and adds one
+more glibc-2.5 intercept. In all other respects it is identical to
+3.2.2. Please do not use (or package) 3.2.2; instead use 3.2.3.
+
+n-i-bz vex: the `impossible' happened: eqIRConst
+n-i-bz Add an intercept for glibc-2.5 __stpcpy_chk
+
+(3.2.3: 29 Jan 2007, vex r1732, valgrind r6560).
+
+
+Release 3.2.2 (22 Jan 2007)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.2.2 fixes a bunch of bugs in 3.2.1, adds support for glibc-2.5 based
+systems (openSUSE 10.2, Fedora Core 6), improves support for icc-9.X
+compiled code, and brings modest performance improvements in some
+areas, including amd64 floating point, powerpc support, and startup
+responsiveness on all targets.
+
+The fixed bugs are as follows. Note that "n-i-bz" stands for "not in
+bugzilla" -- that is, a bug that was reported to us but never got a
+bugzilla entry. We encourage you to file bugs in bugzilla
+(http://bugs.kde.org/enter_valgrind_bug.cgi) rather than mailing the
+developers (or mailing lists) directly.
+
+129390 ppc?->IR: some kind of VMX prefetch (dstt)
+129968 amd64->IR: 0xF 0xAE 0x0 (fxsave)
+134319 ==129968
+133054 'make install' fails with syntax errors
+118903 ==133054
+132998 startup fails in when running on UML
+134207 pkg-config output contains @VG_PLATFORM@
+134727 valgrind exits with "Value too large for defined data type"
+n-i-bz ppc32/64: support mcrfs
+n-i-bz Cachegrind/Callgrind: Update cache parameter detection
+135012 x86->IR: 0xD7 0x8A 0xE0 0xD0 (xlat)
+125959 ==135012
+126147 x86->IR: 0xF2 0xA5 0xF 0x77 (repne movsw)
+136650 amd64->IR: 0xC2 0x8 0x0
+135421 x86->IR: unhandled Grp5(R) case 6
+n-i-bz Improved documentation of the IR intermediate representation
+n-i-bz jcxz (x86) (users list, 8 Nov)
+n-i-bz ExeContext hashing fix
+n-i-bz fix CFI reading failures ("Dwarf CFI 0:24 0:32 0:48 0:7")
+n-i-bz fix Cachegrind/Callgrind simulation bug
+n-i-bz libmpiwrap.c: fix handling of MPI_LONG_DOUBLE
+n-i-bz make User errors suppressible
+136844 corrupted malloc line when using --gen-suppressions=yes
+138507 ==136844
+n-i-bz Speed up the JIT's register allocator
+n-i-bz Fix confusing leak-checker flag hints
+n-i-bz Support recent autoswamp versions
+n-i-bz ppc32/64 dispatcher speedups
+n-i-bz ppc64 front end rld/rlw improvements
+n-i-bz ppc64 back end imm64 improvements
+136300 support 64K pages on ppc64-linux
+139124 == 136300
+n-i-bz fix ppc insn set tests for gcc >= 4.1
+137493 x86->IR: recent binutils no-ops
+137714 x86->IR: 0x66 0xF 0xF7 0xC6 (maskmovdqu)
+138424 "failed in UME with error 22" (produce a better error msg)
+138856 ==138424
+138627 Enhancement support for prctl ioctls
+138896 Add support for usb ioctls
+136059 ==138896
+139050 ppc32->IR: mfspr 268/269 instructions not handled
+n-i-bz ppc32->IR: lvxl/stvxl
+n-i-bz glibc-2.5 support
+n-i-bz memcheck: provide replacement for mempcpy
+n-i-bz memcheck: replace bcmp in ld.so
+n-i-bz Use 'ifndef' in VEX's Makefile correctly
+n-i-bz Suppressions for MVL 4.0.1 on ppc32-linux
+n-i-bz libmpiwrap.c: Fixes for MPICH
+n-i-bz More robust handling of hinted client mmaps
+139776 Invalid read in unaligned memcpy with Intel compiler v9
+n-i-bz Generate valid XML even for very long fn names
+n-i-bz Don't prompt about suppressions for unshown reachable leaks
+139910 amd64 rcl is not supported
+n-i-bz DWARF CFI reader: handle DW_CFA_undefined
+n-i-bz DWARF CFI reader: handle icc9 generated CFI info better
+n-i-bz fix false uninit-value errs in icc9 generated FP code
+n-i-bz reduce extraneous frames in libmpiwrap.c
+n-i-bz support pselect6 on amd64-linux
+
+(3.2.2: 22 Jan 2007, vex r1729, valgrind r6545).
+
+
+Release 3.2.1 (16 Sept 2006)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.2.1 adds x86/amd64 support for all SSE3 instructions except monitor
+and mwait, further reduces memcheck's false error rate on all
+platforms, adds support for recent binutils (in OpenSUSE 10.2 and
+Fedora Rawhide) and fixes a bunch of bugs in 3.2.0. Some of the fixed
+bugs were causing large programs to segfault with --tool=callgrind and
+--tool=cachegrind, so an upgrade is recommended.
+
+In view of the fact that any 3.3.0 release is unlikely to happen until
+well into 1Q07, we intend to keep the 3.2.X line alive for a while
+yet, and so we tentatively plan a 3.2.2 release sometime in December
+06.
+
+The fixed bugs are as follows. Note that "n-i-bz" stands for "not in
+bugzilla" -- that is, a bug that was reported to us but never got a
+bugzilla entry.
+
+n-i-bz Expanding brk() into last available page asserts
+n-i-bz ppc64-linux stack RZ fast-case snafu
+n-i-bz 'c' in --gen-supps=yes doesn't work
+n-i-bz VG_N_SEGMENTS too low (users, 28 June)
+n-i-bz VG_N_SEGNAMES too low (Stu Robinson)
+106852 x86->IR: fisttp (SSE3)
+117172 FUTEX_WAKE does not use uaddr2
+124039 Lacks support for VKI_[GP]IO_UNIMAP*
+127521 amd64->IR: 0xF0 0x48 0xF 0xC7 (cmpxchg8b)
+128917 amd64->IR: 0x66 0xF 0xF6 0xC4 (psadbw,SSE2)
+129246 JJ: ppc32/ppc64 syscalls, w/ patch
+129358 x86->IR: fisttpl (SSE3)
+129866 cachegrind/callgrind causes executable to die
+130020 Can't stat .so/.exe error while reading symbols
+130388 Valgrind aborts when process calls malloc_trim()
+130638 PATCH: ppc32 missing system calls
+130785 amd64->IR: unhandled instruction "pushfq"
+131481: (HINT_NOP) vex x86->IR: 0xF 0x1F 0x0 0xF
+131298 ==131481
+132146 Programs with long sequences of bswap[l,q]s
+132918 vex amd64->IR: 0xD9 0xF8 (fprem)
+132813 Assertion at priv/guest-x86/toIR.c:652 fails
+133051 'cfsi->len > 0 && cfsi->len < 2000000' failed
+132722 valgrind header files are not standard C
+n-i-bz Livelocks entire machine (users list, Timothy Terriberry)
+n-i-bz Alex Bennee mmap problem (9 Aug)
+n-i-bz BartV: Don't print more lines of a stack-trace than were obtained.
+n-i-bz ppc32 SuSE 10.1 redir
+n-i-bz amd64 padding suppressions
+n-i-bz amd64 insn printing fix.
+n-i-bz ppc cmp reg,reg fix
+n-i-bz x86/amd64 iropt e/rflag reduction rules
+n-i-bz SuSE 10.1 (ppc32) minor fixes
+133678 amd64->IR: 0x48 0xF 0xC5 0xC0 (pextrw?)
+133694 aspacem assertion: aspacem_minAddr <= holeStart
+n-i-bz callgrind: fix warning about malformed creator line
+n-i-bz callgrind: fix annotate script for data produced with
+ --dump-instr=yes
+n-i-bz callgrind: fix failed assertion when toggling
+ instrumentation mode
+n-i-bz callgrind: fix annotate script fix warnings with
+ --collect-jumps=yes
+n-i-bz docs path hardwired (Dennis Lubert)
+
+The following bugs were not fixed, due primarily to lack of developer
+time, and also because bug reporters did not answer requests for
+feedback in time for the release:
+
+129390 ppc?->IR: some kind of VMX prefetch (dstt)
+129968 amd64->IR: 0xF 0xAE 0x0 (fxsave)
+133054 'make install' fails with syntax errors
+n-i-bz Signal race condition (users list, 13 June, Johannes Berg)
+n-i-bz Unrecognised instruction at address 0x70198EC2 (users list,
+ 19 July, Bennee)
+132998 startup fails in when running on UML
+
+The following bug was tentatively fixed on the mainline but the fix
+was considered too risky to push into 3.2.X:
+
+133154 crash when using client requests to register/deregister stack
+
+(3.2.1: 16 Sept 2006, vex r1658, valgrind r6070).
+
+
+Release 3.2.0 (7 June 2006)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.2.0 is a feature release with many significant improvements and the
+usual collection of bug fixes. This release supports X86/Linux,
+AMD64/Linux, PPC32/Linux and PPC64/Linux.
+
+Performance, especially of Memcheck, is improved, Addrcheck has been
+removed, Callgrind has been added, PPC64/Linux support has been added,
+Lackey has been improved, and MPI support has been added. In detail:
+
+- Memcheck has improved speed and reduced memory use. Run times are
+ typically reduced by 15-30%, averaging about 24% for SPEC CPU2000.
+ The other tools have smaller but noticeable speed improvements. We
+ are interested to hear what improvements users get.
+
+ Memcheck uses less memory due to the introduction of a compressed
+ representation for shadow memory. The space overhead has been
+ reduced by a factor of up to four, depending on program behaviour.
+ This means you should be able to run programs that use more memory
+ than before without hitting problems.
+
+- Addrcheck has been removed. It has not worked since version 2.4.0,
+ and the speed and memory improvements to Memcheck make it redundant.
+ If you liked using Addrcheck because it didn't give undefined value
+ errors, you can use the new Memcheck option --undef-value-errors=no
+ to get the same behaviour.
+
+- The number of undefined-value errors incorrectly reported by
+ Memcheck has been reduced (such false reports were already very
+ rare). In particular, efforts have been made to ensure Memcheck
+ works really well with gcc 4.0/4.1-generated code on X86/Linux and
+ AMD64/Linux.
+
+- Josef Weidendorfer's popular Callgrind tool has been added. Folding
+ it in was a logical step given its popularity and usefulness, and
+ makes it easier for us to ensure it works "out of the box" on all
+ supported targets. The associated KDE KCachegrind GUI remains a
+ separate project.
+
+- A new release of the Valkyrie GUI for Memcheck, version 1.2.0,
+ accompanies this release. Improvements over previous releases
+ include improved robustness, many refinements to the user interface,
+ and use of a standard autoconf/automake build system. You can get
+ it from http://www.valgrind.org/downloads/guis.html.
+
+- Valgrind now works on PPC64/Linux. As with the AMD64/Linux port,
+ this supports programs using to 32G of address space. On 64-bit
+ capable PPC64/Linux setups, you get a dual architecture build so
+ that both 32-bit and 64-bit executables can be run. Linux on POWER5
+ is supported, and POWER4 is also believed to work. Both 32-bit and
+ 64-bit DWARF2 is supported. This port is known to work well with
+ both gcc-compiled and xlc/xlf-compiled code.
+
+- Floating point accuracy has been improved for PPC32/Linux.
+ Specifically, the floating point rounding mode is observed on all FP
+ arithmetic operations, and multiply-accumulate instructions are
+ preserved by the compilation pipeline. This means you should get FP
+ results which are bit-for-bit identical to a native run. These
+ improvements are also present in the PPC64/Linux port.
+
+- Lackey, the example tool, has been improved:
+
+ * It has a new option --detailed-counts (off by default) which
+ causes it to print out a count of loads, stores and ALU operations
+ done, and their sizes.
+
+ * It has a new option --trace-mem (off by default) which causes it
+ to print out a trace of all memory accesses performed by a
+ program. It's a good starting point for building Valgrind tools
+ that need to track memory accesses. Read the comments at the top
+ of the file lackey/lk_main.c for details.
+
+ * The original instrumentation (counting numbers of instructions,
+ jumps, etc) is now controlled by a new option --basic-counts. It
+ is on by default.
+
+- MPI support: partial support for debugging distributed applications
+ using the MPI library specification has been added. Valgrind is
+ aware of the memory state changes caused by a subset of the MPI
+ functions, and will carefully check data passed to the (P)MPI_
+ interface.
+
+- A new flag, --error-exitcode=, has been added. This allows changing
+ the exit code in runs where Valgrind reported errors, which is
+ useful when using Valgrind as part of an automated test suite.
+
+- Various segfaults when reading old-style "stabs" debug information
+ have been fixed.
+
+- A simple performance evaluation suite has been added. See
+ perf/README and README_DEVELOPERS for details. There are
+ various bells and whistles.
+
+- New configuration flags:
+ --enable-only32bit
+ --enable-only64bit
+ By default, on 64 bit platforms (ppc64-linux, amd64-linux) the build
+ system will attempt to build a Valgrind which supports both 32-bit
+ and 64-bit executables. This may not be what you want, and you can
+ override the default behaviour using these flags.
+
+Please note that Helgrind is still not working. We have made an
+important step towards making it work again, however, with the
+addition of function wrapping (see below).
+
+Other user-visible changes:
+
+- Valgrind now has the ability to intercept and wrap arbitrary
+ functions. This is a preliminary step towards making Helgrind work
+ again, and was required for MPI support.
+
+- There are some changes to Memcheck's client requests. Some of them
+ have changed names:
+
+ MAKE_NOACCESS --> MAKE_MEM_NOACCESS
+ MAKE_WRITABLE --> MAKE_MEM_UNDEFINED
+ MAKE_READABLE --> MAKE_MEM_DEFINED
+
+ CHECK_WRITABLE --> CHECK_MEM_IS_ADDRESSABLE
+ CHECK_READABLE --> CHECK_MEM_IS_DEFINED
+ CHECK_DEFINED --> CHECK_VALUE_IS_DEFINED
+
+ The reason for the change is that the old names are subtly
+ misleading. The old names will still work, but they are deprecated
+ and may be removed in a future release.
+
+ We also added a new client request:
+
+ MAKE_MEM_DEFINED_IF_ADDRESSABLE(a, len)
+
+ which is like MAKE_MEM_DEFINED but only affects a byte if the byte is
+ already addressable.
+
+- The way client requests are encoded in the instruction stream has
+ changed. Unfortunately, this means 3.2.0 will not honour client
+ requests compiled into binaries using headers from earlier versions
+ of Valgrind. We will try to keep the client request encodings more
+ stable in future.
+
+BUGS FIXED:
+
+108258 NPTL pthread cleanup handlers not called
+117290 valgrind is sigKILL'd on startup
+117295 == 117290
+118703 m_signals.c:1427 Assertion 'tst->status == VgTs_WaitSys'
+118466 add %reg, %reg generates incorrect validity for bit 0
+123210 New: strlen from ld-linux on amd64
+123244 DWARF2 CFI reader: unhandled CFI instruction 0:18
+123248 syscalls in glibc-2.4: openat, fstatat, symlinkat
+123258 socketcall.recvmsg(msg.msg_iov[i] points to uninit
+123535 mremap(new_addr) requires MREMAP_FIXED in 4th arg
+123836 small typo in the doc
+124029 ppc compile failed: `vor' gcc 3.3.5
+124222 Segfault: @@don't know what type ':' is
+124475 ppc32: crash (syscall?) timer_settime()
+124499 amd64->IR: 0xF 0xE 0x48 0x85 (femms)
+124528 FATAL: aspacem assertion failed: segment_is_sane
+124697 vex x86->IR: 0xF 0x70 0xC9 0x0 (pshufw)
+124892 vex x86->IR: 0xF3 0xAE (REPx SCASB)
+126216 == 124892
+124808 ppc32: sys_sched_getaffinity() not handled
+n-i-bz Very long stabs strings crash m_debuginfo
+n-i-bz amd64->IR: 0x66 0xF 0xF5 (pmaddwd)
+125492 ppc32: support a bunch more syscalls
+121617 ppc32/64: coredumping gives assertion failure
+121814 Coregrind return error as exitcode patch
+126517 == 121814
+125607 amd64->IR: 0x66 0xF 0xA3 0x2 (btw etc)
+125651 amd64->IR: 0xF8 0x49 0xFF 0xE3 (clc?)
+126253 x86 movx is wrong
+126451 3.2 SVN doesn't work on ppc32 CPU's without FPU
+126217 increase # threads
+126243 vex x86->IR: popw mem
+126583 amd64->IR: 0x48 0xF 0xA4 0xC2 (shld $1,%rax,%rdx)
+126668 amd64->IR: 0x1C 0xFF (sbb $0xff,%al)
+126696 support for CDROMREADRAW ioctl and CDROMREADTOCENTRY fix
+126722 assertion: segment_is_sane at m_aspacemgr/aspacemgr.c:1624
+126938 bad checking for syscalls linkat, renameat, symlinkat
+
+(3.2.0RC1: 27 May 2006, vex r1626, valgrind r5947).
+(3.2.0: 7 June 2006, vex r1628, valgrind r5957).
+
+
+Release 3.1.1 (15 March 2006)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.1.1 fixes a bunch of bugs reported in 3.1.0. There is no new
+functionality. The fixed bugs are:
+
+(note: "n-i-bz" means "not in bugzilla" -- this bug does not have
+ a bugzilla entry).
+
+n-i-bz ppc32: fsub 3,3,3 in dispatcher doesn't clear NaNs
+n-i-bz ppc32: __NR_{set,get}priority
+117332 x86: missing line info with icc 8.1
+117366 amd64: 0xDD 0x7C fnstsw
+118274 == 117366
+117367 amd64: 0xD9 0xF4 fxtract
+117369 amd64: __NR_getpriority (140)
+117419 ppc32: lfsu f5, -4(r11)
+117419 ppc32: fsqrt
+117936 more stabs problems (segfaults while reading debug info)
+119914 == 117936
+120345 == 117936
+118239 amd64: 0xF 0xAE 0x3F (clflush)
+118939 vm86old system call
+n-i-bz memcheck/tests/mempool reads freed memory
+n-i-bz AshleyP's custom-allocator assertion
+n-i-bz Dirk strict-aliasing stuff
+n-i-bz More space for debugger cmd line (Dan Thaler)
+n-i-bz Clarified leak checker output message
+n-i-bz AshleyP's --gen-suppressions output fix
+n-i-bz cg_annotate's --sort option broken
+n-i-bz OSet 64-bit fastcmp bug
+n-i-bz VG_(getgroups) fix (Shinichi Noda)
+n-i-bz ppc32: allocate from callee-saved FP/VMX regs
+n-i-bz misaligned path word-size bug in mc_main.c
+119297 Incorrect error message for sse code
+120410 x86: prefetchw (0xF 0xD 0x48 0x4)
+120728 TIOCSERGETLSR, TIOCGICOUNT, HDIO_GET_DMA ioctls
+120658 Build fixes for gcc 2.96
+120734 x86: Support for changing EIP in signal handler
+n-i-bz memcheck/tests/zeropage de-looping fix
+n-i-bz x86: fxtract doesn't work reliably
+121662 x86: lock xadd (0xF0 0xF 0xC0 0x2)
+121893 calloc does not always return zeroed memory
+121901 no support for syscall tkill
+n-i-bz Suppression update for Debian unstable
+122067 amd64: fcmovnu (0xDB 0xD9)
+n-i-bz ppc32: broken signal handling in cpu feature detection
+n-i-bz ppc32: rounding mode problems (improved, partial fix only)
+119482 ppc32: mtfsb1
+n-i-bz ppc32: mtocrf/mfocrf
+
+(3.1.1: 15 March 2006, vex r1597, valgrind r5771).
+
+
+Release 3.1.0 (25 November 2005)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.1.0 is a feature release with a number of significant improvements:
+AMD64 support is much improved, PPC32 support is good enough to be
+usable, and the handling of memory management and address space is
+much more robust. In detail:
+
+- AMD64 support is much improved. The 64-bit vs. 32-bit issues in
+ 3.0.X have been resolved, and it should "just work" now in all
+ cases. On AMD64 machines both 64-bit and 32-bit versions of
+ Valgrind are built. The right version will be invoked
+ automatically, even when using --trace-children and mixing execution
+ between 64-bit and 32-bit executables. Also, many more instructions
+ are supported.
+
+- PPC32 support is now good enough to be usable. It should work with
+ all tools, but please let us know if you have problems. Three
+ classes of CPUs are supported: integer only (no FP, no Altivec),
+ which covers embedded PPC uses, integer and FP but no Altivec
+ (G3-ish), and CPUs capable of Altivec too (G4, G5).
+
+- Valgrind's address space management has been overhauled. As a
+ result, Valgrind should be much more robust with programs that use
+ large amounts of memory. There should be many fewer "memory
+ exhausted" messages, and debug symbols should be read correctly on
+ large (eg. 300MB+) executables. On 32-bit machines the full address
+ space available to user programs (usually 3GB or 4GB) can be fully
+ utilised. On 64-bit machines up to 32GB of space is usable; when
+ using Memcheck that means your program can use up to about 14GB.
+
+ A side effect of this change is that Valgrind is no longer protected
+ against wild writes by the client. This feature was nice but relied
+ on the x86 segment registers and so wasn't portable.
+
+- Most users should not notice, but as part of the address space
+ manager change, the way Valgrind is built has been changed. Each
+ tool is now built as a statically linked stand-alone executable,
+ rather than as a shared object that is dynamically linked with the
+ core. The "valgrind" program invokes the appropriate tool depending
+ on the --tool option. This slightly increases the amount of disk
+ space used by Valgrind, but it greatly simplified many things and
+ removed Valgrind's dependence on glibc.
+
+Please note that Addrcheck and Helgrind are still not working. Work
+is underway to reinstate them (or equivalents). We apologise for the
+inconvenience.
+
+Other user-visible changes:
+
+- The --weird-hacks option has been renamed --sim-hints.
+
+- The --time-stamp option no longer gives an absolute date and time.
+ It now prints the time elapsed since the program began.
+
+- It should build with gcc-2.96.
+
+- Valgrind can now run itself (see README_DEVELOPERS for how).
+ This is not much use to you, but it means the developers can now
+ profile Valgrind using Cachegrind. As a result a couple of
+ performance bad cases have been fixed.
+
+- The XML output format has changed slightly. See
+ docs/internals/xml-output.txt.
+
+- Core dumping has been reinstated (it was disabled in 3.0.0 and 3.0.1).
+ If your program crashes while running under Valgrind, a core file with
+ the name "vgcore.<pid>" will be created (if your settings allow core
+ file creation). Note that the floating point information is not all
+ there. If Valgrind itself crashes, the OS will create a normal core
+ file.
+
+The following are some user-visible changes that occurred in earlier
+versions that may not have been announced, or were announced but not
+widely noticed. So we're mentioning them now.
+
+- The --tool flag is optional once again; if you omit it, Memcheck
+ is run by default.
+
+- The --num-callers flag now has a default value of 12. It was
+ previously 4.
+
+- The --xml=yes flag causes Valgrind's output to be produced in XML
+ format. This is designed to make it easy for other programs to
+ consume Valgrind's output. The format is described in the file
+ docs/internals/xml-format.txt.
+
+- The --gen-suppressions flag supports an "all" value that causes every
+ suppression to be printed without asking.
+
+- The --log-file option no longer puts "pid" in the filename, eg. the
+ old name "foo.pid12345" is now "foo.12345".
+
+- There are several graphical front-ends for Valgrind, such as Valkyrie,
+ Alleyoop and Valgui. See http://www.valgrind.org/downloads/guis.html
+ for a list.
+
+BUGS FIXED:
+
+109861 amd64 hangs at startup
+110301 ditto
+111554 valgrind crashes with Cannot allocate memory
+111809 Memcheck tool doesn't start java
+111901 cross-platform run of cachegrind fails on opteron
+113468 (vgPlain_mprotect_range): Assertion 'r != -1' failed.
+ 92071 Reading debugging info uses too much memory
+109744 memcheck loses track of mmap from direct ld-linux.so.2
+110183 tail of page with _end
+ 82301 FV memory layout too rigid
+ 98278 Infinite recursion possible when allocating memory
+108994 Valgrind runs out of memory due to 133x overhead
+115643 valgrind cannot allocate memory
+105974 vg_hashtable.c static hash table
+109323 ppc32: dispatch.S uses Altivec insn, which doesn't work on POWER.
+109345 ptrace_setregs not yet implemented for ppc
+110831 Would like to be able to run against both 32 and 64 bit
+ binaries on AMD64
+110829 == 110831
+111781 compile of valgrind-3.0.0 fails on my linux (gcc 2.X prob)
+112670 Cachegrind: cg_main.c:486 (handleOneStatement ...
+112941 vex x86: 0xD9 0xF4 (fxtract)
+110201 == 112941
+113015 vex amd64->IR: 0xE3 0x14 0x48 0x83 (jrcxz)
+113126 Crash with binaries built with -gstabs+/-ggdb
+104065 == 113126
+115741 == 113126
+113403 Partial SSE3 support on x86
+113541 vex: Grp5(x86) (alt encoding inc/dec) case 1
+113642 valgrind crashes when trying to read debug information
+113810 vex x86->IR: 66 0F F6 (66 + PSADBW == SSE PSADBW)
+113796 read() and write() do not work if buffer is in shared memory
+113851 vex x86->IR: (pmaddwd): 0x66 0xF 0xF5 0xC7
+114366 vex amd64 cannnot handle __asm__( "fninit" )
+114412 vex amd64->IR: 0xF 0xAD 0xC2 0xD3 (128-bit shift, shrdq?)
+114455 vex amd64->IR: 0xF 0xAC 0xD0 0x1 (also shrdq)
+115590: amd64->IR: 0x67 0xE3 0x9 0xEB (address size override)
+115953 valgrind svn r5042 does not build with parallel make (-j3)
+116057 maximum instruction size - VG_MAX_INSTR_SZB too small?
+116483 shmat failes with invalid argument
+102202 valgrind crashes when realloc'ing until out of memory
+109487 == 102202
+110536 == 102202
+112687 == 102202
+111724 vex amd64->IR: 0x41 0xF 0xAB (more BT{,S,R,C} fun n games)
+111748 vex amd64->IR: 0xDD 0xE2 (fucom)
+111785 make fails if CC contains spaces
+111829 vex x86->IR: sbb AL, Ib
+111851 vex x86->IR: 0x9F 0x89 (lahf/sahf)
+112031 iopl on AMD64 and README_MISSING_SYSCALL_OR_IOCTL update
+112152 code generation for Xin_MFence on x86 with SSE0 subarch
+112167 == 112152
+112789 == 112152
+112199 naked ar tool is used in vex makefile
+112501 vex x86->IR: movq (0xF 0x7F 0xC1 0xF) (mmx MOVQ)
+113583 == 112501
+112538 memalign crash
+113190 Broken links in docs/html/
+113230 Valgrind sys_pipe on x86-64 wrongly thinks file descriptors
+ should be 64bit
+113996 vex amd64->IR: fucomp (0xDD 0xE9)
+114196 vex x86->IR: out %eax,(%dx) (0xEF 0xC9 0xC3 0x90)
+114289 Memcheck fails to intercept malloc when used in an uclibc
environment
+114756 mbind syscall support
+114757 Valgrind dies with assertion: Assertion 'noLargerThan > 0' failed
+114563 stack tracking module not informed when valgrind switches threads
+114564 clone() and stacks
+114565 == 114564
+115496 glibc crashes trying to use sysinfo page
+116200 enable fsetxattr, fgetxattr, and fremovexattr for amd64
+
+(3.1.0RC1: 20 November 2005, vex r1466, valgrind r5224).
+(3.1.0: 26 November 2005, vex r1471, valgrind r5235).
+
+
+Release 3.0.1 (29 August 2005)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.0.1 fixes a bunch of bugs reported in 3.0.0. There is no new
+functionality. Some of the fixed bugs are critical, so if you
+use/distribute 3.0.0, an upgrade to 3.0.1 is recommended. The fixed
+bugs are:
+
+(note: "n-i-bz" means "not in bugzilla" -- this bug does not have
+ a bugzilla entry).
+
+109313 (== 110505) x86 cmpxchg8b
+n-i-bz x86: track but ignore changes to %eflags.AC (alignment check)
+110102 dis_op2_E_G(amd64)
+110202 x86 sys_waitpid(#286)
+110203 clock_getres(,0)
+110208 execve fail wrong retval
+110274 SSE1 now mandatory for x86
+110388 amd64 0xDD 0xD1
+110464 amd64 0xDC 0x1D FCOMP
+110478 amd64 0xF 0xD PREFETCH
+n-i-bz XML <unique> printing wrong
+n-i-bz Dirk r4359 (amd64 syscalls from trunk)
+110591 amd64 and x86: rdtsc not implemented properly
+n-i-bz Nick r4384 (stub implementations of Addrcheck and Helgrind)
+110652 AMD64 valgrind crashes on cwtd instruction
+110653 AMD64 valgrind crashes on sarb $0x4,foo(%rip) instruction
+110656 PATH=/usr/bin::/bin valgrind foobar stats ./fooba
+110657 Small test fixes
+110671 vex x86->IR: unhandled instruction bytes: 0xF3 0xC3 (rep ret)
+n-i-bz Nick (Cachegrind should not assert when it encounters a client
+ request.)
+110685 amd64->IR: unhandled instruction bytes: 0xE1 0x56 (loope Jb)
+110830 configuring with --host fails to build 32 bit on 64 bit target
+110875 Assertion when execve fails
+n-i-bz Updates to Memcheck manual
+n-i-bz Fixed broken malloc_usable_size()
+110898 opteron instructions missing: btq btsq btrq bsfq
+110954 x86->IR: unhandled instruction bytes: 0xE2 0xF6 (loop Jb)
+n-i-bz Make suppressions work for "???" lines in stacktraces.
+111006 bogus warnings from linuxthreads
+111092 x86: dis_Grp2(Reg): unhandled case(x86)
+111231 sctp_getladdrs() and sctp_getpaddrs() returns uninitialized
+ memory
+111102 (comment #4) Fixed 64-bit unclean "silly arg" message
+n-i-bz vex x86->IR: unhandled instruction bytes: 0x14 0x0
+n-i-bz minor umount/fcntl wrapper fixes
+111090 Internal Error running Massif
+101204 noisy warning
+111513 Illegal opcode for SSE instruction (x86 movups)
+111555 VEX/Makefile: CC is set to gcc
+n-i-bz Fix XML bugs in FAQ
+
+(3.0.1: 29 August 05,
+ vex/branches/VEX_3_0_BRANCH r1367,
+ valgrind/branches/VALGRIND_3_0_BRANCH r4574).
+
+
+
+Release 3.0.0 (3 August 2005)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+3.0.0 is a major overhaul of Valgrind. The most significant user
+visible change is that Valgrind now supports architectures other than
+x86. The new architectures it supports are AMD64 and PPC32, and the
+infrastructure is present for other architectures to be added later.
+
+AMD64 support works well, but has some shortcomings:
+
+- It generally won't be as solid as the x86 version. For example,
+ support for more obscure instructions and system calls may be missing.
+ We will fix these as they arise.
+
+- Address space may be limited; see the point about
+ position-independent executables below.
+
+- If Valgrind is built on an AMD64 machine, it will only run 64-bit
+ executables. If you want to run 32-bit x86 executables under Valgrind
+ on an AMD64, you will need to build Valgrind on an x86 machine and
+ copy it to the AMD64 machine. And it probably won't work if you do
+ something tricky like exec'ing a 32-bit program from a 64-bit program
+ while using --trace-children=yes. We hope to improve this situation
+ in the future.
+
+The PPC32 support is very basic. It may not work reliably even for
+small programs, but it's a start. Many thanks to Paul Mackerras for
+his great work that enabled this support. We are working to make
+PPC32 usable as soon as possible.
+
+Other user-visible changes:
+
+- Valgrind is no longer built by default as a position-independent
+ executable (PIE), as this caused too many problems.
+
+ Without PIE enabled, AMD64 programs will only be able to access 2GB of
+ address space. We will fix this eventually, but not for the moment.
+
+ Use --enable-pie at configure-time to turn this on.
+
+- Support for programs that use stack-switching has been improved. Use
+ the --max-stackframe flag for simple cases, and the
+ VALGRIND_STACK_REGISTER, VALGRIND_STACK_DEREGISTER and
+ VALGRIND_STACK_CHANGE client requests for trickier cases.
+
+- Support for programs that use self-modifying code has been improved,
+ in particular programs that put temporary code fragments on the stack.
+ This helps for C programs compiled with GCC that use nested functions,
+ and also Ada programs. This is controlled with the --smc-check
+ flag, although the default setting should work in most cases.
+
+- Output can now be printed in XML format. This should make it easier
+ for tools such as GUI front-ends and automated error-processing
+ schemes to use Valgrind output as input. The --xml flag controls this.
+ As part of this change, ELF directory information is read from
executables,
+ so absolute source file paths are available if needed.
+
+- Programs that allocate many heap blocks may run faster, due to
+ improvements in certain data structures.
+
+- Addrcheck is currently not working. We hope to get it working again
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/README.android_emulator Thu Nov 22 04:55:39 2012
@@ -0,0 +1,73 @@
+
+How to install and run an android emulator.
+
+mkdir android # or any other place you prefer
+cd android
+
+# download java JDK
+# http://www.oracle.com/technetwork/java/javase/downloads/index.html
+# download android SDK
+# http://developer.android.com/sdk/index.html
+# download android NDK
+# http://developer.android.com/sdk/ndk/index.html
+
+# versions I used:
+# jdk-7u4-linux-i586.tar.gz
+# android-ndk-r8-linux-x86.tar.bz2
+# android-sdk_r18-linux.tgz
+
+# install jdk
+tar xzf jdk-7u4-linux-i586.tar.gz
+
+# install sdk
+tar xzf android-sdk_r18-linux.tgz
+
+# install ndk
+tar xjf android-ndk-r8-linux-x86.tar.bz2
+
+
+# setup PATH to use the installed software:
+export SDKROOT=$HOME/android/android-sdk-linux
+export PATH=$PATH:$SDKROOT/tools:$SDKROOT/platform-tools
+export NDKROOT=$HOME/android/android-ndk-r8
+
+# install android platforms you want by starting:
+android
+# (from $SDKROOT/tools)
+
+# select the platforms you need
+# I selected and installed:
+# Android 4.0.3 (API 15)
+# Upgraded then to the newer version available:
+# Android sdk 20
+# Android platform tools 12
+
+# then define a virtual device:
+Tools -> Manage AVDs...
+# I define an AVD Name with 64 Mb SD Card, (4.0.3, api 15)
+# rest is default
+
+
+# compile and make install Valgrind, following README.android
+
+
+# Start your android emulator (it takes some time).
+# You can use adb shell to get a shell on the device
+# and see it is working. Note that I usually get
+# one or two time out from adb shell before it works
+adb shell
+
+# Once the emulator is ready, push your Valgrind to the emulator:
+adb push Inst /
+
+
+# if you need to debug:
+# You have on the android side a gdbserver
+# on the device side:
+gdbserver :1234 your_exe
+
+# on the host side:
+adb forward tcp:1234 tcp:1234
+$HOME/android/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb
your_exe
+target remote :1234
+
=======================================
--- /dev/null
+++ /trunk/valgrind/README.mips Thu Nov 22 04:55:39 2012
@@ -0,0 +1,51 @@
+
+Supported platforms
+-------------------
+- MIPS32 and MIPS32r2 platforms are currently supported.
+- Both little-endian and big-endian cores are supported.
+
+
+Building V for MIPS
+-------------------
+- Native build is available for all supported platforms. The build system
+expects that native GCC is configured correctly and optimized for the
platform.
+Yet, this may not be the case with some Debian distributions which
configure
+GCC to compile to "mips1" by default. Depending on a target platform, using
+CFLAGS="-mips32r2" or CFLAGS="-mips32" will do the trick and compile
Valgrind
+correctly.
+- Use of cross-toolchain is supported as well.
+- Example of configure line and additional configure options:
+
+ $ ./configure --host=mipsel-linux-gnu
--prefix=<path_to_install_directory>
+ [--with-pagesize=<4|16|64>]
+
+ * --host=mips-linux-gnu is necessary only if Valgrind is built on platform
+ other then MIPS, tools for building MIPS application have to be in PATH.
+
+ * --with-pagesize option is used to set default PAGE SIZE. If option is
not
+ used, PAGE SIZE is set to value default for platform on which Valgrind
is
+ built on. Possible values are 4, 16 of 64 and represent size in
kilobytes.
+
+ * --host=mips-linux-gnu is necessary if you compile it with cross
toolchain
+ compiler for big endian platform.
+
+ * --host=mipsel-linux-gnu is necessary if you compile it with cross
toolchain
+ compiler for little endian platform.
+
+ * --build=mips-linux is needed if you want to build it for MIPS32 on
64-bit
+ MIPS system.
+
+ * If you are compiling Valgrind with gcc version older then gcc (GCC)
4.5.1
+ you must specify CFLAGS="-mips32r2 -mplt", e.g.
+ ./configure --prefix=<path_to_install_directory>
+ CFLAGS="-mips32r2 -mplt"
+
+
+Limitations
+-----------
+- Currently, memcheck, massif, lackey, callgrind and none are supported.
+- Support for helgrind, drd and exp-ptrcheck is still incomplete.
+- Some Valgrind tests for MIPS expect mips32r2 architecture and will not
+compile when target is one of the older instruction sets.
+- Older GCC may have issues with some inline assembly blocks. Get a
toolchain
+based on newer GCC versions, if possible.
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/guest_mips_defs.h Thu Nov 22 04:55:39 2012
@@ -0,0 +1,117 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin guest_mips_defs.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Only to be used within the guest-mips directory. */
+
+#ifndef __VEX_GUEST_MIPS_DEFS_H
+#define __VEX_GUEST_MIPS_DEFS_H
+
+#include "libvex_basictypes.h"
+#include "guest_generic_bb_to_IR.h" // DisResult
+
+/*---------------------------------------------------------*/
+/*--- mips to IR conversion ---*/
+/*---------------------------------------------------------*/
+
+/* Convert one MIPS insn to IR. See the type DisOneInstrFn in
+ bb_to_IR.h. */
+extern DisResult disInstr_MIPS ( IRSB* irbb,
+ Bool (*resteerOkFn) (void *,
Addr64),
+ Bool resteerCisOk,
+ void* callback_opaque,
+ UChar* guest_code,
+ Long delta,
+ Addr64 guest_IP,
+ VexArch guest_arch,
+ VexArchInfo* archinfo,
+ VexAbiInfo* abiinfo,
+ Bool host_bigendian );
+
+/* Used by the optimiser to specialise calls to helpers. */
+extern IRExpr *guest_mips32_spechelper(const HChar * function_name, IRExpr
** args,
+ IRStmt ** precedingStmts,
+ Int n_precedingStmts);
+
+/* Describes to the optimser which part of the guest state require
+ precise memory exceptions. This is logically part of the guest
+ state description. */
+extern Bool guest_mips32_state_requires_precise_mem_exns(Int, Int);
+
+extern VexGuestLayout mips32Guest_layout;
+
+/*---------------------------------------------------------*/
+/*--- mips guest helpers ---*/
+/*---------------------------------------------------------*/
+
+extern UInt mips32_dirtyhelper_mfc0(UInt rd, UInt sel);
+
+extern void mips32_dirtyhelper_sync(UInt sync);
+
+/*---------------------------------------------------------*/
+/*--- Condition code stuff ---*/
+/*---------------------------------------------------------*/
+
+/* Defines conditions which we can ask for (MIPS MIPS 2e page A3-6) */
+
+typedef enum {
+ MIPSCondEQ = 0, /* equal : Z=1 */
+ MIPSCondNE = 1, /* not equal : Z=0 */
+
+ MIPSCondHS = 2, /* >=u (higher or same) : C=1 */
+ MIPSCondLO = 3, /* <u (lower) : C=0 */
+
+ MIPSCondMI = 4, /* minus (negative) : N=1 */
+ MIPSCondPL = 5, /* plus (zero or +ve) : N=0 */
+
+ MIPSCondVS = 6, /* overflow : V=1 */
+ MIPSCondVC = 7, /* no overflow : V=0 */
+
+ MIPSCondHI = 8, /* >u (higher) : C=1 && Z=0 */
+ MIPSCondLS = 9, /* <=u (lower or same) : C=0 || Z=1 */
+
+ MIPSCondGE = 10, /* >=s (signed greater or equal) : N=V */
+ MIPSCondLT = 11, /* <s (signed less than) : N!=V */
+
+ MIPSCondGT = 12, /* >s (signed greater) : Z=0 && N=V */
+ MIPSCondLE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
+
+ MIPSCondAL = 14, /* always (unconditional) : 1 */
+ MIPSCondNV = 15 /* never (unconditional): : 0 */
+ /* NB: MIPS have deprecated the use of the NV condition code.
+ You are now supposed to use MOV R0,R0 as a noop rather than
+ MOVNV R0,R0 as was previously recommended. Future processors
+ may have the NV condition code reused to do other things. */
+} MIPSCondcode;
+
+#endif /* __VEX_GUEST_MIPS_DEFS_H */
+
+/*---------------------------------------------------------------*/
+/*--- end guest_mips_defs.h ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/guest_mips_helpers.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,578 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin guest_mips_helpers.c ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_basictypes.h"
+#include "libvex_emnote.h"
+#include "libvex_guest_mips32.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+
+#include "main_util.h"
+#include "main_globals.h"
+#include "guest_generic_bb_to_IR.h"
+#include "guest_mips_defs.h"
+
+/* This file contains helper functions for mips guest code. Calls to
+ these functions are generated by the back end.
+*/
+
+#define ALWAYSDEFD32(field) \
+ { offsetof(VexGuestMIPS32State, field), \
+ (sizeof ((VexGuestMIPS32State*)0)->field) }
+
+IRExpr *guest_mips32_spechelper(const HChar * function_name, IRExpr **
args,
+ IRStmt ** precedingStmts, Int
n_precedingStmts)
+{
+ return NULL;
+}
+
+/* VISIBLE TO LIBVEX CLIENT */
+void LibVEX_GuestMIPS32_initialise( /*OUT*/ VexGuestMIPS32State *
vex_state)
+{
+ vex_state->guest_r0 = 0; /* Hardwired to 0 */
+ vex_state->guest_r1 = 0; /* Assembler temporary */
+ vex_state->guest_r2 = 0; /* Values for function returns ... */
+ vex_state->guest_r3 = 0; /* ...and expression evaluation */
+ vex_state->guest_r4 = 0; /* Function arguments */
+ vex_state->guest_r5 = 0;
+ vex_state->guest_r6 = 0;
+ vex_state->guest_r7 = 0;
+ vex_state->guest_r8 = 0; /* Temporaries */
+ vex_state->guest_r9 = 0;
+ vex_state->guest_r10 = 0;
+ vex_state->guest_r11 = 0;
+ vex_state->guest_r12 = 0;
+ vex_state->guest_r13 = 0;
+ vex_state->guest_r14 = 0;
+ vex_state->guest_r15 = 0;
+ vex_state->guest_r16 = 0; /* Saved temporaries */
+ vex_state->guest_r17 = 0;
+ vex_state->guest_r18 = 0;
+ vex_state->guest_r19 = 0;
+ vex_state->guest_r20 = 0;
+ vex_state->guest_r21 = 0;
+ vex_state->guest_r22 = 0;
+ vex_state->guest_r23 = 0;
+ vex_state->guest_r24 = 0; /* Temporaries */
+ vex_state->guest_r25 = 0;
+ vex_state->guest_r26 = 0; /* Reserved for OS kernel */
+ vex_state->guest_r27 = 0;
+ vex_state->guest_r28 = 0; /* Global pointer */
+ vex_state->guest_r29 = 0; /* Stack pointer */
+ vex_state->guest_r30 = 0; /* Frame pointer */
+ vex_state->guest_r31 = 0; /* Return address */
+ vex_state->guest_PC = 0; /* Program counter */
+ vex_state->guest_HI = 0; /* Multiply and divide register higher
result */
+ vex_state->guest_LO = 0; /* Multiply and divide register lower result
*/
+
+ /* FPU Registers */
+ vex_state->guest_f0 = 0x7ff80000; /* Floting point general purpose
registers */
+ vex_state->guest_f1 = 0x7ff80000;
+ vex_state->guest_f2 = 0x7ff80000;
+ vex_state->guest_f3 = 0x7ff80000;
+ vex_state->guest_f4 = 0x7ff80000;
+ vex_state->guest_f5 = 0x7ff80000;
+ vex_state->guest_f6 = 0x7ff80000;
+ vex_state->guest_f7 = 0x7ff80000;
+ vex_state->guest_f8 = 0x7ff80000;
+ vex_state->guest_f9 = 0x7ff80000;
+ vex_state->guest_f10 = 0x7ff80000;
+ vex_state->guest_f11 = 0x7ff80000;
+ vex_state->guest_f12 = 0x7ff80000;
+ vex_state->guest_f13 = 0x7ff80000;
+ vex_state->guest_f14 = 0x7ff80000;
+ vex_state->guest_f15 = 0x7ff80000;
+ vex_state->guest_f16 = 0x7ff80000;
+ vex_state->guest_f17 = 0x7ff80000;
+ vex_state->guest_f18 = 0x7ff80000;
+ vex_state->guest_f19 = 0x7ff80000;
+ vex_state->guest_f20 = 0x7ff80000;
+ vex_state->guest_f21 = 0x7ff80000;
+ vex_state->guest_f22 = 0x7ff80000;
+ vex_state->guest_f23 = 0x7ff80000;
+ vex_state->guest_f24 = 0x7ff80000;
+ vex_state->guest_f25 = 0x7ff80000;
+ vex_state->guest_f26 = 0x7ff80000;
+ vex_state->guest_f27 = 0x7ff80000;
+ vex_state->guest_f28 = 0x7ff80000;
+ vex_state->guest_f29 = 0x7ff80000;
+ vex_state->guest_f30 = 0x7ff80000;
+ vex_state->guest_f31 = 0x7ff80000;
+
+ vex_state->guest_FIR = 0; /* FP implementation and revision register */
+ vex_state->guest_FCCR = 0; /* FP condition codes register */
+ vex_state->guest_FEXR = 0; /* FP exceptions register */
+ vex_state->guest_FENR = 0; /* FP enables register */
+ vex_state->guest_FCSR = 0; /* FP control/status register */
+ vex_state->guest_ULR = 0; /* TLS */
+
+ /* Various pseudo-regs mandated by Vex or Valgrind. */
+ /* Emulation notes */
+ vex_state->guest_EMNOTE = 0;
+
+ /* For clflush: record start and length of area to invalidate */
+ vex_state->guest_TISTART = 0;
+ vex_state->guest_TILEN = 0;
+ vex_state->host_EvC_COUNTER = 0;
+ vex_state->host_EvC_FAILADDR = 0;
+
+ /* Used to record the unredirected guest address at the start of
+ a translation whose start has been redirected. By reading
+ this pseudo-register shortly afterwards, the translation can
+ find out what the corresponding no-redirection address was.
+ Note, this is only set for wrap-style redirects, not for
+ replace-style ones. */
+ vex_state->guest_NRADDR = 0;
+
+ vex_state->guest_COND = 0;
+}
+
+/*-----------------------------------------------------------*/
+/*--- Describing the mips guest state, for the benefit ---*/
+/*--- of iropt and instrumenters. ---*/
+/*-----------------------------------------------------------*/
+
+/* Figure out if any part of the guest state contained in minoff
+ .. maxoff requires precise memory exceptions. If in doubt return
+ True (but this generates significantly slower code).
+
+ We enforce precise exns for guest SP, PC.
+
+ Only SP is needed in mode VexRegUpdSpAtMemAccess.
+*/
+Bool guest_mips32_state_requires_precise_mem_exns(Int minoff, Int maxoff)
+{
+ Int sp_min = offsetof(VexGuestMIPS32State, guest_r29);
+ Int sp_max = sp_min + 4 - 1;
+ Int pc_min = offsetof(VexGuestMIPS32State, guest_PC);
+ Int pc_max = pc_min + 4 - 1;
+
+ if (maxoff < sp_min || minoff > sp_max) {
+ /* no overlap with sp */
+ if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+ return False; // We only need to check stack pointer.
+ } else {
+ return True;
+ }
+
+ if (maxoff < pc_min || minoff > pc_max) {
+ /* no overlap with pc */
+ } else {
+ return True;
+ }
+
+ /* We appear to need precise updates of R11 in order to get proper
+ stacktraces from non-optimised code. */
+ Int fp_min = offsetof(VexGuestMIPS32State, guest_r30);
+ Int fp_max = fp_min + 4 - 1;
+
+ if (maxoff < fp_min || minoff > fp_max) {
+ /* no overlap with fp */
+ } else {
+ return True;
+ }
+
+ return False;
+}
+
+VexGuestLayout mips32Guest_layout = {
+ /* Total size of the guest state, in bytes. */
+ .total_sizeB = sizeof(VexGuestMIPS32State),
+ /* Describe the stack pointer. */
+ .offset_SP = offsetof(VexGuestMIPS32State, guest_r29),
+ .sizeof_SP = 4,
+ /* Describe the frame pointer. */
+ .offset_FP = offsetof(VexGuestMIPS32State, guest_r30),
+ .sizeof_FP = 4,
+ /* Describe the instruction pointer. */
+ .offset_IP = offsetof(VexGuestMIPS32State, guest_PC),
+ .sizeof_IP = 4,
+ /* Describe any sections to be regarded by Memcheck as
+ 'always-defined'. */
+ .n_alwaysDefd = 8,
+ /* ? :( */
+ .alwaysDefd = {
+ /* 0 */ ALWAYSDEFD32(guest_r0),
+ /* 1 */ ALWAYSDEFD32(guest_r1),
+ /* 2 */ ALWAYSDEFD32(guest_EMNOTE),
+ /* 3 */ ALWAYSDEFD32(guest_TISTART),
+ /* 4 */ ALWAYSDEFD32(guest_TILEN),
+ /* 5 */ ALWAYSDEFD32(guest_r29),
+ /* 6 */ ALWAYSDEFD32(guest_r31),
+ /* 7 */ ALWAYSDEFD32(guest_ULR)
+ }
+};
+
+#define ASM_VOLATILE_CASE(rd, sel) \
+ case rd: asm volatile ("mfc0 %0, $" #rd ", "#sel"\n\t" :"=r" (x)
); break;
+
+UInt mips32_dirtyhelper_mfc0(UInt rd, UInt sel)
+{
+ UInt x = 0;
+#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
+ switch (sel) {
+ case 0:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 0);
+ ASM_VOLATILE_CASE(1, 0);
+ ASM_VOLATILE_CASE(2, 0);
+ ASM_VOLATILE_CASE(3, 0);
+ ASM_VOLATILE_CASE(4, 0);
+ ASM_VOLATILE_CASE(5, 0);
+ ASM_VOLATILE_CASE(6, 0);
+ ASM_VOLATILE_CASE(7, 0);
+ ASM_VOLATILE_CASE(8, 0);
+ ASM_VOLATILE_CASE(9, 0);
+ ASM_VOLATILE_CASE(10, 0);
+ ASM_VOLATILE_CASE(11, 0);
+ ASM_VOLATILE_CASE(12, 0);
+ ASM_VOLATILE_CASE(13, 0);
+ ASM_VOLATILE_CASE(14, 0);
+ ASM_VOLATILE_CASE(15, 0);
+ ASM_VOLATILE_CASE(16, 0);
+ ASM_VOLATILE_CASE(17, 0);
+ ASM_VOLATILE_CASE(18, 0);
+ ASM_VOLATILE_CASE(19, 0);
+ ASM_VOLATILE_CASE(20, 0);
+ ASM_VOLATILE_CASE(21, 0);
+ ASM_VOLATILE_CASE(22, 0);
+ ASM_VOLATILE_CASE(23, 0);
+ ASM_VOLATILE_CASE(24, 0);
+ ASM_VOLATILE_CASE(25, 0);
+ ASM_VOLATILE_CASE(26, 0);
+ ASM_VOLATILE_CASE(27, 0);
+ ASM_VOLATILE_CASE(28, 0);
+ ASM_VOLATILE_CASE(29, 0);
+ ASM_VOLATILE_CASE(30, 0);
+ ASM_VOLATILE_CASE(31, 0);
+ default:
+ break;
+ }
+ break;
+ case 1:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 1);
+ ASM_VOLATILE_CASE(1, 1);
+ ASM_VOLATILE_CASE(2, 1);
+ ASM_VOLATILE_CASE(3, 1);
+ ASM_VOLATILE_CASE(4, 1);
+ ASM_VOLATILE_CASE(5, 1);
+ ASM_VOLATILE_CASE(6, 1);
+ ASM_VOLATILE_CASE(7, 1);
+ ASM_VOLATILE_CASE(8, 1);
+ ASM_VOLATILE_CASE(9, 1);
+ ASM_VOLATILE_CASE(10, 1);
+ ASM_VOLATILE_CASE(11, 1);
+ ASM_VOLATILE_CASE(12, 1);
+ ASM_VOLATILE_CASE(13, 1);
+ ASM_VOLATILE_CASE(14, 1);
+ ASM_VOLATILE_CASE(15, 1);
+ ASM_VOLATILE_CASE(16, 1);
+ ASM_VOLATILE_CASE(17, 1);
+ ASM_VOLATILE_CASE(18, 1);
+ ASM_VOLATILE_CASE(19, 1);
+ ASM_VOLATILE_CASE(20, 1);
+ ASM_VOLATILE_CASE(21, 1);
+ ASM_VOLATILE_CASE(22, 1);
+ ASM_VOLATILE_CASE(23, 1);
+ ASM_VOLATILE_CASE(24, 1);
+ ASM_VOLATILE_CASE(25, 1);
+ ASM_VOLATILE_CASE(26, 1);
+ ASM_VOLATILE_CASE(27, 1);
+ ASM_VOLATILE_CASE(28, 1);
+ ASM_VOLATILE_CASE(29, 1);
+ ASM_VOLATILE_CASE(30, 1);
+ ASM_VOLATILE_CASE(31, 1);
+ default:
+ break;
+ }
+ break;
+ case 2:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 2);
+ ASM_VOLATILE_CASE(1, 2);
+ ASM_VOLATILE_CASE(2, 2);
+ ASM_VOLATILE_CASE(3, 1);
+ ASM_VOLATILE_CASE(4, 2);
+ ASM_VOLATILE_CASE(5, 2);
+ ASM_VOLATILE_CASE(6, 2);
+ ASM_VOLATILE_CASE(7, 2);
+ ASM_VOLATILE_CASE(8, 2);
+ ASM_VOLATILE_CASE(9, 2);
+ ASM_VOLATILE_CASE(10, 2);
+ ASM_VOLATILE_CASE(11, 2);
+ ASM_VOLATILE_CASE(12, 2);
+ ASM_VOLATILE_CASE(13, 2);
+ ASM_VOLATILE_CASE(14, 2);
+ ASM_VOLATILE_CASE(15, 2);
+ ASM_VOLATILE_CASE(16, 2);
+ ASM_VOLATILE_CASE(17, 2);
+ ASM_VOLATILE_CASE(18, 2);
+ ASM_VOLATILE_CASE(19, 2);
+ ASM_VOLATILE_CASE(20, 2);
+ ASM_VOLATILE_CASE(21, 2);
+ ASM_VOLATILE_CASE(22, 2);
+ ASM_VOLATILE_CASE(23, 2);
+ ASM_VOLATILE_CASE(24, 2);
+ ASM_VOLATILE_CASE(25, 2);
+ ASM_VOLATILE_CASE(26, 2);
+ ASM_VOLATILE_CASE(27, 2);
+ ASM_VOLATILE_CASE(28, 2);
+ ASM_VOLATILE_CASE(29, 2);
+ ASM_VOLATILE_CASE(30, 2);
+ ASM_VOLATILE_CASE(31, 2);
+ default:
+ break;
+ }
+ break;
+ case 3:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 3);
+ ASM_VOLATILE_CASE(1, 3);
+ ASM_VOLATILE_CASE(2, 3);
+ ASM_VOLATILE_CASE(3, 3);
+ ASM_VOLATILE_CASE(4, 3);
+ ASM_VOLATILE_CASE(5, 3);
+ ASM_VOLATILE_CASE(6, 3);
+ ASM_VOLATILE_CASE(7, 3);
+ ASM_VOLATILE_CASE(8, 3);
+ ASM_VOLATILE_CASE(9, 3);
+ ASM_VOLATILE_CASE(10, 3);
+ ASM_VOLATILE_CASE(11, 3);
+ ASM_VOLATILE_CASE(12, 3);
+ ASM_VOLATILE_CASE(13, 3);
+ ASM_VOLATILE_CASE(14, 3);
+ ASM_VOLATILE_CASE(15, 3);
+ ASM_VOLATILE_CASE(16, 3);
+ ASM_VOLATILE_CASE(17, 3);
+ ASM_VOLATILE_CASE(18, 3);
+ ASM_VOLATILE_CASE(19, 3);
+ ASM_VOLATILE_CASE(20, 3);
+ ASM_VOLATILE_CASE(21, 3);
+ ASM_VOLATILE_CASE(22, 3);
+ ASM_VOLATILE_CASE(23, 3);
+ ASM_VOLATILE_CASE(24, 3);
+ ASM_VOLATILE_CASE(25, 3);
+ ASM_VOLATILE_CASE(26, 3);
+ ASM_VOLATILE_CASE(27, 3);
+ ASM_VOLATILE_CASE(28, 3);
+ ASM_VOLATILE_CASE(29, 3);
+ ASM_VOLATILE_CASE(30, 3);
+ ASM_VOLATILE_CASE(31, 3);
+ default:
+ break;
+ }
+ break;
+ case 4:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 4);
+ ASM_VOLATILE_CASE(1, 4);
+ ASM_VOLATILE_CASE(2, 4);
+ ASM_VOLATILE_CASE(3, 4);
+ ASM_VOLATILE_CASE(4, 4);
+ ASM_VOLATILE_CASE(5, 4);
+ ASM_VOLATILE_CASE(6, 4);
+ ASM_VOLATILE_CASE(7, 4);
+ ASM_VOLATILE_CASE(8, 4);
+ ASM_VOLATILE_CASE(9, 4);
+ ASM_VOLATILE_CASE(10, 4);
+ ASM_VOLATILE_CASE(11, 4);
+ ASM_VOLATILE_CASE(12, 4);
+ ASM_VOLATILE_CASE(13, 4);
+ ASM_VOLATILE_CASE(14, 4);
+ ASM_VOLATILE_CASE(15, 4);
+ ASM_VOLATILE_CASE(16, 4);
+ ASM_VOLATILE_CASE(17, 4);
+ ASM_VOLATILE_CASE(18, 4);
+ ASM_VOLATILE_CASE(19, 4);
+ ASM_VOLATILE_CASE(20, 4);
+ ASM_VOLATILE_CASE(21, 4);
+ ASM_VOLATILE_CASE(22, 4);
+ ASM_VOLATILE_CASE(23, 4);
+ ASM_VOLATILE_CASE(24, 4);
+ ASM_VOLATILE_CASE(25, 4);
+ ASM_VOLATILE_CASE(26, 4);
+ ASM_VOLATILE_CASE(27, 4);
+ ASM_VOLATILE_CASE(28, 4);
+ ASM_VOLATILE_CASE(29, 4);
+ ASM_VOLATILE_CASE(30, 4);
+ ASM_VOLATILE_CASE(31, 4);
+ default:
+ break;
+ }
+ break;
+ case 5:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 5);
+ ASM_VOLATILE_CASE(1, 5);
+ ASM_VOLATILE_CASE(2, 5);
+ ASM_VOLATILE_CASE(3, 5);
+ ASM_VOLATILE_CASE(4, 5);
+ ASM_VOLATILE_CASE(5, 5);
+ ASM_VOLATILE_CASE(6, 5);
+ ASM_VOLATILE_CASE(7, 5);
+ ASM_VOLATILE_CASE(8, 5);
+ ASM_VOLATILE_CASE(9, 5);
+ ASM_VOLATILE_CASE(10, 5);
+ ASM_VOLATILE_CASE(11, 5);
+ ASM_VOLATILE_CASE(12, 5);
+ ASM_VOLATILE_CASE(13, 5);
+ ASM_VOLATILE_CASE(14, 5);
+ ASM_VOLATILE_CASE(15, 5);
+ ASM_VOLATILE_CASE(16, 5);
+ ASM_VOLATILE_CASE(17, 5);
+ ASM_VOLATILE_CASE(18, 5);
+ ASM_VOLATILE_CASE(19, 5);
+ ASM_VOLATILE_CASE(20, 5);
+ ASM_VOLATILE_CASE(21, 5);
+ ASM_VOLATILE_CASE(22, 5);
+ ASM_VOLATILE_CASE(23, 5);
+ ASM_VOLATILE_CASE(24, 5);
+ ASM_VOLATILE_CASE(25, 5);
+ ASM_VOLATILE_CASE(26, 5);
+ ASM_VOLATILE_CASE(27, 5);
+ ASM_VOLATILE_CASE(28, 5);
+ ASM_VOLATILE_CASE(29, 5);
+ ASM_VOLATILE_CASE(30, 5);
+ ASM_VOLATILE_CASE(31, 5);
+ default:
+ break;
+ }
+ break;
+ case 6:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 6);
+ ASM_VOLATILE_CASE(1, 6);
+ ASM_VOLATILE_CASE(2, 6);
+ ASM_VOLATILE_CASE(3, 6);
+ ASM_VOLATILE_CASE(4, 6);
+ ASM_VOLATILE_CASE(5, 6);
+ ASM_VOLATILE_CASE(6, 6);
+ ASM_VOLATILE_CASE(7, 6);
+ ASM_VOLATILE_CASE(8, 6);
+ ASM_VOLATILE_CASE(9, 6);
+ ASM_VOLATILE_CASE(10, 6);
+ ASM_VOLATILE_CASE(11, 6);
+ ASM_VOLATILE_CASE(12, 6);
+ ASM_VOLATILE_CASE(13, 6);
+ ASM_VOLATILE_CASE(14, 6);
+ ASM_VOLATILE_CASE(15, 6);
+ ASM_VOLATILE_CASE(16, 6);
+ ASM_VOLATILE_CASE(17, 6);
+ ASM_VOLATILE_CASE(18, 6);
+ ASM_VOLATILE_CASE(19, 6);
+ ASM_VOLATILE_CASE(20, 6);
+ ASM_VOLATILE_CASE(21, 6);
+ ASM_VOLATILE_CASE(22, 6);
+ ASM_VOLATILE_CASE(23, 6);
+ ASM_VOLATILE_CASE(24, 6);
+ ASM_VOLATILE_CASE(25, 6);
+ ASM_VOLATILE_CASE(26, 6);
+ ASM_VOLATILE_CASE(27, 6);
+ ASM_VOLATILE_CASE(28, 6);
+ ASM_VOLATILE_CASE(29, 6);
+ ASM_VOLATILE_CASE(30, 6);
+ ASM_VOLATILE_CASE(31, 6);
+ default:
+ break;
+ }
+ break;
+ case 7:
+ //__asm__("mfc0 %0, $1, 0" :"=r" (x));
+ switch (rd) {
+ ASM_VOLATILE_CASE(0, 7);
+ ASM_VOLATILE_CASE(1, 7);
+ ASM_VOLATILE_CASE(2, 7);
+ ASM_VOLATILE_CASE(3, 7);
+ ASM_VOLATILE_CASE(4, 7);
+ ASM_VOLATILE_CASE(5, 7);
+ ASM_VOLATILE_CASE(6, 7);
+ ASM_VOLATILE_CASE(7, 7);
+ ASM_VOLATILE_CASE(8, 7);
+ ASM_VOLATILE_CASE(9, 7);
+ ASM_VOLATILE_CASE(10, 7);
+ ASM_VOLATILE_CASE(11, 7);
+ ASM_VOLATILE_CASE(12, 7);
+ ASM_VOLATILE_CASE(13, 7);
+ ASM_VOLATILE_CASE(14, 7);
+ ASM_VOLATILE_CASE(15, 7);
+ ASM_VOLATILE_CASE(16, 7);
+ ASM_VOLATILE_CASE(17, 7);
+ ASM_VOLATILE_CASE(18, 7);
+ ASM_VOLATILE_CASE(19, 7);
+ ASM_VOLATILE_CASE(20, 7);
+ ASM_VOLATILE_CASE(21, 7);
+ ASM_VOLATILE_CASE(22, 7);
+ ASM_VOLATILE_CASE(23, 7);
+ ASM_VOLATILE_CASE(24, 7);
+ ASM_VOLATILE_CASE(25, 7);
+ ASM_VOLATILE_CASE(26, 7);
+ ASM_VOLATILE_CASE(27, 7);
+ ASM_VOLATILE_CASE(28, 7);
+ ASM_VOLATILE_CASE(29, 7);
+ ASM_VOLATILE_CASE(30, 7);
+ ASM_VOLATILE_CASE(31, 7);
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+#endif
+ return x;
+}
+
+#undef ASM_VOLATILE_CASE
+
+#define ASM_VOLATILE_CASE(rd, sel) \
+ case rd: asm volatile ("dmfc0 %0, $" #rd ", "#sel"\n\t" :"=r" (x) );
break;
+
+#define ASM_VOLATILE_SYNC(stype) \
+ asm volatile ("sync \n\t");
+
+void mips32_dirtyhelper_sync(UInt stype)
+{
+#if defined(__mips__) && ((defined(__mips_isa_rev) && __mips_isa_rev >= 2))
+ ASM_VOLATILE_SYNC(0);
+#endif
+}
+
+/*---------------------------------------------------------------*/
+/*--- end guest_mips_helpers.c ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/guest_mips_toIR.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,3678 @@
+
+/*--------------------------------------------------------------------*/
+/*--- begin guest_mips_toIR.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Translates MIPS code to IR. */
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+#include "libvex_guest_mips32.h"
+
+#include "main_util.h"
+#include "main_globals.h"
+#include "guest_generic_bb_to_IR.h"
+#include "guest_mips_defs.h"
+
+/*------------------------------------------------------------*/
+/*--- Globals ---*/
+/*------------------------------------------------------------*/
+
+/* These are set at the start of the translation of a instruction, so
+ that we don't have to pass them around endlessly. CONST means does
+ not change during translation of the instruction.
+*/
+
+/* CONST: is the host bigendian? This has to do with float vs double
+ register accesses on VFP, but it's complex and not properly thought
+ out. */
+static Bool host_is_bigendian;
+
+/* Pointer to the guest code area. */
+static UChar *guest_code;
+
+/* The guest address corresponding to guest_code[0]. */
+static Addr32 guest_PC_bbstart;
+
+/* CONST: The guest address for the instruction currently being
+ translated. */
+static Addr32 guest_PC_curr_instr;
+
+/* MOD: The IRSB* into which we're generating code. */
+static IRSB *irsb;
+
+/* Is our guest binary 32 or 64bit? Set at each call to
+ disInstr_MIPS below. */
+static Bool mode64 = False;
+
+/*------------------------------------------------------------*/
+/*--- Debugging output ---*/
+/*------------------------------------------------------------*/
+
+#define DIP(format, args...) \
+ if (vex_traceflags & VEX_TRACE_FE) \
+ vex_printf(format, ## args)
+
+/*------------------------------------------------------------*/
+/*--- Helper bits and pieces for deconstructing the ---*/
+/*--- mips insn stream. ---*/
+/*------------------------------------------------------------*/
+
+/* ---------------- Integer registers ---------------- */
+
+static UInt integerGuestRegOffset(UInt iregNo)
+{
+ /* Do we care about endianness here? We do if sub-parts of integer
+ registers are accessed, but I don't think that ever happens on
+ MIPS. */
+ UInt ret;
+ switch (iregNo) {
+ case 0:
+ ret = offsetof(VexGuestMIPS32State, guest_r0); break;
+ case 1:
+ ret = offsetof(VexGuestMIPS32State, guest_r1); break;
+ case 2:
+ ret = offsetof(VexGuestMIPS32State, guest_r2); break;
+ case 3:
+ ret = offsetof(VexGuestMIPS32State, guest_r3); break;
+ case 4:
+ ret = offsetof(VexGuestMIPS32State, guest_r4); break;
+ case 5:
+ ret = offsetof(VexGuestMIPS32State, guest_r5); break;
+ case 6:
+ ret = offsetof(VexGuestMIPS32State, guest_r6); break;
+ case 7:
+ ret = offsetof(VexGuestMIPS32State, guest_r7); break;
+ case 8:
+ ret = offsetof(VexGuestMIPS32State, guest_r8); break;
+ case 9:
+ ret = offsetof(VexGuestMIPS32State, guest_r9); break;
+ case 10:
+ ret = offsetof(VexGuestMIPS32State, guest_r10); break;
+ case 11:
+ ret = offsetof(VexGuestMIPS32State, guest_r11); break;
+ case 12:
+ ret = offsetof(VexGuestMIPS32State, guest_r12); break;
+ case 13:
+ ret = offsetof(VexGuestMIPS32State, guest_r13); break;
+ case 14:
+ ret = offsetof(VexGuestMIPS32State, guest_r14); break;
+ case 15:
+ ret = offsetof(VexGuestMIPS32State, guest_r15); break;
+ case 16:
+ ret = offsetof(VexGuestMIPS32State, guest_r16); break;
+ case 17:
+ ret = offsetof(VexGuestMIPS32State, guest_r17); break;
+ case 18:
+ ret = offsetof(VexGuestMIPS32State, guest_r18); break;
+ case 19:
+ ret = offsetof(VexGuestMIPS32State, guest_r19); break;
+ case 20:
+ ret = offsetof(VexGuestMIPS32State, guest_r20); break;
+ case 21:
+ ret = offsetof(VexGuestMIPS32State, guest_r21); break;
+ case 22:
+ ret = offsetof(VexGuestMIPS32State, guest_r22); break;
+ case 23:
+ ret = offsetof(VexGuestMIPS32State, guest_r23); break;
+ case 24:
+ ret = offsetof(VexGuestMIPS32State, guest_r24); break;
+ case 25:
+ ret = offsetof(VexGuestMIPS32State, guest_r25); break;
+ case 26:
+ ret = offsetof(VexGuestMIPS32State, guest_r26); break;
+ case 27:
+ ret = offsetof(VexGuestMIPS32State, guest_r27); break;
+ case 28:
+ ret = offsetof(VexGuestMIPS32State, guest_r28); break;
+ case 29:
+ ret = offsetof(VexGuestMIPS32State, guest_r29); break;
+ case 30:
+ ret = offsetof(VexGuestMIPS32State, guest_r30); break;
+ case 31:
+ ret = offsetof(VexGuestMIPS32State, guest_r31); break;
+ default:
+ vassert(0);
+ break;
+ }
+ return ret;
+}
+
+#define OFFB_PC offsetof(VexGuestMIPS32State, guest_PC)
+
+/* ---------------- Floating point registers ---------------- */
+
+static UInt floatGuestRegOffset(UInt fregNo)
+{
+ vassert(fregNo < 32);
+ UInt ret;
+ switch (fregNo) {
+ case 0:
+ ret = offsetof(VexGuestMIPS32State, guest_f0); break;
+ case 1:
+ ret = offsetof(VexGuestMIPS32State, guest_f1); break;
+ case 2:
+ ret = offsetof(VexGuestMIPS32State, guest_f2); break;
+ case 3:
+ ret = offsetof(VexGuestMIPS32State, guest_f3); break;
+ case 4:
+ ret = offsetof(VexGuestMIPS32State, guest_f4); break;
+ case 5:
+ ret = offsetof(VexGuestMIPS32State, guest_f5); break;
+ case 6:
+ ret = offsetof(VexGuestMIPS32State, guest_f6); break;
+ case 7:
+ ret = offsetof(VexGuestMIPS32State, guest_f7); break;
+ case 8:
+ ret = offsetof(VexGuestMIPS32State, guest_f8); break;
+ case 9:
+ ret = offsetof(VexGuestMIPS32State, guest_f9); break;
+ case 10:
+ ret = offsetof(VexGuestMIPS32State, guest_f10); break;
+ case 11:
+ ret = offsetof(VexGuestMIPS32State, guest_f11); break;
+ case 12:
+ ret = offsetof(VexGuestMIPS32State, guest_f12); break;
+ case 13:
+ ret = offsetof(VexGuestMIPS32State, guest_f13); break;
+ case 14:
+ ret = offsetof(VexGuestMIPS32State, guest_f14); break;
+ case 15:
+ ret = offsetof(VexGuestMIPS32State, guest_f15); break;
+ case 16:
+ ret = offsetof(VexGuestMIPS32State, guest_f16); break;
+ case 17:
+ ret = offsetof(VexGuestMIPS32State, guest_f17); break;
+ case 18:
+ ret = offsetof(VexGuestMIPS32State, guest_f18); break;
+ case 19:
+ ret = offsetof(VexGuestMIPS32State, guest_f19); break;
+ case 20:
+ ret = offsetof(VexGuestMIPS32State, guest_f20); break;
+ case 21:
+ ret = offsetof(VexGuestMIPS32State, guest_f21); break;
+ case 22:
+ ret = offsetof(VexGuestMIPS32State, guest_f22); break;
+ case 23:
+ ret = offsetof(VexGuestMIPS32State, guest_f23); break;
+ case 24:
+ ret = offsetof(VexGuestMIPS32State, guest_f24); break;
+ case 25:
+ ret = offsetof(VexGuestMIPS32State, guest_f25); break;
+ case 26:
+ ret = offsetof(VexGuestMIPS32State, guest_f26); break;
+ case 27:
+ ret = offsetof(VexGuestMIPS32State, guest_f27); break;
+ case 28:
+ ret = offsetof(VexGuestMIPS32State, guest_f28); break;
+ case 29:
+ ret = offsetof(VexGuestMIPS32State, guest_f29); break;
+ case 30:
+ ret = offsetof(VexGuestMIPS32State, guest_f30); break;
+ case 31:
+ ret = offsetof(VexGuestMIPS32State, guest_f31); break;
+ default:
+ vassert(0);
+ break;
+ }
+ return ret;
+}
+
+/* Do a endian load of a 32-bit word, regardless of the
+ endianness of the underlying host. */
+static inline UInt getUInt(UChar * p)
+{
+ UInt w = 0;
+#if defined (_MIPSEL)
+ w = (w << 8) | p[3];
+ w = (w << 8) | p[2];
+ w = (w << 8) | p[1];
+ w = (w << 8) | p[0];
+#elif defined (_MIPSEB)
+ w = (w << 8) | p[0];
+ w = (w << 8) | p[1];
+ w = (w << 8) | p[2];
+ w = (w << 8) | p[3];
+#endif
+ return w;
+}
+
+#define BITS2(_b1,_b0) \
+ (((_b1) << 1) | (_b0))
+
+#define BITS3(_b2,_b1,_b0) \
+ (((_b2) << 2) | ((_b1) << 1) | (_b0))
+
+#define BITS4(_b3,_b2,_b1,_b0) \
+ (((_b3) << 3) | ((_b2) << 2) | ((_b1) << 1) | (_b0))
+
+#define BITS5(_b4,_b3,_b2,_b1,_b0) \
+ (((_b4) << 4) | BITS4((_b3),(_b2),(_b1),(_b0)))
+
+#define BITS6(_b5,_b4,_b3,_b2,_b1,_b0) \
+ ((BITS2((_b5),(_b4)) << 4) \
+ | BITS4((_b3),(_b2),(_b1),(_b0)))
+
+#define BITS8(_b7,_b6,_b5,_b4,_b3,_b2,_b1,_b0) \
+ ((BITS4((_b7),(_b6),(_b5),(_b4)) << 4) \
+ | BITS4((_b3),(_b2),(_b1),(_b0)))
+
+#define LOAD_STORE_PATTERN \
+ t1 = newTemp(Ity_I32); \
+ assign(t1, binop(Iop_Add32, getIReg(rs),
mkU32(extend_s_16to32(imm)))); \
+
+#define LWX_SWX_PATTERN \
+ t2 = newTemp(Ity_I32); \
+ assign(t2, binop(Iop_And32, mkexpr(t1), mkU32(0xFFFFFFFC))); \
+ t4 = newTemp(Ity_I32); \
+ assign(t4, binop(Iop_And32, mkexpr(t1), mkU32(0x00000003)))
+
+#define SXXV_PATTERN(op) \
+ putIReg(rd, binop(op, \
+ getIReg(rt), \
+ unop(Iop_32to8, \
+ binop(Iop_And32, \
+ getIReg(rs), \
+ mkU32(0x0000001F) \
+ ) \
+ ) \
+ ) \
+ )
+
+#define SXX_PATTERN(op) \
+ putIReg(rd, binop(op, getIReg(rt), mkU8(sa)));
+
+#define ALU_PATTERN(op) \
+ putIReg(rd, binop(op, getIReg(rs), getIReg(rt)));
+
+#define ALUI_PATTERN(op) \
+ putIReg(rt, binop(op, getIReg(rs), mkU32(imm)));
+
+#define ALUI_PATTERN64(op) \
+ putIReg(rt, binop(op, getIReg(rs), mkU64(imm)));
+
+#define FP_CONDITIONAL_CODE \
+ t3 = newTemp(Ity_I32); \
+ assign(t3, binop(Iop_And32, IRExpr_Mux0X( unop(Iop_1Uto8, \
+ binop(Iop_CmpEQ32, mkU32(cc), mkU32(0))), \
+ binop(Iop_Shr32, getFCSR(), mkU8(24+cc)), \
+ binop(Iop_Shr32, getFCSR(), mkU8(23))), mkU32(0x1)));
+
+/*------------------------------------------------------------*/
+/*--- Field helpers ---*/
+/*------------------------------------------------------------*/
+
+static UInt get_opcode(UInt mipsins)
+{
+ return (0xFC000000 & mipsins) >> 26;
+}
+
+static UInt get_rs(UInt mipsins)
+{
+ return (0x03E00000 & mipsins) >> 21;
+}
+
+static UInt get_rt(UInt mipsins)
+{
+ return (0x001F0000 & mipsins) >> 16;
+}
+
+static UInt get_imm(UInt mipsins)
+{
+ return (0x0000FFFF & mipsins);
+}
+
+static UInt get_instr_index(UInt mipsins)
+{
+ return (0x03FFFFFF & mipsins);
+}
+
+static UInt get_rd(UInt mipsins)
+{
+ return (0x0000F800 & mipsins) >> 11;
+}
+
+static UInt get_sa(UInt mipsins)
+{
+ return (0x000007C0 & mipsins) >> 6;
+}
+
+static UInt get_function(UInt mipsins)
+{
+ return (0x0000003F & mipsins);
+}
+
+static UInt get_ft(UInt mipsins)
+{
+ return (0x001F0000 & mipsins) >> 16;
+}
+
+static UInt get_fs(UInt mipsins)
+{
+ return (0x0000F800 & mipsins) >> 11;
+}
+
+static UInt get_fd(UInt mipsins)
+{
+ return (0x000007C0 & mipsins) >> 6;
+}
+
+static UInt get_mov_cc(UInt mipsins)
+{
+ return (0x001C0000 & mipsins) >> 18;
+}
+
+static UInt get_bc1_cc(UInt mipsins)
+{
+ return (0x001C0000 & mipsins) >> 18;
+}
+
+static UInt get_fpc_cc(UInt mipsins)
+{
+ return (0x00000700 & mipsins) >> 8;
+}
+
+static UInt get_tf(UInt mipsins)
+{
+ return (0x00010000 & mipsins) >> 16;
+}
+
+static UInt get_nd(UInt mipsins)
+{
+ return (0x00020000 & mipsins) >> 17;
+}
+
+static UInt get_fmt(UInt mipsins)
+{
+ return (0x03E00000 & mipsins) >> 21;
+}
+
+static UInt get_FC(UInt mipsins)
+{
+ return (0x000000F0 & mipsins) >> 4;
+}
+
+static UInt get_cond(UInt mipsins)
+{
+ return (0x0000000F & mipsins);
+}
+
+/* for break & syscall */
+static UInt get_code(UInt mipsins)
+{
+ return (0xFFC0 & mipsins) >> 6;
+}
+
+static UInt get_lsb(UInt mipsins)
+{
+ return (0x7C0 & mipsins) >> 6;
+}
+
+static UInt get_msb(UInt mipsins)
+{
+ return (0x0000F800 & mipsins) >> 11;
+}
+
+static UInt get_rot(UInt mipsins)
+{
+ return (0x00200000 & mipsins) >> 21;
+}
+
+static UInt get_rotv(UInt mipsins)
+{
+ return (0x00000040 & mipsins) >> 6;
+}
+
+static UInt get_sel(UInt mipsins)
+{
+ return (0x00000007 & mipsins);
+}
+
+static Bool branch_or_jump(UChar * addr)
+{
+ UInt fmt;
+ UInt cins = getUInt(addr);
+
+ UInt opcode = get_opcode(cins);
+ UInt rt = get_rt(cins);
+ UInt function = get_function(cins);
+
+ /* bgtz, blez, bne, beq, jal */
+ if (opcode == 0x07 || opcode == 0x06 || opcode == 0x05 || opcode == 0x04
+ || opcode == 0x03 || opcode == 0x02) {
+ return True;
+ }
+
+ /* bgez */
+ if (opcode == 0x01 && rt == 0x01) {
+ return True;
+ }
+
+ /* bgezal */
+ if (opcode == 0x01 && rt == 0x11) {
+ return True;
+ }
+
+ /* bltzal */
+ if (opcode == 0x01 && rt == 0x10) {
+ return True;
+ }
+
+ /* bltz */
+ if (opcode == 0x01 && rt == 0x00) {
+ return True;
+ }
+
+ /* jalr */
+ if (opcode == 0x00 && function == 0x09) {
+ return True;
+ }
+
+ /* jr */
+ if (opcode == 0x00 && function == 0x08) {
+ return True;
+ }
+
+ if (opcode == 0x11) {
+ /*bc1f & bc1t */
+ fmt = get_fmt(cins);
+ if (fmt == 0x08) {
+ return True;
+ }
+ }
+
+ return False;
+}
+
+static Bool is_Branch_or_Jump_and_Link(UChar * addr)
+{
+ UInt cins = getUInt(addr);
+
+ UInt opcode = get_opcode(cins);
+ UInt rt = get_rt(cins);
+ UInt function = get_function(cins);
+
+ /* jal */
+ if (opcode == 0x02) {
+ return True;
+ }
+
+ /* bgezal */
+ if (opcode == 0x01 && rt == 0x11) {
+ return True;
+ }
+
+ /* bltzal */
+ if (opcode == 0x01 && rt == 0x10) {
+ return True;
+ }
+
+ /* jalr */
+ if (opcode == 0x00 && function == 0x09) {
+ return True;
+ }
+
+ return False;
+}
+
+static Bool branch_or_link_likely(UChar * addr)
+{
+ UInt cins = getUInt(addr);
+ UInt opcode = get_opcode(cins);
+ UInt rt = get_rt(cins);
+
+ /* bgtzl, blezl, bnel, beql */
+ if (opcode == 0x17 || opcode == 0x16 || opcode == 0x15 || opcode ==
0x14)
+ return True;
+
+ /* bgezl */
+ if (opcode == 0x01 && rt == 0x03)
+ return True;
+
+ /* bgezall */
+ if (opcode == 0x01 && rt == 0x13)
+ return True;
+
+ /* bltzall */
+ if (opcode == 0x01 && rt == 0x12)
+ return True;
+
+ /* bltzl */
+ if (opcode == 0x01 && rt == 0x02)
+ return True;
+
+ return False;
+}
+
+/*------------------------------------------------------------*/
+/*--- Helper bits and pieces for creating IR fragments. ---*/
+/*------------------------------------------------------------*/
+
+static IRExpr *mkU8(UInt i)
+{
+ vassert(i < 256);
+ return IRExpr_Const(IRConst_U8((UChar) i));
+}
+
+/* Create an expression node for a 32-bit integer constant */
+static IRExpr *mkU32(UInt i)
+{
+ return IRExpr_Const(IRConst_U32(i));
+}
+
+/* Create an expression node for a 64-bit integer constant */
+static IRExpr *mkU64(ULong i)
+{
+ return IRExpr_Const(IRConst_U64(i));
+}
+
+static IRExpr *mkexpr(IRTemp tmp)
+{
+ return IRExpr_RdTmp(tmp);
+}
+
+static IRExpr *unop(IROp op, IRExpr * a)
+{
+ return IRExpr_Unop(op, a);
+}
+
+static IRExpr *binop(IROp op, IRExpr * a1, IRExpr * a2)
+{
+ return IRExpr_Binop(op, a1, a2);
+}
+
+static IRExpr *triop(IROp op, IRExpr * a1, IRExpr * a2, IRExpr * a3)
+{
+ return IRExpr_Triop(op, a1, a2, a3);
+}
+
+static IRExpr *load(IRType ty, IRExpr * addr)
+{
+ IRExpr *load1 = NULL;
+#if defined (_MIPSEL)
+ load1 = IRExpr_Load(Iend_LE, ty, addr);
+#elif defined (_MIPSEB)
+ load1 = IRExpr_Load(Iend_BE, ty, addr);
+#endif
+ return load1;
+}
+
+/* Add a statement to the list held by "irsb". */
+static void stmt(IRStmt * st)
+{
+ addStmtToIRSB(irsb, st);
+}
+
+static void assign(IRTemp dst, IRExpr * e)
+{
+ stmt(IRStmt_WrTmp(dst, e));
+}
+
+static void store(IRExpr * addr, IRExpr * data)
+{
+#if defined (_MIPSEL)
+ stmt(IRStmt_Store(Iend_LE, addr, data));
+#elif defined (_MIPSEB)
+ stmt(IRStmt_Store(Iend_BE, addr, data));
+#endif
+}
+
+/* Generate a new temporary of the given type. */
+static IRTemp newTemp(IRType ty)
+{
+ vassert(isPlausibleIRType(ty));
+ return newIRTemp(irsb->tyenv, ty);
+}
+
+/* Generate an expression for SRC rotated right by ROT. */
+static IRExpr *genROR32(IRExpr * src, Int rot)
+{
+ vassert(rot >= 0 && rot < 32);
+ if (rot == 0)
+ return src;
+ return binop(Iop_Or32, binop(Iop_Shl32, src, mkU8(32 - rot)),
+ binop(Iop_Shr32, src, mkU8(rot)));
+}
+
+static IRExpr *genRORV32(IRExpr * src, IRExpr * rs)
+{
+ IRTemp t0 = newTemp(Ity_I8);
+ IRTemp t1 = newTemp(Ity_I8);
+
+ assign(t0, unop(Iop_32to8, binop(Iop_And32, rs, mkU32(0x0000001F))));
+ assign(t1, binop(Iop_Sub8, mkU8(32), mkexpr(t0)));
+ return binop(Iop_Or32, binop(Iop_Shl32, src, mkexpr(t1)),
+ binop(Iop_Shr32, src, mkexpr(t0)));
+}
+
+static UInt extend_s_16to32(UInt x)
+{
+ return (UInt) ((((Int) x) << 16) >> 16);
+}
+
+static UInt extend_s_18to32(UInt x)
+{
+ return (UInt) ((((Int) x) << 14) >> 14);
+}
+
+static void jmp_lit( /*MOD*/DisResult* dres,
+ IRJumpKind kind, Addr32 d32 )
+{
+ vassert(dres->whatNext == Dis_Continue);
+ vassert(dres->len == 0);
+ vassert(dres->continueAt == 0);
+ vassert(dres->jk_StopHere == Ijk_INVALID);
+ dres->whatNext = Dis_StopHere;
+ dres->jk_StopHere = kind;
+ stmt( IRStmt_Put( OFFB_PC, mkU32(d32) ) );
+}
+
+/* Fetch a byte from the guest insn stream. */
+static UChar getIByte(Int delta)
+{
+ return guest_code[delta];
+}
+
+static IRExpr *getIReg(UInt iregNo)
+{
+ if (0 == iregNo) {
+ return mode64 ? mkU64(0x0) : mkU32(0x0);
+ } else {
+ IRType ty = mode64 ? Ity_I64 : Ity_I32;
+ vassert(iregNo < 32);
+ return IRExpr_Get(integerGuestRegOffset(iregNo), ty);
+ }
+}
+
+static IRExpr *getHI(void)
+{
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_HI), Ity_I32);
+}
+
+static IRExpr *getLO(void)
+{
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_LO), Ity_I32);
+}
+
+static IRExpr *getFCSR(void)
+{
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_FCSR), Ity_I32);
+}
+
+static void putFCSR(IRExpr * e)
+{
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_FCSR), e));
+}
+
+static IRExpr *getULR(void)
+{
+ return IRExpr_Get(offsetof(VexGuestMIPS32State, guest_ULR), Ity_I32);
+}
+
+static void putIReg(UInt archreg, IRExpr * e)
+{
+ IRType ty = mode64 ? Ity_I64 : Ity_I32;
+ vassert(archreg < 32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
+ if (archreg != 0)
+ stmt(IRStmt_Put(integerGuestRegOffset(archreg), e));
+}
+
+static void putLO(IRExpr * e)
+{
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_LO), e));
+}
+
+static void putHI(IRExpr * e)
+{
+ stmt(IRStmt_Put(offsetof(VexGuestMIPS32State, guest_HI), e));
+}
+
+static void putPC(IRExpr * e)
+{
+ stmt(IRStmt_Put(OFFB_PC, e));
+}
+
+static IRExpr *mkWidenFrom32(IRType ty, IRExpr * src, Bool sined)
+{
+ vassert(ty == Ity_I32 || ty == Ity_I64);
+ if (ty == Ity_I32)
+ return src;
+ return (sined) ? unop(Iop_32Sto64, src) : unop(Iop_32Uto64, src);
+}
+
+/* Narrow 8/16/32 bit int expr to 8/16/32. Clearly only some
+ of these combinations make sense. */
+static IRExpr *narrowTo(IRType dst_ty, IRExpr * e)
+{
+ IRType src_ty = typeOfIRExpr(irsb->tyenv, e);
+ if (src_ty == dst_ty)
+ return e;
+ if (src_ty == Ity_I32 && dst_ty == Ity_I16)
+ return unop(Iop_32to16, e);
+ if (src_ty == Ity_I32 && dst_ty == Ity_I8)
+ return unop(Iop_32to8, e);
+ if (src_ty == Ity_I64 && dst_ty == Ity_I8) {
+ vassert(mode64);
+ return unop(Iop_64to8, e);
+ }
+ if (src_ty == Ity_I64 && dst_ty == Ity_I16) {
+ vassert(mode64);
+ return unop(Iop_64to16, e);
+ }
+
+ if (vex_traceflags & VEX_TRACE_FE) {
+ vex_printf("\nsrc, dst tys are: ");
+ ppIRType(src_ty);
+ vex_printf(", ");
+ ppIRType(dst_ty);
+ vex_printf("\n");
+ }
+
+ vpanic("narrowTo(mips)");
+ return 0;
+}
+
+static IRExpr *mkNarrowTo32(IRType ty, IRExpr * src)
+{
+ vassert(ty == Ity_I32 || ty == Ity_I64);
+ return ty == Ity_I64 ? unop(Iop_64to32, src) : src;
+}
+
+static IRExpr *getLoFromF64(IRType ty, IRExpr * src)
+{
+ vassert(ty == Ity_F32 || ty == Ity_F64);
+ if (ty == Ity_F64) {
+ IRTemp t0, t1;
+ t0 = newTemp(Ity_I64);
+ t1 = newTemp(Ity_I32);
+ assign(t0, unop(Iop_ReinterpF64asI64, src));
+ assign(t1, unop(Iop_64to32, mkexpr(t0)));
+ return unop(Iop_ReinterpI32asF32, mkexpr(t1));
+ } else
+ return src;
+}
+
+static IRExpr *mkWidenFromF32(IRType ty, IRExpr * src)
+{
+ vassert(ty == Ity_F32 || ty == Ity_F64);
+ return ty == Ity_F64 ? unop(Iop_F32toF64, src) : src;
+}
+
+static IRExpr *dis_branch_likely(IRExpr * guard, UInt imm)
+{
+ ULong branch_offset;
+ IRTemp t0;
+
+ /* PC = PC + (SignExtend(signed_immed_24) << 2)
+ An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
+ is added to the address of the instruction following
+ the branch (not the branch itself), in the branch delay slot, to form
+ a PC-relative effective target address. */
+ branch_offset = extend_s_18to32(imm << 2);
+
+ t0 = newTemp(Ity_I1);
+ assign(t0, guard);
+
+ stmt(IRStmt_Exit(mkexpr(t0), Ijk_Boring,
+ IRConst_U32(guest_PC_curr_instr + 8), OFFB_PC));
+
+ irsb->jumpkind = Ijk_Boring;
+
+ return mkU32(guest_PC_curr_instr + 4 + branch_offset);
+}
+
+static void dis_branch(Bool link, IRExpr * guard, UInt imm, IRStmt ** set)
+{
+ ULong branch_offset;
+ IRTemp t0;
+
+ if (link) { // LR (GPR31) = addr of the 2nd instr after branch instr
+ putIReg(31, mkU32(guest_PC_curr_instr + 8));
+ }
+
+ /* PC = PC + (SignExtend(signed_immed_24) << 2)
+ An 18-bit signed offset (the 16-bit offset field shifted left 2 bits)
+ is added to the address of the instruction following
+ the branch (not the branch itself), in the branch delay slot, to form
+ a PC-relative effective target address. */
+
+ branch_offset = extend_s_18to32(imm << 2);
+
+ t0 = newTemp(Ity_I1);
+ assign(t0, guard);
+ *set = IRStmt_Exit(mkexpr(t0), link ? Ijk_Call : Ijk_Boring,
+ IRConst_U32(guest_PC_curr_instr + 4 + (UInt)
branch_offset),
+ OFFB_PC);
+}
+
+static IRExpr *getFReg(UInt dregNo)
+{
+ vassert(dregNo < 32);
+ IRType ty = mode64 ? Ity_F64 : Ity_F32;
+ return IRExpr_Get(floatGuestRegOffset(dregNo), ty);
+}
+
+static IRExpr *getDReg(UInt dregNo)
+{
+ vassert(dregNo < 32);
+ IRTemp t0 = newTemp(Ity_F32);
+ IRTemp t1 = newTemp(Ity_F32);
+ IRTemp t2 = newTemp(Ity_F64);
+ IRTemp t3 = newTemp(Ity_I32);
+ IRTemp t4 = newTemp(Ity_I32);
+ IRTemp t5 = newTemp(Ity_I64);
+
+#if defined (_MIPSEL)
+ assign(t0, getFReg(dregNo));
+ assign(t1, getFReg(dregNo + 1));
+#elif defined (_MIPSEB)
+ assign(t0, getFReg(dregNo + 1));
+ assign(t1, getFReg(dregNo));
+#endif
+
+ assign(t3, unop(Iop_ReinterpF32asI32, mkexpr(t0)));
+ assign(t4, unop(Iop_ReinterpF32asI32, mkexpr(t1)));
+ assign(t5, binop(Iop_32HLto64, mkexpr(t4), mkexpr(t3)));
+ assign(t2, unop(Iop_ReinterpI64asF64, mkexpr(t5)));
+
+ return mkexpr(t2);
+}
+
+static void putFReg(UInt dregNo, IRExpr * e)
+{
+ vassert(dregNo < 32);
+ IRType ty = mode64 ? Ity_F64 : Ity_F32;
+ vassert(typeOfIRExpr(irsb->tyenv, e) == ty);
+ stmt(IRStmt_Put(floatGuestRegOffset(dregNo), e));
+}
+
+static void putDReg(UInt dregNo, IRExpr * e)
+{
+ vassert(dregNo < 32);
+ vassert(typeOfIRExpr(irsb->tyenv, e) == Ity_F64);
+ IRTemp t1 = newTemp(Ity_F64);
+ IRTemp t4 = newTemp(Ity_I32);
+ IRTemp t5 = newTemp(Ity_I32);
+ IRTemp t6 = newTemp(Ity_I64);
+ assign(t1, e);
+ assign(t6, unop(Iop_ReinterpF64asI64, mkexpr(t1)));
+ assign(t4, unop(Iop_64HIto32, mkexpr(t6))); // hi
+ assign(t5, unop(Iop_64to32, mkexpr(t6))); //lo
+#if defined (_MIPSEL)
+ putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
+ putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
+#elif defined (_MIPSEB)
+ putFReg(dregNo + 1, unop(Iop_ReinterpI32asF32, mkexpr(t5)));
+ putFReg(dregNo, unop(Iop_ReinterpI32asF32, mkexpr(t4)));
+#endif
+}
+
+static void setFPUCondCode(IRExpr * e, UInt cc)
+{
+ if (cc == 0) {
+ DIP("setFpu: %d\n", cc);
+ putFCSR(binop(Iop_And32, getFCSR(), mkU32(0xFF7FFFFF)));
+ putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(23))));
+ } else {
+ DIP("setFpu1: %d\n", cc);
+ putFCSR(binop(Iop_And32, getFCSR(), unop(Iop_Not32,
+ binop(Iop_Shl32, mkU32(0x01000000),
mkU8(cc)))));
+ putFCSR(binop(Iop_Or32, getFCSR(), binop(Iop_Shl32, e, mkU8(24 +
cc))));
+ }
+}
+
+static IRExpr */* :: Ity_I32 */get_IR_roundingmode(void)
+{
+/*
+ rounding mode | MIPS | IR
+ ------------------------
+ to nearest | 00 | 00
+ to zero | 01 | 11
+ to +infinity | 10 | 10
+ to -infinity | 11 | 01
+*/
+ IRTemp rm_MIPS = newTemp(Ity_I32);
+ /* Last two bits in FCSR are rounding mode. */
+
+ assign(rm_MIPS, binop(Iop_And32,
IRExpr_Get(offsetof(VexGuestMIPS32State,
+ guest_FCSR), Ity_I32), mkU32(3)));
+
+ // rm_IR = XOR( rm_MIPS32, (rm_MIPS32 << 1) & 2)
+
+ return binop(Iop_Xor32, mkexpr(rm_MIPS), binop(Iop_And32,
+ binop(Iop_Shl32, mkexpr(rm_MIPS), mkU8(1)), mkU32(2)));
+}
+
+/*********************************************************/
+/*--- Floating Point Compare ---*/
+/*********************************************************/
+static Bool dis_instr_CCondFmt(UInt cins)
+{
+ IRTemp t0, t1, t2, t3;
+ IRTemp ccIR = newTemp(Ity_I32);
+ IRTemp ccMIPS = newTemp(Ity_I32);
+ UInt FC = get_FC(cins);
+ UInt fmt = get_fmt(cins);
+ UInt fs = get_fs(cins);
+ UInt ft = get_ft(cins);
+ UInt cond = get_cond(cins);
+
+ if (FC == 0x3) { // C.cond.fmt
+ UInt fpc_cc = get_fpc_cc(cins);
+ switch (fmt) {
+ case 0x10: { //C.cond.S
+ DIP("C.cond.S %d f%d, f%d\n", fpc_cc, fs, ft);
+ t0 = newTemp(Ity_I32);
+ t1 = newTemp(Ity_I32);
+ t2 = newTemp(Ity_I32);
+ t3 = newTemp(Ity_I32);
+
+ assign(ccIR, binop(Iop_CmpF64, unop(Iop_F32toF64, getFReg(fs)),
+ unop(Iop_F32toF64,
getFReg(ft))));
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/host_mips_defs.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,4004 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin host_mips_defs.c ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_basictypes.h"
+#include "libvex.h"
+#include "libvex_trc_values.h"
+
+#include "main_util.h"
+#include "host_generic_regs.h"
+#include "host_mips_defs.h"
+
+/*---------------- Registers ----------------*/
+
+void ppHRegMIPS(HReg reg, Bool mode64)
+{
+ Int r;
+ static const HChar *ireg32_names[35]
+ = { "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
+ "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
+ "%32", "%33", "%34",
+ };
+
+ static const HChar *freg32_names[32]
+ = { "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "f30", "$f31"
+ };
+
+ static const HChar *freg64_names[32]
+ = { "$d0", "$d1", "$d2", "$d3", "$d4", "$d5", "$d6", "$d7",
+ "$d8", "$d9", "$d10", "$d11", "$d12", "$d13", "$d14", "$d15",
+ };
+
+ /* Be generic for all virtual regs. */
+ if (hregIsVirtual(reg)) {
+ ppHReg(reg);
+ return;
+ }
+
+ /* But specific for real regs. */
+ vassert(hregClass(reg) == HRcInt32 || hregClass(reg) == HRcInt64 ||
+ hregClass(reg) == HRcFlt32 || hregClass(reg) == HRcFlt64);
+
+ /* But specific for real regs. */
+ {
+ switch (hregClass(reg)) {
+ case HRcInt32:
+ r = hregNumber(reg);
+ vassert(r >= 0 && r < 32);
+ vex_printf("%s", ireg32_names[r]);
+ return;
+ case HRcFlt32:
+ r = hregNumber(reg);
+ vassert(r >= 0 && r < 32);
+ vex_printf("%s", freg32_names[r]);
+ return;
+ case HRcFlt64:
+ r = hregNumber(reg);
+ vassert(r >= 0 && r < 32);
+ vex_printf("%s", freg64_names[r]);
+ return;
+ default:
+ vpanic("ppHRegMIPS");
+ break;
+ }
+ }
+
+ return;
+}
+
+#define MkHRegGPR(_n, _mode64) \
+ mkHReg(_n, _mode64 ? HRcInt64 : HRcInt32, False)
+
+HReg hregMIPS_GPR0(Bool mode64)
+{
+ return MkHRegGPR(0, mode64);
+}
+
+HReg hregMIPS_GPR1(Bool mode64)
+{
+ return MkHRegGPR(1, mode64);
+}
+
+HReg hregMIPS_GPR2(Bool mode64)
+{
+ return MkHRegGPR(2, mode64);
+}
+
+HReg hregMIPS_GPR3(Bool mode64)
+{
+ return MkHRegGPR(3, mode64);
+}
+
+HReg hregMIPS_GPR4(Bool mode64)
+{
+ return MkHRegGPR(4, mode64);
+}
+
+HReg hregMIPS_GPR5(Bool mode64)
+{
+ return MkHRegGPR(5, mode64);
+}
+
+HReg hregMIPS_GPR6(Bool mode64)
+{
+ return MkHRegGPR(6, mode64);
+}
+
+HReg hregMIPS_GPR7(Bool mode64)
+{
+ return MkHRegGPR(7, mode64);
+}
+
+HReg hregMIPS_GPR8(Bool mode64)
+{
+ return MkHRegGPR(8, mode64);
+}
+
+HReg hregMIPS_GPR9(Bool mode64)
+{
+ return MkHRegGPR(9, mode64);
+}
+
+HReg hregMIPS_GPR10(Bool mode64)
+{
+ return MkHRegGPR(10, mode64);
+}
+
+HReg hregMIPS_GPR11(Bool mode64)
+{
+ return MkHRegGPR(11, mode64);
+}
+
+HReg hregMIPS_GPR12(Bool mode64)
+{
+ return MkHRegGPR(12, mode64);
+}
+
+HReg hregMIPS_GPR13(Bool mode64)
+{
+ return MkHRegGPR(13, mode64);
+}
+
+HReg hregMIPS_GPR14(Bool mode64)
+{
+ return MkHRegGPR(14, mode64);
+}
+
+HReg hregMIPS_GPR15(Bool mode64)
+{
+ return MkHRegGPR(15, mode64);
+}
+
+HReg hregMIPS_GPR16(Bool mode64)
+{
+ return MkHRegGPR(16, mode64);
+}
+
+HReg hregMIPS_GPR17(Bool mode64)
+{
+ return MkHRegGPR(17, mode64);
+}
+
+HReg hregMIPS_GPR18(Bool mode64)
+{
+ return MkHRegGPR(18, mode64);
+}
+
+HReg hregMIPS_GPR19(Bool mode64)
+{
+ return MkHRegGPR(19, mode64);
+}
+
+HReg hregMIPS_GPR20(Bool mode64)
+{
+ return MkHRegGPR(20, mode64);
+}
+
+HReg hregMIPS_GPR21(Bool mode64)
+{
+ return MkHRegGPR(21, mode64);
+}
+
+HReg hregMIPS_GPR22(Bool mode64)
+{
+ return MkHRegGPR(22, mode64);
+}
+
+HReg hregMIPS_GPR23(Bool mode64)
+{
+ return MkHRegGPR(23, mode64);
+}
+
+HReg hregMIPS_GPR24(Bool mode64)
+{
+ return MkHRegGPR(24, mode64);
+}
+
+HReg hregMIPS_GPR25(Bool mode64)
+{
+ return MkHRegGPR(25, mode64);
+}
+
+HReg hregMIPS_GPR26(Bool mode64)
+{
+ return MkHRegGPR(26, mode64);
+}
+
+HReg hregMIPS_GPR27(Bool mode64)
+{
+ return MkHRegGPR(27, mode64);
+}
+
+HReg hregMIPS_GPR28(Bool mode64)
+{
+ return MkHRegGPR(28, mode64);
+}
+
+HReg hregMIPS_GPR29(Bool mode64)
+{
+ return MkHRegGPR(29, mode64);
+}
+
+HReg hregMIPS_GPR30(Bool mode64)
+{
+ return MkHRegGPR(30, mode64);
+}
+
+HReg hregMIPS_GPR31(Bool mode64)
+{
+ return MkHRegGPR(31, mode64);
+}
+
+#define MkHRegFPR(_n, _mode64) \
+ mkHReg(_n, _mode64 ? HRcFlt64 : HRcFlt32, False)
+
+HReg hregMIPS_F0(Bool mode64)
+{
+ return MkHRegFPR(0, mode64);
+}
+
+HReg hregMIPS_F1(Bool mode64)
+{
+ return MkHRegFPR(1, mode64);
+}
+
+HReg hregMIPS_F2(Bool mode64)
+{
+ return MkHRegFPR(2, mode64);
+}
+
+HReg hregMIPS_F3(Bool mode64)
+{
+ return MkHRegFPR(3, mode64);
+}
+
+HReg hregMIPS_F4(Bool mode64)
+{
+ return MkHRegFPR(4, mode64);
+}
+
+HReg hregMIPS_F5(Bool mode64)
+{
+ return MkHRegFPR(5, mode64);
+}
+
+HReg hregMIPS_F6(Bool mode64)
+{
+ return MkHRegFPR(6, mode64);
+}
+
+HReg hregMIPS_F7(Bool mode64)
+{
+ return MkHRegFPR(7, mode64);
+}
+
+HReg hregMIPS_F8(Bool mode64)
+{
+ return MkHRegFPR(8, mode64);
+}
+
+HReg hregMIPS_F9(Bool mode64)
+{
+ return MkHRegFPR(9, mode64);
+}
+
+HReg hregMIPS_F10(Bool mode64)
+{
+ return MkHRegFPR(10, mode64);
+}
+
+HReg hregMIPS_F11(Bool mode64)
+{
+ return MkHRegFPR(11, mode64);
+}
+
+HReg hregMIPS_F12(Bool mode64)
+{
+ return MkHRegFPR(12, mode64);
+}
+
+HReg hregMIPS_F13(Bool mode64)
+{
+ return MkHRegFPR(13, mode64);
+}
+
+HReg hregMIPS_F14(Bool mode64)
+{
+ return MkHRegFPR(14, mode64);
+}
+
+HReg hregMIPS_F15(Bool mode64)
+{
+ return MkHRegFPR(15, mode64);
+}
+
+HReg hregMIPS_F16(Bool mode64)
+{
+ return MkHRegFPR(16, mode64);
+}
+
+HReg hregMIPS_F17(Bool mode64)
+{
+ return MkHRegFPR(17, mode64);
+}
+
+HReg hregMIPS_F18(Bool mode64)
+{
+ return MkHRegFPR(18, mode64);
+}
+
+HReg hregMIPS_F19(Bool mode64)
+{
+ return MkHRegFPR(19, mode64);
+}
+
+HReg hregMIPS_F20(Bool mode64)
+{
+ return MkHRegFPR(20, mode64);
+}
+
+HReg hregMIPS_F21(Bool mode64)
+{
+ return MkHRegFPR(21, mode64);
+}
+
+HReg hregMIPS_F22(Bool mode64)
+{
+ return MkHRegFPR(22, mode64);
+}
+
+HReg hregMIPS_F23(Bool mode64)
+{
+ return MkHRegFPR(23, mode64);
+}
+
+HReg hregMIPS_F24(Bool mode64)
+{
+ return MkHRegFPR(24, mode64);
+}
+
+HReg hregMIPS_F25(Bool mode64)
+{
+ return MkHRegFPR(25, mode64);
+}
+
+HReg hregMIPS_F26(Bool mode64)
+{
+ return MkHRegFPR(26, mode64);
+}
+
+HReg hregMIPS_F27(Bool mode64)
+{
+ return MkHRegFPR(27, mode64);
+}
+
+HReg hregMIPS_F28(Bool mode64)
+{
+ return MkHRegFPR(28, mode64);
+}
+
+HReg hregMIPS_F29(Bool mode64)
+{
+ return MkHRegFPR(29, mode64);
+}
+
+HReg hregMIPS_F30(Bool mode64)
+{
+ return MkHRegFPR(30, mode64);
+}
+
+HReg hregMIPS_F31(Bool mode64)
+{
+ return MkHRegFPR(31, mode64);
+}
+
+HReg hregMIPS_PC(Bool mode64)
+{
+ return mkHReg(32, mode64 ? HRcFlt64 : HRcFlt32, False);
+}
+
+HReg hregMIPS_HI(Bool mode64)
+{
+ return mkHReg(33, mode64 ? HRcFlt64 : HRcFlt32, False);
+}
+
+HReg hregMIPS_LO(Bool mode64)
+{
+ return mkHReg(34, mode64 ? HRcFlt64 : HRcFlt32, False);
+}
+
+HReg hregMIPS_D0(void)
+{
+ return mkHReg(0, HRcFlt64, False);
+}
+
+HReg hregMIPS_D1(void)
+{
+ return mkHReg(2, HRcFlt64, False);
+}
+
+HReg hregMIPS_D2(void)
+{
+ return mkHReg(4, HRcFlt64, False);
+}
+
+HReg hregMIPS_D3(void)
+{
+ return mkHReg(6, HRcFlt64, False);
+}
+
+HReg hregMIPS_D4(void)
+{
+ return mkHReg(8, HRcFlt64, False);
+}
+
+HReg hregMIPS_D5(void)
+{
+ return mkHReg(10, HRcFlt64, False);
+}
+
+HReg hregMIPS_D6(void)
+{
+ return mkHReg(12, HRcFlt64, False);
+}
+
+HReg hregMIPS_D7(void)
+{
+ return mkHReg(14, HRcFlt64, False);
+}
+
+HReg hregMIPS_D8(void)
+{
+ return mkHReg(16, HRcFlt64, False);
+}
+
+HReg hregMIPS_D9(void)
+{
+ return mkHReg(18, HRcFlt64, False);
+}
+
+HReg hregMIPS_D10(void)
+{
+ return mkHReg(20, HRcFlt64, False);
+}
+
+HReg hregMIPS_D11(void)
+{
+ return mkHReg(22, HRcFlt64, False);
+}
+
+HReg hregMIPS_D12(void)
+{
+ return mkHReg(24, HRcFlt64, False);
+}
+
+HReg hregMIPS_D13(void)
+{
+ return mkHReg(26, HRcFlt64, False);
+}
+
+HReg hregMIPS_D14(void)
+{
+ return mkHReg(28, HRcFlt64, False);
+}
+
+HReg hregMIPS_D15(void)
+{
+ return mkHReg(30, HRcFlt64, False);
+}
+
+HReg hregMIPS_FIR(void)
+{
+ return mkHReg(35, HRcInt32, False);
+}
+
+HReg hregMIPS_FCCR(void)
+{
+ return mkHReg(36, HRcInt32, False);
+}
+
+HReg hregMIPS_FEXR(void)
+{
+ return mkHReg(37, HRcInt32, False);
+}
+
+HReg hregMIPS_FENR(void)
+{
+ return mkHReg(38, HRcInt32, False);
+}
+
+HReg hregMIPS_FCSR(void)
+{
+ return mkHReg(39, HRcInt32, False);
+}
+
+HReg hregMIPS_COND(void)
+{
+ return mkHReg(47, HRcInt32, False);
+}
+
+void getAllocableRegs_MIPS(Int * nregs, HReg ** arr, Bool mode64)
+{
+ /*
+ * The list of allocable registers is shorten to fit MIPS32 mode on
Loongson.
+ * More precisely, we workaround Loongson MIPS32 issues by avoiding
usage of
+ * odd single precision FP registers.
+ */
+ if (mode64)
+ *nregs = 24;
+ else
+ *nregs = 29;
+ UInt i = 0;
+ *arr = LibVEX_Alloc(*nregs * sizeof(HReg));
+
+ //ZERO = constant 0
+ //AT = assembler temporary
+ // callee saves ones are listed first, since we prefer them
+ // if they're available
+ (*arr)[i++] = hregMIPS_GPR16(mode64);
+ (*arr)[i++] = hregMIPS_GPR17(mode64);
+ (*arr)[i++] = hregMIPS_GPR18(mode64);
+ (*arr)[i++] = hregMIPS_GPR19(mode64);
+ (*arr)[i++] = hregMIPS_GPR20(mode64);
+ (*arr)[i++] = hregMIPS_GPR21(mode64);
+ (*arr)[i++] = hregMIPS_GPR22(mode64);
+ if (!mode64)
+ (*arr)[i++] = hregMIPS_GPR23(mode64);
+
+ // otherwise we'll have to slum it out with caller-saves ones
+ if (mode64) {
+ (*arr)[i++] = hregMIPS_GPR8(mode64);
+ (*arr)[i++] = hregMIPS_GPR9(mode64);
+ (*arr)[i++] = hregMIPS_GPR10(mode64);
+ (*arr)[i++] = hregMIPS_GPR11(mode64);
+ }
+ (*arr)[i++] = hregMIPS_GPR12(mode64);
+ (*arr)[i++] = hregMIPS_GPR13(mode64);
+ (*arr)[i++] = hregMIPS_GPR14(mode64);
+ (*arr)[i++] = hregMIPS_GPR15(mode64);
+ (*arr)[i++] = hregMIPS_GPR24(mode64);
+ /***********mips32********************/
+ // t0 (=dispatch_ctr)
+ // t1 spill reg temp
+ // t2 (=guest_state)
+ // t3 (=PC = next guest address)
+ // K0 and K1 are reserved for OS kernel
+ // GP = global pointer
+ // SP = stack pointer
+ // FP = frame pointer
+ // RA = link register
+ // + PC, HI and LO
+ (*arr)[i++] = hregMIPS_F16(mode64);
+ (*arr)[i++] = hregMIPS_F18(mode64);
+ (*arr)[i++] = hregMIPS_F20(mode64);
+ (*arr)[i++] = hregMIPS_F22(mode64);
+ (*arr)[i++] = hregMIPS_F24(mode64);
+ (*arr)[i++] = hregMIPS_F26(mode64);
+ (*arr)[i++] = hregMIPS_F28(mode64);
+ (*arr)[i++] = hregMIPS_F30(mode64);
+ if (!mode64) {
+ /* Fake double floating point */
+ (*arr)[i++] = hregMIPS_D0();
+ (*arr)[i++] = hregMIPS_D1();
+ (*arr)[i++] = hregMIPS_D2();
+ (*arr)[i++] = hregMIPS_D3();
+ (*arr)[i++] = hregMIPS_D4();
+ (*arr)[i++] = hregMIPS_D5();
+ (*arr)[i++] = hregMIPS_D6();
+ (*arr)[i++] = hregMIPS_D7();
+ }
+ vassert(i == *nregs);
+
+}
+
+/*----------------- Condition Codes ----------------------*/
+
+const HChar *showMIPSCondCode(MIPSCondCode cond)
+{
+ const HChar* ret;
+ switch (cond) {
+ case MIPScc_EQ:
+ ret = "EQ"; /* equal */
+ break;
+ case MIPScc_NE:
+ ret = "NEQ"; /* not equal */
+ break;
+ case MIPScc_HS:
+ ret = "GE"; /* >=u (Greater Than or Equal) */
+ break;
+ case MIPScc_LO:
+ ret = "LT"; /* <u (lower) */
+ break;
+ case MIPScc_MI:
+ ret = "mi"; /* minus (negative) */
+ break;
+ case MIPScc_PL:
+ ret = "pl"; /* plus (zero or +ve) */
+ break;
+ case MIPScc_VS:
+ ret = "vs"; /* overflow */
+ break;
+ case MIPScc_VC:
+ ret = "vc"; /* no overflow */
+ break;
+ case MIPScc_HI:
+ ret = "hi"; /* >u (higher) */
+ break;
+ case MIPScc_LS:
+ ret = "ls"; /* <=u (lower or same) */
+ break;
+ case MIPScc_GE:
+ ret = "ge"; /* >=s (signed greater or equal) */
+ break;
+ case MIPScc_LT:
+ ret = "lt"; /* <s (signed less than) */
+ break;
+ case MIPScc_GT:
+ ret = "gt"; /* >s (signed greater) */
+ break;
+ case MIPScc_LE:
+ ret = "le"; /* <=s (signed less or equal) */
+ break;
+ case MIPScc_AL:
+ ret = "al"; /* always (unconditional) */
+ break;
+ case MIPScc_NV:
+ ret = "nv"; /* never (unconditional): */
+ break;
+ default:
+ vpanic("showMIPSCondCode");
+ break;
+ }
+ return ret;
+}
+
+const HChar *showMIPSFpOp(MIPSFpOp op)
+{
+ const HChar *ret;
+ switch (op) {
+ case Mfp_ADDD:
+ ret = "ADD.D";
+ break;
+ case Mfp_SUBD:
+ ret = "SUB.D";
+ break;
+ case Mfp_MULD:
+ ret = "MUL.D";
+ break;
+ case Mfp_DIVD:
+ ret = "DIV.D";
+ break;
+ case Mfp_MADDD:
+ ret = "MADD.D";
+ break;
+ case Mfp_MSUBD:
+ ret = "MSUB.D";
+ break;
+ case Mfp_MADDS:
+ ret = "MADD.S";
+ break;
+ case Mfp_MSUBS:
+ ret = "MSUB.S";
+ break;
+ case Mfp_ADDS:
+ ret = "ADD.S";
+ break;
+ case Mfp_SUBS:
+ ret = "SUB.S";
+ break;
+ case Mfp_MULS:
+ ret = "MUL.S";
+ break;
+ case Mfp_DIVS:
+ ret = "DIV.S";
+ break;
+ case Mfp_SQRTS:
+ ret = "SQRT.S";
+ break;
+ case Mfp_SQRTD:
+ ret = "SQRT.D";
+ break;
+ case Mfp_RSQRTS:
+ ret = "RSQRT.S";
+ break;
+ case Mfp_RSQRTD:
+ ret = "RSQRT.D";
+ break;
+ case Mfp_RECIPS:
+ ret = "RECIP.S";
+ break;
+ case Mfp_RECIPD:
+ ret = "RECIP.D";
+ break;
+ case Mfp_ABSS:
+ ret = "ABS.S";
+ break;
+ case Mfp_ABSD:
+ ret = "ABS.D";
+ break;
+ case Mfp_NEGS:
+ ret = "NEG.S";
+ break;
+ case Mfp_NEGD:
+ ret = "NEG.D";
+ break;
+ case Mfp_MOVS:
+ ret = "MOV.S";
+ break;
+ case Mfp_MOVD:
+ ret = "MOV.D";
+ break;
+ case Mfp_RES:
+ ret = "RES";
+ break;
+ case Mfp_ROUNDWS:
+ ret = "ROUND.W.S";
+ break;
+ case Mfp_ROUNDWD:
+ ret = "ROUND.W.D";
+ break;
+ case Mfp_FLOORWS:
+ ret = "FLOOR.W.S";
+ break;
+ case Mfp_FLOORWD:
+ ret = "FLOOR.W.D";
+ break;
+ case Mfp_RSQRTE:
+ ret = "frsqrte";
+ break;
+ case Mfp_CVTDW:
+ case Mfp_CVTD:
+ ret = "CVT.D";
+ break;
+ case Mfp_CVTSD:
+ case Mfp_CVTSW:
+ ret = "CVT.S";
+ break;
+ case Mfp_CVTWS:
+ case Mfp_CVTWD:
+ ret = "CVT.W";
+ break;
+ case Mfp_TRUWD:
+ case Mfp_TRUWS:
+ ret = "TRUNC.W";
+ break;
+ case Mfp_TRULD:
+ case Mfp_TRULS:
+ ret = "TRUNC.L";
+ break;
+ case Mfp_CEILWS:
+ case Mfp_CEILWD:
+ ret = "CEIL.W";
+ break;
+ case Mfp_CEILLS:
+ case Mfp_CEILLD:
+ ret = "CEIL.L";
+ break;
+ case Mfp_CMP:
+ ret = "C.cond.d";
+ break;
+ default:
+ vpanic("showMIPSFpOp");
+ break;
+ }
+ return ret;
+}
+
+/* --------- MIPSAMode: memory address expressions. --------- */
+
+MIPSAMode *MIPSAMode_IR(Int idx, HReg base)
+{
+ MIPSAMode *am = LibVEX_Alloc(sizeof(MIPSAMode));
+ am->tag = Mam_IR;
+ am->Mam.IR.base = base;
+ am->Mam.IR.index = idx;
+
+ return am;
+}
+
+MIPSAMode *MIPSAMode_RR(HReg idx, HReg base)
+{
+ MIPSAMode *am = LibVEX_Alloc(sizeof(MIPSAMode));
+ am->tag = Mam_RR;
+ am->Mam.RR.base = base;
+ am->Mam.RR.index = idx;
+
+ return am;
+}
+
+MIPSAMode *dopyMIPSAMode(MIPSAMode * am)
+{
+ MIPSAMode* ret;
+ switch (am->tag) {
+ case Mam_IR:
+ ret = MIPSAMode_IR(am->Mam.IR.index, am->Mam.IR.base);
+ break;
+ case Mam_RR:
+ ret = MIPSAMode_RR(am->Mam.RR.index, am->Mam.RR.base);
+ break;
+ default:
+ vpanic("dopyMIPSAMode");
+ break;
+ }
+ return ret;
+}
+
+MIPSAMode *nextMIPSAModeFloat(MIPSAMode * am)
+{
+ MIPSAMode* ret;
+ switch (am->tag) {
+ case Mam_IR:
+ ret = MIPSAMode_IR(am->Mam.IR.index + 4, am->Mam.IR.base);
+ break;
+ case Mam_RR:
+ ret = MIPSAMode_RR(am->Mam.RR.index + 1, am->Mam.RR.base);
+ break;
+ default:
+ vpanic("dopyMIPSAMode");
+ break;
+ }
+ return ret;
+}
+
+MIPSAMode *nextMIPSAModeInt(MIPSAMode * am)
+{
+ MIPSAMode* ret;
+ switch (am->tag) {
+ case Mam_IR:
+ ret = MIPSAMode_IR(am->Mam.IR.index + 4, am->Mam.IR.base);
+ break;
+ case Mam_RR:
+ ret = MIPSAMode_RR(am->Mam.RR.index + 1, am->Mam.RR.base);
+ break;
+ default:
+ vpanic("dopyMIPSAMode");
+ break;
+ }
+ return ret;
+}
+
+void ppMIPSAMode(MIPSAMode * am, Bool mode64)
+{
+ switch (am->tag) {
+ case Mam_IR:
+ if (am->Mam.IR.index == 0)
+ vex_printf("0(");
+ else
+ vex_printf("%d(", (Int) am->Mam.IR.index);
+ ppHRegMIPS(am->Mam.IR.base, mode64);
+ vex_printf(")");
+ return;
+ case Mam_RR:
+ ppHRegMIPS(am->Mam.RR.base, mode64);
+ vex_printf(", ");
+ ppHRegMIPS(am->Mam.RR.index, mode64);
+ return;
+ default:
+ vpanic("ppMIPSAMode");
+ break;
+ }
+}
+
+static void addRegUsage_MIPSAMode(HRegUsage * u, MIPSAMode * am)
+{
+ switch (am->tag) {
+ case Mam_IR:
+ addHRegUse(u, HRmRead, am->Mam.IR.base);
+ return;
+ case Mam_RR:
+ addHRegUse(u, HRmRead, am->Mam.RR.base);
+ addHRegUse(u, HRmRead, am->Mam.RR.index);
+ return;
+ default:
+ vpanic("addRegUsage_MIPSAMode");
+ break;
+ }
+}
+
+static void mapRegs_MIPSAMode(HRegRemap * m, MIPSAMode * am)
+{
+ switch (am->tag) {
+ case Mam_IR:
+ am->Mam.IR.base = lookupHRegRemap(m, am->Mam.IR.base);
+ return;
+ case Mam_RR:
+ am->Mam.RR.base = lookupHRegRemap(m, am->Mam.RR.base);
+ am->Mam.RR.index = lookupHRegRemap(m, am->Mam.RR.index);
+ return;
+ default:
+ vpanic("mapRegs_MIPSAMode");
+ break;
+ }
+}
+
+/* --------- Operand, which can be a reg or a u16/s16. --------- */
+
+MIPSRH *MIPSRH_Imm(Bool syned, UShort imm16)
+{
+ MIPSRH *op = LibVEX_Alloc(sizeof(MIPSRH));
+ op->tag = Mrh_Imm;
+ op->Mrh.Imm.syned = syned;
+ op->Mrh.Imm.imm16 = imm16;
+ /* If this is a signed value, ensure it's not -32768, so that we
+ are guaranteed always to be able to negate if needed. */
+ if (syned)
+ vassert(imm16 != 0x8000);
+ vassert(syned == True || syned == False);
+ return op;
+}
+
+MIPSRH *MIPSRH_Reg(HReg reg)
+{
+ MIPSRH *op = LibVEX_Alloc(sizeof(MIPSRH));
+ op->tag = Mrh_Reg;
+ op->Mrh.Reg.reg = reg;
+ return op;
+}
+
+void ppMIPSRH(MIPSRH * op, Bool mode64)
+{
+ MIPSRHTag tag = op->tag;
+ switch (tag) {
+ case Mrh_Imm:
+ if (op->Mrh.Imm.syned)
+ vex_printf("%d", (Int) (Short) op->Mrh.Imm.imm16);
+ else
+ vex_printf("%u", (UInt) (UShort) op->Mrh.Imm.imm16);
+ return;
+ case Mrh_Reg:
+ ppHRegMIPS(op->Mrh.Reg.reg, mode64);
+ return;
+ default:
+ vpanic("ppMIPSRH");
+ break;
+ }
+}
+
+/* An MIPSRH can only be used in a "read" context (what would it mean
+ to write or modify a literal?) and so we enumerate its registers
+ accordingly. */
+static void addRegUsage_MIPSRH(HRegUsage * u, MIPSRH * op)
+{
+ switch (op->tag) {
+ case Mrh_Imm:
+ return;
+ case Mrh_Reg:
+ addHRegUse(u, HRmRead, op->Mrh.Reg.reg);
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/host_mips_defs.h Thu Nov 22 04:55:39 2012
@@ -0,0 +1,757 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin host_mips_defs.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VEX_HOST_MIPS_DEFS_H
+#define __VEX_HOST_MIPS_DEFS_H
+
+#include "libvex_basictypes.h"
+#include "libvex.h" // VexArch
+#include "host_generic_regs.h" // HReg
+
+/* Num registers used for function calls */
+#define MIPS_N_REGPARMS 4
+
+/* --------- Registers. --------- */
+
+/* The usual HReg abstraction.
+ There are 32 general purpose regs.
+*/
+
+extern void ppHRegMIPS(HReg, Bool);
+
+extern HReg hregMIPS_GPR0(Bool mode64); // scratch reg / zero reg
+extern HReg hregMIPS_GPR1(Bool mode64); // reserved for trap handling
+extern HReg hregMIPS_GPR2(Bool mode64); // reserved for trap handling
+extern HReg hregMIPS_GPR3(Bool mode64);
+extern HReg hregMIPS_GPR4(Bool mode64);
+extern HReg hregMIPS_GPR5(Bool mode64);
+extern HReg hregMIPS_GPR6(Bool mode64);
+extern HReg hregMIPS_GPR7(Bool mode64);
+extern HReg hregMIPS_GPR8(Bool mode64);
+extern HReg hregMIPS_GPR9(Bool mode64);
+extern HReg hregMIPS_GPR10(Bool mode64);
+extern HReg hregMIPS_GPR11(Bool mode64);
+extern HReg hregMIPS_GPR12(Bool mode64);
+extern HReg hregMIPS_GPR13(Bool mode64);
+extern HReg hregMIPS_GPR14(Bool mode64);
+extern HReg hregMIPS_GPR15(Bool mode64);
+extern HReg hregMIPS_GPR16(Bool mode64);
+extern HReg hregMIPS_GPR17(Bool mode64);
+extern HReg hregMIPS_GPR18(Bool mode64);
+extern HReg hregMIPS_GPR19(Bool mode64);
+extern HReg hregMIPS_GPR20(Bool mode64);
+extern HReg hregMIPS_GPR21(Bool mode64);
+extern HReg hregMIPS_GPR22(Bool mode64);
+extern HReg hregMIPS_GPR23(Bool mode64); // GuestStatePtr
+extern HReg hregMIPS_GPR24(Bool mode64); // reserved for dispatcher
+extern HReg hregMIPS_GPR25(Bool mode64);
+extern HReg hregMIPS_GPR26(Bool mode64);
+extern HReg hregMIPS_GPR27(Bool mode64);
+extern HReg hregMIPS_GPR28(Bool mode64);
+extern HReg hregMIPS_GPR29(Bool mode64);
+extern HReg hregMIPS_GPR30(Bool mode64);
+extern HReg hregMIPS_GPR31(Bool mode64);
+extern HReg hregMIPS_PC(Bool mode64);
+
+extern HReg hregMIPS_HI(Bool mode64);
+extern HReg hregMIPS_LO(Bool mode64);
+
+extern HReg hregMIPS_F0(Bool mode64);
+extern HReg hregMIPS_F1(Bool mode64);
+extern HReg hregMIPS_F2(Bool mode64);
+extern HReg hregMIPS_F3(Bool mode64);
+extern HReg hregMIPS_F4(Bool mode64);
+extern HReg hregMIPS_F5(Bool mode64);
+extern HReg hregMIPS_F6(Bool mode64);
+extern HReg hregMIPS_F7(Bool mode64);
+extern HReg hregMIPS_F8(Bool mode64);
+extern HReg hregMIPS_F9(Bool mode64);
+extern HReg hregMIPS_F10(Bool mode64);
+extern HReg hregMIPS_F11(Bool mode64);
+extern HReg hregMIPS_F12(Bool mode64);
+extern HReg hregMIPS_F13(Bool mode64);
+extern HReg hregMIPS_F14(Bool mode64);
+extern HReg hregMIPS_F15(Bool mode64);
+extern HReg hregMIPS_F16(Bool mode64);
+extern HReg hregMIPS_F17(Bool mode64);
+extern HReg hregMIPS_F18(Bool mode64);
+extern HReg hregMIPS_F19(Bool mode64);
+extern HReg hregMIPS_F20(Bool mode64);
+extern HReg hregMIPS_F21(Bool mode64);
+extern HReg hregMIPS_F22(Bool mode64);
+extern HReg hregMIPS_F23(Bool mode64);
+extern HReg hregMIPS_F24(Bool mode64);
+extern HReg hregMIPS_F25(Bool mode64);
+extern HReg hregMIPS_F26(Bool mode64);
+extern HReg hregMIPS_F27(Bool mode64);
+extern HReg hregMIPS_F28(Bool mode64);
+extern HReg hregMIPS_F29(Bool mode64);
+extern HReg hregMIPS_F30(Bool mode64);
+extern HReg hregMIPS_F31(Bool mode64);
+extern HReg hregMIPS_FIR(void);
+extern HReg hregMIPS_FCCR(void);
+extern HReg hregMIPS_FEXR(void);
+extern HReg hregMIPS_FENR(void);
+extern HReg hregMIPS_FCSR(void);
+extern HReg hregMIPS_COND(void);
+
+extern HReg hregMIPS_D0(void);
+extern HReg hregMIPS_D1(void);
+extern HReg hregMIPS_D2(void);
+extern HReg hregMIPS_D3(void);
+extern HReg hregMIPS_D4(void);
+extern HReg hregMIPS_D5(void);
+extern HReg hregMIPS_D6(void);
+extern HReg hregMIPS_D7(void);
+extern HReg hregMIPS_D8(void);
+extern HReg hregMIPS_D9(void);
+extern HReg hregMIPS_D10(void);
+extern HReg hregMIPS_D11(void);
+extern HReg hregMIPS_D12(void);
+extern HReg hregMIPS_D13(void);
+extern HReg hregMIPS_D14(void);
+extern HReg hregMIPS_D15(void);
+
+#define GuestStatePointer(_mode64) hregMIPS_GPR10(_mode64)
+
+#define StackFramePointer(_mode64) hregMIPS_GPR30(_mode64)
+#define LinkRegister(_mode64) hregMIPS_GPR31(_mode64)
+#define StackPointer(_mode64) hregMIPS_GPR29(_mode64)
+#define FCSR() hregMIPS_FCSR()
+#define COND() hregMIPS_COND()
+
+#define HIRegister(_mode64) hregMIPS_HI(_mode64)
+#define LORegister(_mode64) hregMIPS_LO(_mode64)
+
+/* a0, a1, a2, a3 */
+#define MIPS_N_ARGREGS 4
+
+/* --------- Condition codes, Intel encoding. --------- */
+typedef enum {
+ MIPScc_EQ = 0, /* equal */
+ MIPScc_NE = 1, /* not equal */
+
+ MIPScc_HS = 2, /* >=u (higher or same) */
+ MIPScc_LO = 3, /* <u (lower) */
+
+ MIPScc_MI = 4, /* minus (negative) */
+ MIPScc_PL = 5, /* plus (zero or +ve) */
+
+ MIPScc_VS = 6, /* overflow */
+ MIPScc_VC = 7, /* no overflow */
+
+ MIPScc_HI = 8, /* >u (higher) */
+ MIPScc_LS = 9, /* <=u (lower or same) */
+
+ MIPScc_GE = 10, /* >=s (signed greater or equal) */
+ MIPScc_LT = 11, /* <s (signed less than) */
+
+ MIPScc_GT = 12, /* >s (signed greater) */
+ MIPScc_LE = 13, /* <=s (signed less or equal) */
+
+ MIPScc_AL = 14, /* always (unconditional) */
+ MIPScc_NV = 15 /* never (unconditional): */
+} MIPSCondCode;
+
+extern const HChar *showMIPSCondCode(MIPSCondCode);
+
+/* --------- Memory address expressions (amodes). --------- */
+typedef enum {
+ Mam_IR, /* Immediate (signed 16-bit) + Reg */
+ Mam_RR /* Reg1 + Reg2 */
+} MIPSAModeTag;
+
+typedef struct {
+ MIPSAModeTag tag;
+ union {
+ struct {
+ HReg base;
+ Int index;
+ } IR;
+ struct {
+ HReg base;
+ HReg index;
+ } RR;
+ } Mam;
+} MIPSAMode;
+
+extern MIPSAMode *MIPSAMode_IR(Int, HReg);
+extern MIPSAMode *MIPSAMode_RR(HReg, HReg);
+
+extern MIPSAMode *dopyMIPSAMode(MIPSAMode *);
+extern MIPSAMode *nextMIPSAModeFloat(MIPSAMode *);
+extern MIPSAMode *nextMIPSAModeInt(MIPSAMode *);
+
+extern void ppMIPSAMode(MIPSAMode *, Bool);
+
+/* --------- Operand, which can be a reg or a u16/s16. --------- */
+/* ("RH" == "Register or Halfword immediate") */
+typedef enum {
+ Mrh_Imm,
+ Mrh_Reg
+} MIPSRHTag;
+
+typedef struct {
+ MIPSRHTag tag;
+ union {
+ struct {
+ Bool syned;
+ UShort imm16;
+ } Imm;
+ struct {
+ HReg reg;
+ } Reg;
+ } Mrh;
+} MIPSRH;
+
+extern void ppMIPSRH(MIPSRH *, Bool);
+
+extern MIPSRH *MIPSRH_Imm(Bool, UShort);
+extern MIPSRH *MIPSRH_Reg(HReg);
+
+/* --- Addressing Mode suitable for VFP --- */
+typedef struct {
+ HReg reg;
+ Int simm11;
+} MIPSAModeV;
+
+extern MIPSAModeV *mkMIPSAModeV(HReg reg, Int simm11);
+
+extern void ppMIPSAModeV(MIPSAModeV *);
+
+/* --------- Reg or imm-8x4 operands --------- */
+/* a.k.a (a very restricted form of) Shifter Operand,
+ in the MIPS parlance. */
+
+typedef enum {
+ MIPSri84_I84 = 5, /* imm8 `ror` (2 * imm4) */
+ MIPSri84_R /* reg */
+} MIPSRI84Tag;
+
+typedef struct {
+ MIPSRI84Tag tag;
+ union {
+ struct {
+ UShort imm8;
+ UShort imm4;
+ } I84;
+ struct {
+ HReg reg;
+ } R;
+ } MIPSri84;
+} MIPSRI84;
+
+extern MIPSRI84 *MIPSRI84_I84(UShort imm8, UShort imm4);
+extern MIPSRI84 *MIPSRI84_R(HReg);
+
+extern void ppMIPSRI84(MIPSRI84 *);
+
+/* --------- Reg or imm5 operands --------- */
+typedef enum {
+ MIPSri5_I5 = 7, /* imm5, 1 .. 31 only (no zero!) */
+ MIPSri5_R /* reg */
+} MIPSRI5Tag;
+
+typedef struct {
+ MIPSRI5Tag tag;
+ union {
+ struct {
+ UInt imm5;
+ } I5;
+ struct {
+ HReg reg;
+ } R;
+ } MIPSri5;
+} MIPSRI5;
+
+extern MIPSRI5 *MIPSRI5_I5(UInt imm5);
+extern MIPSRI5 *MIPSRI5_R(HReg);
+
+extern void ppMIPSRI5(MIPSRI5 *);
+
+/* --------- Instructions. --------- */
+
+/*Tags for operations*/
+
+/* --------- */
+typedef enum {
+ Mun_CLO,
+ Mun_CLZ,
+ Mun_NOP,
+} MIPSUnaryOp;
+
+extern const HChar *showMIPSUnaryOp(MIPSUnaryOp);
+/* --------- */
+
+/* --------- */
+
+typedef enum {
+ Malu_INVALID,
+ Malu_ADD, Malu_SUB,
+ Malu_AND, Malu_OR, Malu_NOR, Malu_XOR,
+} MIPSAluOp;
+
+extern const HChar *showMIPSAluOp(MIPSAluOp,
+ Bool /* is the 2nd operand an immediate? */ );
+
+/* --------- */
+typedef enum {
+ Mshft_INVALID,
+ Mshft_SLL, Mshft_SRL,
+ Mshft_SRA
+} MIPSShftOp;
+
+extern const HChar *showMIPSShftOp(MIPSShftOp,
+ Bool /* is the 2nd operand an immediate? */ ,
+ Bool /* is this a 32bit or 64bit op? */ );
+
+/* --------- */
+typedef enum {
+ Macc_ADD,
+ Macc_SUB
+} MIPSMaccOp;
+
+extern const HChar *showMIPSMaccOp(MIPSMaccOp, Bool);
+/* --------- */
+
+/* ----- Instruction tags ----- */
+typedef enum {
+ Min_LI, /* load word (32/64-bit) immediate (fake insn) */
+ Min_Alu, /* word add/sub/and/or/xor/nor/others? */
+ Min_Shft, /* word sll/srl/sra */
+ Min_Unary, /* clo, clz, nop, neg */
+
+ Min_Cmp, /* word compare (fake insn) */
+
+ Min_Mul, /* widening/non-widening multiply */
+ Min_Div, /* div */
+
+ Min_Call, /* call to address in register */
+
+ /* The following 5 insns are mandated by translation chaining */
+ Min_XDirect, /* direct transfer to GA */
+ Min_XIndir, /* indirect transfer to GA */
+ Min_XAssisted, /* assisted transfer to GA */
+ Min_EvCheck, /* Event check */
+ Min_ProfInc, /* 64-bit profile counter increment */
+
+ Min_RdWrLR, /* Read/Write Link Register */
+ Min_Mthi, /* Move to HI from GP register */
+ Min_Mtlo, /* Move to LO from GP register */
+ Min_Mfhi, /* Move from HI to GP register */
+ Min_Mflo, /* Move from LO to GP register */
+ Min_Macc, /* Multiply and accumulate */
+
+ Min_Load, /* zero-extending load a 8|16|32 bit value from mem */
+ Min_Store, /* store a 8|16|32 bit value to mem */
+ Min_LoadL, /* mips Load Linked Word */
+ Min_StoreC, /* mips Store Conditional Word */
+
+ Min_FpUnary, /* FP unary op */
+ Min_FpBinary, /* FP binary op */
+ Min_FpConvert, /* FP conversion op */
+ Min_FpMulAcc, /* FP multipy-accumulate style op */
+ Min_FpLdSt, /* FP load/store */
+ Min_FpSTFIW, /* stfiwx */
+ Min_FpRSP, /* FP round IEEE754 double to IEEE754 single */
+ Min_FpCftI, /* fcfid/fctid/fctiw */
+ Min_FpCMov, /* FP floating point conditional move */
+ Min_MtFCSR, /* set FCSR register */
+ Min_MfFCSR, /* get FCSR register */
+ Min_FpCompare, /* FP compare, generating value into int reg */
+ Min_MovCond
+} MIPSInstrTag;
+
+/* --------- */
+typedef enum {
+ Mfp_INVALID,
+
+ /* Ternary */
+ Mfp_MADDD, Mfp_MSUBD,
+ Mfp_MADDS, Mfp_MSUBS,
+
+ /* Binary */
+ Mfp_ADDD, Mfp_SUBD, Mfp_MULD, Mfp_DIVD,
+ Mfp_ADDS, Mfp_SUBS, Mfp_MULS, Mfp_DIVS, Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD,
+ Mfp_CVTWS, Mfp_TRULS, Mfp_TRULD, Mfp_TRUWS, Mfp_TRUWD, Mfp_FLOORWS,
+ Mfp_FLOORWD, Mfp_ROUNDWS, Mfp_ROUNDWD, Mfp_CVTDW, Mfp_CMP,
+ Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD,
+
+ /* Unary */
+ Mfp_SQRTS, Mfp_SQRTD, Mfp_RSQRTS, Mfp_RSQRTD, Mfp_RECIPS, Mfp_RECIPD,
+ Mfp_ABSS, Mfp_ABSD, Mfp_NEGS, Mfp_NEGD, Mfp_MOVS, Mfp_MOVD,
+ Mfp_RES, Mfp_RSQRTE, Mfp_FRIN, Mfp_FRIM, Mfp_FRIP, Mfp_FRIZ, Mfp_CVTD
+} MIPSFpOp;
+
+extern const HChar *showMIPSFpOp(MIPSFpOp);
+
+/*--------- Structure for instructions ----------*/
+/* Destinations are on the LEFT (first operand) */
+
+typedef struct {
+ MIPSInstrTag tag;
+ union {
+ /* Get a 32/64-bit literal into a register.
+ May turn into a number of real insns. */
+ struct {
+ HReg dst;
+ ULong imm;
+ } LI;
+ /* Integer add/sub/and/or/xor. Limitations:
+ - For add, the immediate, if it exists, is a signed 16.
+ - For sub, the immediate, if it exists, is a signed 16
+ which may not be -32768, since no such instruction
+ exists, and so we have to emit addi with +32768, but
+ that is not possible.
+ - For and/or/xor, the immediate, if it exists,
+ is an unsigned 16.
+ */
+ struct {
+ MIPSAluOp op;
+ HReg dst;
+ HReg srcL;
+ MIPSRH *srcR;
+ } Alu;
+ /* Integer shl/shr/sar.
+ Limitations: the immediate, if it exists,
+ is a signed 5-bit value between 1 and 31 inclusive.
+ */
+ struct {
+ MIPSShftOp op;
+ Bool sz32; /* mode64 has both 32 and 64bit shft */
+ HReg dst;
+ HReg srcL;
+ MIPSRH *srcR;
+ } Shft;
+ /* Clz, Clo, nop */
+ struct {
+ MIPSUnaryOp op;
+ HReg dst;
+ HReg src;
+ } Unary;
+ /* Word compare. Fake instruction, used for basic block ending */
+ struct {
+ Bool syned;
+ Bool sz32;
+ HReg dst;
+ HReg srcL;
+ HReg srcR;
+
+ MIPSCondCode cond;
+ } Cmp;
+ struct {
+ Bool widening; //True => widening, False => non-widening
+ Bool syned; //signed/unsigned - meaningless if widenind = False
+ Bool sz32;
+ HReg dst;
+ HReg srcL;
+ HReg srcR;
+ } Mul;
+ struct {
+ Bool syned; //signed/unsigned - meaningless if widenind = False
+ Bool sz32;
+ HReg srcL;
+ HReg srcR;
+ } Div;
+ /* Pseudo-insn. Call target (an absolute address), on given
+ condition (which could be Mcc_ALWAYS). argiregs indicates
+ which of r3 .. r10
+ carries argument values for this call,
+ using a bit mask (1<<N is set if rN holds an arg, for N in
+ 3 .. 10 inclusive).
+ If cond is != Mcc_ALWAYS, src is checked.
+ Otherwise, unconditional call */
+ struct {
+ MIPSCondCode cond;
+ Addr32 target;
+ UInt argiregs;
+ HReg src;
+ } Call;
+ /* Update the guest EIP value, then exit requesting to chain
+ to it. May be conditional. Urr, use of Addr32 implicitly
+ assumes that wordsize(guest) == wordsize(host). */
+ struct {
+ Addr32 dstGA; /* next guest address */
+ MIPSAMode* amPC; /* amode in guest state for PC */
+ MIPSCondCode cond; /* can be MIPScc_AL */
+ Bool toFastEP; /* chain to the slow or fast point? */
+ } XDirect;
+ /* Boring transfer to a guest address not known at JIT time.
+ Not chainable. May be conditional. */
+ struct {
+ HReg dstGA;
+ MIPSAMode* amPC;
+ MIPSCondCode cond; /* can be MIPScc_AL */
+ } XIndir;
+ /* Assisted transfer to a guest address, most general case.
+ Not chainable. May be conditional. */
+ struct {
+ HReg dstGA;
+ MIPSAMode* amPC;
+ MIPSCondCode cond; /* can be MIPScc_AL */
+ IRJumpKind jk;
+ } XAssisted;
+ /* Zero extending loads. Dst size is host word size */
+ struct {
+ UChar sz; /* 1|2|4|8 */
+ HReg dst;
+ MIPSAMode *src;
+ } Load;
+ /* 64/32/16/8 bit stores */
+ struct {
+ UChar sz; /* 1|2|4|8 */
+ MIPSAMode *dst;
+ HReg src;
+ } Store;
+ struct {
+ UChar sz; /* 4|8 */
+ HReg dst;
+ MIPSAMode *src;
+ } LoadL;
+ struct {
+ UChar sz; /* 4|8 */
+ MIPSAMode *dst;
+ HReg src;
+ } StoreC;
+ /* Move from HI/LO register to GP register. */
+ struct {
+ HReg dst;
+ } MfHL;
+
+ /* Move to HI/LO register from GP register. */
+ struct {
+ HReg src;
+ } MtHL;
+
+ /* Read/Write Link Register */
+ struct {
+ Bool wrLR;
+ HReg gpr;
+ } RdWrLR;
+
+ /* MIPS Multiply and accumulate instructions. */
+ struct {
+ MIPSMaccOp op;
+ Bool syned;
+
+ HReg srcL;
+ HReg srcR;
+ } Macc;
+
+ /* MIPS Floating point */
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg src;
+ } FpUnary;
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg srcL;
+ HReg srcR;
+ } FpBinary;
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg srcML;
+ HReg srcMR;
+ HReg srcAcc;
+ } FpMulAcc;
+ struct {
+ Bool isLoad;
+ UChar sz; /* only 4 (IEEE single) or 8 (IEEE double) */
+ HReg reg;
+ MIPSAMode *addr;
+ } FpLdSt;
+
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg src;
+ } FpConvert;
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg srcL;
+ HReg srcR;
+ UChar cond1;
+ } FpCompare;
+ struct {
+ MIPSFpOp op;
+ HReg dst;
+ HReg srcL;
+ MIPSRH *srcR;
+ HReg condR;
+ MIPSCondCode cond;
+ } MovCond;
+ /* Move from GP register to FCSR register. */
+ struct {
+ HReg src;
+ } MtFCSR;
+ /* Move from FCSR register to GP register. */
+ struct {
+ HReg dst;
+ } MfFCSR;
+ struct {
+ MIPSAMode* amCounter;
+ MIPSAMode* amFailAddr;
+ } EvCheck;
+ struct {
+ /* No fields. The address of the counter to inc is
+ installed later, post-translation, by patching it in,
+ as it is not known at translation time. */
+ } ProfInc;
+
+ } Min;
+} MIPSInstr;
+
+extern MIPSInstr *MIPSInstr_LI(HReg, ULong);
+extern MIPSInstr *MIPSInstr_Alu(MIPSAluOp, HReg, HReg, MIPSRH *);
+extern MIPSInstr *MIPSInstr_Shft(MIPSShftOp, Bool sz32, HReg, HReg, MIPSRH
*);
+extern MIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src);
+extern MIPSInstr *MIPSInstr_Cmp(Bool, Bool, HReg, HReg, HReg,
MIPSCondCode);
+
+extern MIPSInstr *MIPSInstr_Mul(Bool syned, Bool hi32, Bool sz32, HReg,
+ HReg, HReg);
+extern MIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg, HReg);
+extern MIPSInstr *MIPSInstr_Madd(Bool, HReg, HReg);
+extern MIPSInstr *MIPSInstr_Msub(Bool, HReg, HReg);
+
+extern MIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src,
+ Bool mode64);
+extern MIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src,
+ Bool mode64);
+
+extern MIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src,
+ Bool mode64);
+extern MIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src,
+ Bool mode64);
+
+extern MIPSInstr *MIPSInstr_Call(MIPSCondCode, Addr32, UInt, HReg);
+extern MIPSInstr *MIPSInstr_CallAlways(MIPSCondCode, Addr32, UInt);
+
+extern MIPSInstr *MIPSInstr_XDirect(Addr32 dstGA, MIPSAMode* amPC,
+ MIPSCondCode cond, Bool toFastEP);
+extern MIPSInstr *MIPSInstr_XIndir(HReg dstGA, MIPSAMode* amPC,
+ MIPSCondCode cond);
+extern MIPSInstr *MIPSInstr_XAssisted(HReg dstGA, MIPSAMode* amPC,
+ MIPSCondCode cond, IRJumpKind jk);
+
+extern MIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src);
+extern MIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL,
+ HReg srcR);
+extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src);
+extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL,
+ HReg srcR, UChar cond1);
+extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML,
+ HReg srcMR, HReg srcAcc);
+extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode
*);
+extern MIPSInstr *MIPSInstr_FpSTFIW(HReg addr, HReg data);
+extern MIPSInstr *MIPSInstr_FpRSP(HReg dst, HReg src);
+extern MIPSInstr *MIPSInstr_FpCftI(Bool fromI, Bool int32, HReg dst, HReg
src);
+extern MIPSInstr *MIPSInstr_FpCMov(MIPSCondCode, HReg dst, HReg src);
+extern MIPSInstr *MIPSInstr_MtFCSR(HReg src);
+extern MIPSInstr *MIPSInstr_MfFCSR(HReg dst);
+extern MIPSInstr *MIPSInstr_FpCmp(HReg dst, HReg srcL, HReg srcR);
+
+extern MIPSInstr *MIPSInstr_Mfhi(HReg dst);
+extern MIPSInstr *MIPSInstr_Mflo(HReg dst);
+extern MIPSInstr *MIPSInstr_Mthi(HReg src);
+extern MIPSInstr *MIPSInstr_Mtlo(HReg src);
+
+extern MIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr);
+
+// srcL will be copied if !condR
+extern MIPSInstr *MIPSInstr_MovCond(HReg dst, HReg srcL, MIPSRH * src,
+ HReg condR, MIPSCondCode cond);
+
+extern MIPSInstr *MIPSInstr_EvCheck(MIPSAMode* amCounter,
+ MIPSAMode* amFailAddr );
+extern MIPSInstr *MIPSInstr_ProfInc( void );
+
+extern void ppMIPSInstr(MIPSInstr *, Bool mode64);
+
+/* Some functions that insulate the register allocator from details
+ of the underlying instruction set. */
+extern void getRegUsage_MIPSInstr (HRegUsage *, MIPSInstr *, Bool);
+extern void mapRegs_MIPSInstr (HRegRemap *, MIPSInstr *, Bool
mode64);
+extern Bool isMove_MIPSInstr (MIPSInstr *, HReg *, HReg *);
+extern Int emit_MIPSInstr (/*MB_MOD*/Bool* is_profInc,
+ UChar* buf, Int nbuf, MIPSInstr*
i,
+ Bool mode64,
+ void* disp_cp_chain_me_to_slowEP,
+ void* disp_cp_chain_me_to_fastEP,
+ void* disp_cp_xindir,
+ void* disp_cp_xassisted );
+
+extern void genSpill_MIPS ( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
+ HReg rreg, Int offset, Bool);
+extern void genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2,
+ HReg rreg, Int offset, Bool);
+
+extern void getAllocableRegs_MIPS (Int *, HReg **, Bool mode64);
+extern HInstrArray *iselSB_MIPS ( IRSB*,
+ VexArch,
+ VexArchInfo*,
+ VexAbiInfo*,
+ Int offs_Host_EvC_Counter,
+ Int offs_Host_EvC_FailAddr,
+ Bool chainingAllowed,
+ Bool addProfInc,
+ Addr64 max_ga );
+
+/* How big is an event check? This is kind of a kludge because it
+ depends on the offsets of host_EvC_FAILADDR and host_EvC_COUNTER,
+ and so assumes that they are both <= 128, and so can use the short
+ offset encoding. This is all checked with assertions, so in the
+ worst case we will merely assert at startup. */
+extern Int evCheckSzB_MIPS ( void );
+
+/* Perform a chaining and unchaining of an XDirect jump. */
+extern VexInvalRange chainXDirect_MIPS ( void* place_to_chain,
+ void* disp_cp_chain_me_EXPECTED,
+ void* place_to_jump_to,
+ Bool mode64 );
+
+extern VexInvalRange unchainXDirect_MIPS ( void* place_to_unchain,
+ void* place_to_jump_to_EXPECTED,
+ void* disp_cp_chain_me,
+ Bool mode64 );
+
+/* Patch the counter location into an existing ProfInc point. */
+extern VexInvalRange patchProfInc_MIPS ( void* place_to_patch,
+ ULong* location_of_counter,
+ Bool mode64 );
+
+#endif /* ndef __LIBVEX_HOST_MIPS_HDEFS_H */
+
+/*---------------------------------------------------------------*/
+/*--- end host-mips_defs.h ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/host_mips_isel.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,3293 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin host_mips_isel.c ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+
+#include "main_util.h"
+#include "main_globals.h"
+#include "host_generic_regs.h"
+#include "host_mips_defs.h"
+
+/*---------------------------------------------------------*/
+/*--- Register Usage Conventions ---*/
+/*---------------------------------------------------------*/
+/*
+
+Integer Regs
+------------
+ZERO0 Reserved
+GPR1:9 Allocateable
+10 GuestStatePointer
+GPR1:9 Allocateable
+SP StackFramePointer
+RA LinkRegister
+
+*/
+
+static Bool mode64 = False;
+
+/* GPR register class for mips32/64 */
+#define HRcGPR(__mode64) (__mode64 ? HRcInt64 : HRcInt32)
+
+/* FPR register class for mips32/64 */
+#define HRcFPR(__mode64) (__mode64 ? HRcFlt64 : HRcFlt32)
+
+/*---------------------------------------------------------*/
+/*--- ISelEnv ---*/
+/*---------------------------------------------------------*/
+
+/* This carries around:
+
+ - A mapping from IRTemp to IRType, giving the type of any IRTemp we
+ might encounter. This is computed before insn selection starts,
+ and does not change.
+
+ - A mapping from IRTemp to HReg. This tells the insn selector
+ which virtual register(s) are associated with each IRTemp
+ temporary. This is computed before insn selection starts, and
+ does not change. We expect this mapping to map precisely the
+ same set of IRTemps as the type mapping does.
+
+ - vregmap holds the primary register for the IRTemp.
+ - vregmapHI is only used for 64-bit integer-typed
+ IRTemps. It holds the identity of a second
+ 32-bit virtual HReg, which holds the high half
+ of the value.
+
+ - The code array, that is, the insns selected so far.
+
+ - A counter, for generating new virtual registers.
+
+ - The host subarchitecture we are selecting insns for.
+ This is set at the start and does not change.
+
+ - A Bool for indicating whether we may generate chain-me
+ instructions for control flow transfers, or whether we must use
+ XAssisted.
+
+ - The maximum guest address of any guest insn in this block.
+ Actually, the address of the highest-addressed byte from any insn
+ in this block. Is set at the start and does not change. This is
+ used for detecting jumps which are definitely forward-edges from
+ this block, and therefore can be made (chained) to the fast entry
+ point of the destination, thereby avoiding the destination's
+ event check.
+
+ Note, this is all (well, mostly) host-independent.
+*/
+
+typedef
+ struct {
+ /* Constant -- are set at the start and do not change. */
+ IRTypeEnv* type_env;
+
+ HReg* vregmap;
+ HReg* vregmapHI;
+ Int n_vregmap;
+
+ UInt hwcaps;
+ Bool mode64;
+
+ Bool chainingAllowed;
+ Addr64 max_ga;
+
+ /* These are modified as we go along. */
+ HInstrArray* code;
+ Int vreg_ctr;
+ }
+ ISelEnv;
+
+static HReg lookupIRTemp(ISelEnv * env, IRTemp tmp)
+{
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ return env->vregmap[tmp];
+}
+
+static void lookupIRTemp64(HReg * vrHI, HReg * vrLO, ISelEnv * env, IRTemp
tmp)
+{
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ vassert(env->vregmapHI[tmp] != INVALID_HREG);
+ *vrLO = env->vregmap[tmp];
+ *vrHI = env->vregmapHI[tmp];
+}
+
+static void
+lookupIRTempPair(HReg * vrHI, HReg * vrLO, ISelEnv * env, IRTemp tmp)
+{
+ vassert(env->mode64);
+ vassert(tmp >= 0);
+ vassert(tmp < env->n_vregmap);
+ vassert(env->vregmapHI[tmp] != INVALID_HREG);
+ *vrLO = env->vregmap[tmp];
+ *vrHI = env->vregmapHI[tmp];
+}
+
+static void addInstr(ISelEnv * env, MIPSInstr * instr)
+{
+ addHInstr(env->code, instr);
+ if (vex_traceflags & VEX_TRACE_VCODE) {
+ ppMIPSInstr(instr, mode64);
+ vex_printf("\n");
+ }
+}
+
+static HReg newVRegI(ISelEnv * env)
+{
+ HReg reg = mkHReg(env->vreg_ctr, HRcGPR(env->mode64),
+ True /*virtual reg */ );
+ env->vreg_ctr++;
+ return reg;
+}
+
+static HReg newVRegD(ISelEnv * env)
+{
+ HReg reg = mkHReg(env->vreg_ctr, HRcFlt64, True /*virtual reg */ );
+ env->vreg_ctr++;
+ return reg;
+}
+
+static HReg newVRegF(ISelEnv * env)
+{
+ HReg reg = mkHReg(env->vreg_ctr, HRcFPR(env->mode64),
+ True /*virtual reg */ );
+ env->vreg_ctr++;
+ return reg;
+}
+
+static void add_to_sp(ISelEnv * env, UInt n)
+{
+ HReg sp = StackPointer(mode64);
+ vassert(n < 256 && (n % 8) == 0);
+ addInstr(env, MIPSInstr_Alu(Malu_ADD, sp, sp, MIPSRH_Imm(True,
+ toUShort(n))));
+}
+
+static void sub_from_sp(ISelEnv * env, UInt n)
+{
+ HReg sp = StackPointer(mode64);
+ vassert(n < 256 && (n % 8) == 0);
+ addInstr(env, MIPSInstr_Alu(Malu_SUB, sp, sp,
+ MIPSRH_Imm(True, toUShort(n))));
+}
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Forward declarations ---*/
+/*---------------------------------------------------------*/
+
+/* These are organised as iselXXX and iselXXX_wrk pairs. The
+ iselXXX_wrk do the real work, but are not to be called directly.
+ For each XXX, iselXXX calls its iselXXX_wrk counterpart, then
+ checks that all returned registers are virtual. You should not
+ call the _wrk version directly.
+*/
+/* 32-bit mode: Compute an I8/I16/I32 into a RH
+ (reg-or-halfword-immediate).
+ It's important to specify whether the immediate is to be regarded
+ as signed or not. If yes, this will never return -32768 as an
+ immediate; this guaranteed that all signed immediates that are
+ return can have their sign inverted if need be.
+*/
+static MIPSRH *iselWordExpr_RH_wrk(ISelEnv * env, Bool syned, IRExpr * e);
+static MIPSRH *iselWordExpr_RH(ISelEnv * env, Bool syned, IRExpr * e);
+
+/* Compute an I8 into a reg-or-5-bit-unsigned-immediate, the latter being
an immediate in
+ the range 1 .. 31 inclusive. Used for doing shift amounts. */
+static MIPSRH *iselWordExpr_RH5u_wrk(ISelEnv * env, IRExpr * e);
+static MIPSRH *iselWordExpr_RH5u(ISelEnv * env, IRExpr * e);
+
+/* compute an I8/I16/I32 into a GPR*/
+static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e);
+static HReg iselWordExpr_R(ISelEnv * env, IRExpr * e);
+
+/* compute an I32 into an AMode. */
+static MIPSAMode *iselWordExpr_AMode_wrk(ISelEnv * env, IRExpr * e,
+ IRType xferTy);
+static MIPSAMode *iselWordExpr_AMode(ISelEnv * env, IRExpr * e, IRType
xferTy);
+
+static void iselInt64Expr_wrk(HReg * rHi, HReg * rLo, ISelEnv * env,
+ IRExpr * e);
+static void iselInt64Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr *
e);
+
+/* 64-bit mode ONLY: compute an I128 into a GPR64 pair. */
+static void iselInt128Expr_wrk(HReg * rHi, HReg * rLo,
+ ISelEnv * env, IRExpr * e);
+static void iselInt128Expr(HReg * rHi, HReg * rLo, ISelEnv * env, IRExpr *
e);
+
+static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e);
+static MIPSCondCode iselCondCode(ISelEnv * env, IRExpr * e);
+
+static HReg iselDblExpr_wrk(ISelEnv * env, IRExpr * e);
+static HReg iselDblExpr(ISelEnv * env, IRExpr * e);
+
+static HReg iselFltExpr_wrk(ISelEnv * env, IRExpr * e);
+static HReg iselFltExpr(ISelEnv * env, IRExpr * e);
+
+static void set_MIPS_rounding_mode(ISelEnv * env, IRExpr * mode)
+{
+ /*
+ rounding mode | MIPS | IR
+ ------------------------
+ to nearest | 00 | 00
+ to zero | 01 | 11
+ to +infinity | 10 | 10
+ to -infinity | 11 | 01
+ */
+ // rm_MIPS32 = XOR(rm_IR , (rm_IR << 1)) & 2
+ HReg irrm = iselWordExpr_R(env, mode);
+ HReg tmp = newVRegI(env);
+ HReg fcsr_old = newVRegI(env);
+ MIPSAMode *am_addr;
+
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, irrm,
+ MIPSRH_Imm(False, 1)));
+ addInstr(env, MIPSInstr_Alu(Malu_XOR, tmp, irrm, MIPSRH_Reg(tmp)));
+ addInstr(env, MIPSInstr_Alu(Malu_AND, irrm, tmp, MIPSRH_Imm(False, 3)));
+ /* save old value of FCSR */
+ addInstr(env, MIPSInstr_MfFCSR(fcsr_old));
+ sub_from_sp(env, 8); // Move SP down 4 bytes
+ am_addr = MIPSAMode_IR(0, StackPointer(mode64));
+
+ //store old FCSR to stack
+ addInstr(env, MIPSInstr_Store(4, am_addr, fcsr_old, mode64));
+
+ //set new value of FCSR
+ addInstr(env, MIPSInstr_MtFCSR(irrm));
+}
+
+static void set_MIPS_rounding_default(ISelEnv * env)
+{
+ HReg fcsr = newVRegI(env);
+ // load as float
+ MIPSAMode *am_addr;
+ am_addr = MIPSAMode_IR(0, StackPointer(mode64));
+
+ addInstr(env, MIPSInstr_Load(4, fcsr, am_addr, mode64));
+
+ add_to_sp(env, 8); // Reset SP
+
+ //set new value of FCSR
+ addInstr(env, MIPSInstr_MtFCSR(fcsr));
+}
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Misc helpers ---*/
+/*---------------------------------------------------------*/
+
+/* Make an int reg-reg move. */
+static MIPSInstr *mk_iMOVds_RR(HReg r_dst, HReg r_src)
+{
+ vassert(hregClass(r_dst) == hregClass(r_src));
+ vassert(hregClass(r_src) == HRcInt32 || hregClass(r_src) == HRcInt64);
+ return MIPSInstr_Alu(Malu_OR, r_dst, r_src, MIPSRH_Reg(r_src));
+}
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Function call helpers ---*/
+/*---------------------------------------------------------*/
+
+/* Used only in doHelperCall. See big comment in doHelperCall re
+ handling of register-parameter args. This function figures out
+ whether evaluation of an expression might require use of a fixed
+ register. If in doubt return True (safe but suboptimal).
+*/
+static Bool mightRequireFixedRegs(IRExpr * e)
+{
+ switch (e->tag) {
+ case Iex_RdTmp:
+ case Iex_Const:
+ case Iex_Get:
+ return False;
+ default:
+ return True;
+ }
+}
+
+/* Load 2*I32 regs to fp reg */
+static HReg mk_LoadRR32toFPR(ISelEnv * env, HReg r_srcHi, HReg r_srcLo)
+{
+ HReg fr_dst = newVRegD(env);
+ MIPSAMode *am_addr0, *am_addr1;
+
+ vassert(hregClass(r_srcHi) == HRcInt32);
+ vassert(hregClass(r_srcLo) == HRcInt32);
+
+ sub_from_sp(env, 16); // Move SP down 16 bytes
+ am_addr0 = MIPSAMode_IR(0, StackPointer(mode64));
+ am_addr1 = MIPSAMode_IR(4, StackPointer(mode64));
+
+ // store hi,lo as Ity_I32's
+ addInstr(env, MIPSInstr_Store(4, am_addr0, r_srcLo, mode64));
+ addInstr(env, MIPSInstr_Store(4, am_addr1, r_srcHi, mode64));
+
+ // load as float
+ addInstr(env, MIPSInstr_FpLdSt(True /*load */ , 8, fr_dst, am_addr0));
+
+ add_to_sp(env, 16); // Reset SP
+ return fr_dst;
+}
+
+/* Do a complete function call. guard is a Ity_Bit expression
+ indicating whether or not the call happens. If guard==NULL, the
+ call is unconditional. */
+
+static void doHelperCall(ISelEnv * env, Bool passBBP, IRExpr * guard,
+ IRCallee * cee, IRExpr ** args)
+{
+ MIPSCondCode cc;
+ HReg argregs[MIPS_N_REGPARMS];
+ HReg tmpregs[MIPS_N_REGPARMS];
+ Bool go_fast;
+ Int n_args, i, argreg;
+ UInt argiregs;
+ ULong target;
+ HReg src = 0;
+
+ /* MIPS O32 calling convention: up to four registers ($a0 ... $a3)
+ are allowed to be used for passing integer arguments. They correspond
+ to regs GPR4 ... GPR7. Note that the cee->regparms field is
meaningless
+ on MIPS host (since we only implement one calling convention) and so
we
+ always ignore it. */
+
+ /* MIPS 64 calling convention: up to four registers ($a0 ... $a7)
+ are allowed to be used for passing integer arguments. They correspond
+ to regs GPR4 ... GPR11. Note that the cee->regparms field is
meaningless
+ on MIPS host (since we only implement one calling convention) and so
we
+ always ignore it. */
+ n_args = 0;
+ for (i = 0; args[i]; i++)
+ n_args++;
+
+ if (MIPS_N_REGPARMS < n_args + (passBBP ? 1 : 0)) {
+ vpanic("doHelperCall(MIPS): cannot currently handle > 4 args");
+ }
+ argregs[0] = hregMIPS_GPR4(mode64);
+ argregs[1] = hregMIPS_GPR5(mode64);
+ argregs[2] = hregMIPS_GPR6(mode64);
+ argregs[3] = hregMIPS_GPR7(mode64);
+ argiregs = 0;
+
+ tmpregs[0] = tmpregs[1] = tmpregs[2] = tmpregs[3] = INVALID_HREG;
+
+ /* First decide which scheme (slow or fast) is to be used. First
+ assume the fast scheme, and select slow if any contraindications
+ (wow) appear. */
+
+ go_fast = True;
+
+ if (guard) {
+ if (guard->tag == Iex_Const && guard->Iex.Const.con->tag == Ico_U1
+ && guard->Iex.Const.con->Ico.U1 == True) {
+ /* unconditional */
+ } else {
+ /* Not manifestly unconditional -- be conservative. */
+ go_fast = False;
+ }
+ }
+
+ if (go_fast) {
+ for (i = 0; i < n_args; i++) {
+ if (mightRequireFixedRegs(args[i])) {
+ go_fast = False;
+ break;
+ }
+ }
+ }
+
+ /* save GuestStatePointer on the stack */
+ sub_from_sp(env, 8); // Move SP down 4 bytes
+ addInstr(env, MIPSInstr_Store(4, MIPSAMode_IR(0, StackPointer(mode64)),
+ GuestStatePointer(mode64), mode64));
+
+ /* At this point the scheme to use has been established. Generate
+ code to get the arg values into the argument rregs. */
+ if (go_fast) {
+ /* FAST SCHEME */
+ argreg = 0;
+ if (passBBP) {
+ argiregs |= (1 << (argreg + 4));
+ addInstr(env, mk_iMOVds_RR(argregs[argreg],
+ GuestStatePointer(mode64)));
+ argreg++;
+ }
+
+ for (i = 0; i < n_args; i++) {
+ vassert(argreg < MIPS_N_REGPARMS);
+ vassert(typeOfIRExpr(env->type_env, args[i]) == Ity_I32
+ || typeOfIRExpr(env->type_env, args[i]) == Ity_I64);
+ if (typeOfIRExpr(env->type_env, args[i]) == Ity_I32 || mode64) {
+ argiregs |= (1 << (argreg + 4));
+ addInstr(env, mk_iMOVds_RR(argregs[argreg], iselWordExpr_R(env,
+ args[i])));
+ } else { // Ity_I64
+ if (argreg & 1) {
+ argreg++;
+ argiregs |= (1 << (argreg + 4));
+ }
+ HReg rHi, rLo;
+ iselInt64Expr(&rHi, &rLo, env, args[i]);
+ argiregs |= (1 << (argreg + 4));
+ addInstr(env, mk_iMOVds_RR( argregs[argreg++], rHi ));
+ argiregs |= (1 << (argreg + 4));
+ addInstr(env, mk_iMOVds_RR( argregs[argreg], rLo));
+ }
+ argreg++;
+ }
+ /* Fast scheme only applies for unconditional calls. Hence: */
+ cc = MIPScc_AL;
+ } else {
+ /* SLOW SCHEME; move via temporaries */
+ argreg = 0;
+ if (passBBP) {
+ /* This is pretty stupid; better to move directly to r3
+ after the rest of the args are done. */
+ tmpregs[argreg] = newVRegI(env);
+ addInstr(env, mk_iMOVds_RR(tmpregs[argreg],
+ GuestStatePointer(mode64)));
+ argreg++;
+ }
+ for (i = 0; i < n_args; i++) {
+ vassert(argreg < MIPS_N_REGPARMS);
+ vassert(typeOfIRExpr(env->type_env, args[i]) == Ity_I32
+ || typeOfIRExpr(env->type_env, args[i]) == Ity_I64);
+ if (typeOfIRExpr(env->type_env, args[i]) == Ity_I32 || mode64) {
+ tmpregs[argreg] = iselWordExpr_R(env, args[i]);
+ } else { // Ity_I64
+ if (argreg & 1)
+ argreg++;
+ if (argreg + 1 >= MIPS_N_REGPARMS)
+ vassert(0); /* out of argregs */
+ HReg raHi, raLo;
+ iselInt64Expr(&raHi, &raLo, env, args[i]);
+ tmpregs[argreg] = raLo;
+ argreg++;
+ tmpregs[argreg] = raHi;
+ }
+ argreg++;
+ }
+
+ /* Now we can compute the condition. We can't do it earlier
+ because the argument computations could trash the condition
+ codes. Be a bit clever to handle the common case where the
+ guard is 1:Bit. */
+ cc = MIPScc_AL;
+ if (guard) {
+ if (guard->tag == Iex_Const && guard->Iex.Const.con->tag == Ico_U1
+ && guard->Iex.Const.con->Ico.U1 == True) {
+ /* unconditional -- do nothing */
+ } else {
+ cc = iselCondCode(env, guard);
+ src = iselWordExpr_R(env, guard);
+ }
+ }
+ /* Move the args to their final destinations. */
+ for (i = 0; i < argreg; i++) {
+ if (tmpregs[i] == INVALID_HREG) // Skip invalid regs
+ continue;
+ /* None of these insns, including any spill code that might
+ be generated, may alter the condition codes. */
+ argiregs |= (1 << (i + 4));
+ addInstr(env, mk_iMOVds_RR(argregs[i], tmpregs[i]));
+ }
+ }
+
+ target = toUInt(Ptr_to_ULong(cee->addr));
+
+ /* Finally, the call itself. */
+ if (mode64)
+ if (cc == MIPScc_AL) {
+ addInstr(env, MIPSInstr_CallAlways(cc, target, argiregs));
+ } else {
+ addInstr(env, MIPSInstr_Call(cc, target, argiregs, src));
+ } else if (cc == MIPScc_AL) {
+ addInstr(env, MIPSInstr_CallAlways(cc, (Addr32) target, argiregs));
+ } else {
+ addInstr(env, MIPSInstr_Call(cc, (Addr32) target, argiregs, src));
+ }
+ /* restore GuestStatePointer */
+ addInstr(env, MIPSInstr_Load(4, GuestStatePointer(mode64),
+ MIPSAMode_IR(0, StackPointer(mode64)), mode64));
+ add_to_sp(env, 8); // Reset SP
+}
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Integer expression auxiliaries ---*/
+/*---------------------------------------------------------*/
+
+/* --------------------- AMODEs --------------------- */
+
+/* Return an AMode which computes the value of the specified
+ expression, possibly also adding insns to the code list as a
+ result. The expression may only be a word-size one.
+*/
+
+static Bool uInt_fits_in_16_bits(UInt u)
+{
+ Int i = u & 0xFFFF;
+ i <<= 16;
+ i >>= 16;
+ return toBool(u == (UInt) i);
+}
+
+static Bool sane_AMode(ISelEnv * env, MIPSAMode * am)
+{
+ switch (am->tag) {
+ case Mam_IR:
+ return toBool(hregClass(am->Mam.IR.base) == HRcGPR(mode64) &&
+ hregIsVirtual(am->Mam.IR.base) &&
+ uInt_fits_in_16_bits(am->Mam.IR.index));
+ case Mam_RR:
+ return toBool(hregClass(am->Mam.RR.base) == HRcGPR(mode64) &&
+ hregIsVirtual(am->Mam.RR.base) &&
+ hregClass(am->Mam.RR.index) == HRcGPR(mode64) &&
+ hregIsVirtual(am->Mam.IR.index));
+ default:
+ vpanic("sane_AMode: unknown mips amode tag");
+ }
+}
+
+static MIPSAMode *iselWordExpr_AMode(ISelEnv * env, IRExpr * e, IRType
xferTy)
+{
+ MIPSAMode *am = iselWordExpr_AMode_wrk(env, e, xferTy);
+ vassert(sane_AMode(env, am));
+ return am;
+}
+
+/* DO NOT CALL THIS DIRECTLY ! */
+static MIPSAMode *iselWordExpr_AMode_wrk(ISelEnv * env, IRExpr * e,
+ IRType xferTy)
+{
+ IRType ty = typeOfIRExpr(env->type_env, e);
+ {
+ vassert(ty == Ity_I32);
+
+ /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */
+ if (e->tag == Iex_Binop
+ && e->Iex.Binop.op == Iop_Add32
+ && e->Iex.Binop.arg2->tag == Iex_Const
+ && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32
+ && uInt_fits_in_16_bits(e->Iex.Binop.arg2->Iex.Const.con->
Ico.U32)) {
+ return MIPSAMode_IR((Int)
e->Iex.Binop.arg2->Iex.Const.con->Ico.U32,
+ iselWordExpr_R(env, e->Iex.Binop.arg1));
+ }
+
+ /* Add32(expr,expr) */
+ if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_Add32) {
+ HReg r_base = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ HReg r_idx = iselWordExpr_R(env, e->Iex.Binop.arg2);
+
+ return MIPSAMode_RR(r_idx, r_base);
+ }
+ }
+
+ /* Doesn't match anything in particular. Generate it into
+ a register and use that. */
+ return MIPSAMode_IR(0, iselWordExpr_R(env, e));
+}
+
+/*---------------------------------------------------------*/
+/*--- ISEL: Integer expressions (64/32/16/8 bit) ---*/
+/*---------------------------------------------------------*/
+
+/* Select insns for an integer-typed expression, and add them to the
+ code list. Return a reg holding the result. This reg will be a
+ virtual register. THE RETURNED REG MUST NOT BE MODIFIED. If you
+ want to modify it, ask for a new vreg, copy it in there, and modify
+ the copy. The register allocator will do its best to map both
+ vregs to the same real register, so the copies will often disappear
+ later in the game.
+
+ This should handle expressions of 64, 32, 16 and 8-bit type.
+ All results are returned in a (mode64 ? 64bit : 32bit) register.
+ For 16- and 8-bit expressions, the upper (32/48/56 : 16/24) bits
+ are arbitrary, so you should mask or sign extend partial values
+ if necessary.
+*/
+static HReg iselWordExpr_R(ISelEnv * env, IRExpr * e)
+{
+ HReg r = iselWordExpr_R_wrk(env, e);
+ /* sanity checks ... */
+
+ vassert(hregClass(r) == HRcGPR(env->mode64));
+ vassert(hregIsVirtual(r));
+ return r;
+}
+
+/* DO NOT CALL THIS DIRECTLY ! */
+static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e)
+{
+ IRType ty = typeOfIRExpr(env->type_env, e);
+ vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32 || ty == Ity_I1
+ || ty == Ity_F32 || (ty == Ity_I64 && mode64)
+ || (ty == Ity_I128 && mode64));
+
+ switch (e->tag) {
+ /* --------- TEMP --------- */
+ case Iex_RdTmp:
+ return lookupIRTemp(env, e->Iex.RdTmp.tmp);
+
+ /* --------- LOAD --------- */
+ case Iex_Load: {
+ HReg r_dst = newVRegI(env);
+ MIPSAMode *am_addr = iselWordExpr_AMode(env, e->Iex.Load.addr,
ty);
+
+ if (e->Iex.Load.end != Iend_LE
+ && e->Iex.Load.end != Iend_BE)
+ goto irreducible;
+
+ addInstr(env, MIPSInstr_Load(toUChar(sizeofIRType(ty)),
+ r_dst, am_addr, mode64));
+ return r_dst;
+ }
+
+ /* --------- BINARY OP --------- */
+ case Iex_Binop: {
+ MIPSAluOp aluOp;
+ MIPSShftOp shftOp;
+
+ /* Is it an addition or logical style op? */
+ switch (e->Iex.Binop.op) {
+ case Iop_Add32:
+ aluOp = Malu_ADD;
+ break;
+
+ case Iop_Sub8:
+ case Iop_Sub16:
+ case Iop_Sub32:
+ aluOp = Malu_SUB;
+ break;
+
+ case Iop_And32:
+ case Iop_And64:
+ aluOp = Malu_AND;
+ break;
+
+ case Iop_Or32:
+ case Iop_Or64:
+ aluOp = Malu_OR;
+ break;
+
+ case Iop_Xor32:
+ case Iop_Xor64:
+ aluOp = Malu_XOR;
+ break;
+
+ default:
+ aluOp = Malu_INVALID;
+ break;
+ }
+
+ /* For commutative ops we assume any literal
+ values are on the second operand. */
+ if (aluOp != Malu_INVALID) {
+ HReg r_dst = newVRegI(env);
+ HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ MIPSRH *ri_srcR = NULL;
+ /* get right arg into an RH, in the appropriate way */
+ switch (aluOp) {
+ case Malu_ADD:
+ case Malu_SUB:
+ ri_srcR = iselWordExpr_RH(env, True /*signed */ ,
+ e->Iex.Binop.arg2);
+ break;
+ case Malu_AND:
+ case Malu_OR:
+ case Malu_XOR:
+ ri_srcR = iselWordExpr_RH(env, False /*unsigned */,
+ e->Iex.Binop.arg2);
+ break;
+ default:
+ vpanic("iselWordExpr_R_wrk-aluOp-arg2");
+ }
+ addInstr(env, MIPSInstr_Alu(aluOp, r_dst, r_srcL, ri_srcR));
+ return r_dst;
+ }
+
+ /* a shift? */
+ switch (e->Iex.Binop.op) {
+ case Iop_Shl32:
+ case Iop_Shl64:
+ shftOp = Mshft_SLL;
+ break;
+ case Iop_Shr32:
+ case Iop_Shr64:
+ shftOp = Mshft_SRL;
+ break;
+ case Iop_Sar32:
+ case Iop_Sar64:
+ shftOp = Mshft_SRA;
+ break;
+ default:
+ shftOp = Mshft_INVALID;
+ break;
+ }
+
+ /* we assume any literal values are on the second operand. */
+ if (shftOp != Mshft_INVALID) {
+ HReg r_dst = newVRegI(env);
+ HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ MIPSRH *ri_srcR = NULL;
+ /* get right arg into an RH, in the appropriate way */
+ switch (shftOp) {
+ case Mshft_SLL:
+ case Mshft_SRL:
+ case Mshft_SRA:
+ ri_srcR = iselWordExpr_RH5u(env, e->Iex.Binop. arg2);
+ break;
+ default:
+ vpanic("iselIntExpr_R_wrk-shftOp-arg2");
+ }
+ /* widen the left arg if needed */
+ /*TODO do we need this? */
+ if (ty == Ity_I8 || ty == Ity_I16)
+ goto irreducible;
+ if (ty == Ity_I64) {
+ vassert(mode64);
+ addInstr(env, MIPSInstr_Shft(shftOp, False/*64bit shift */,
+ r_dst, r_srcL, ri_srcR));
+ } else {
+ addInstr(env, MIPSInstr_Shft(shftOp, True /*32bit shift */,
+ r_dst, r_srcL, ri_srcR));
+ }
+ return r_dst;
+ }
+
+ /* Cmp*32*(x,y) ? */
+ if (e->Iex.Binop.op == Iop_CmpEQ32
+ || e->Iex.Binop.op == Iop_CmpNE32
+ || e->Iex.Binop.op == Iop_CmpNE64
+ || e->Iex.Binop.op == Iop_CmpLT32S
+ || e->Iex.Binop.op == Iop_CmpLT32U
+ || e->Iex.Binop.op == Iop_CmpLT64U
+ || e->Iex.Binop.op == Iop_CmpLE32S
+ || e->Iex.Binop.op == Iop_CmpLE64S
+ || e->Iex.Binop.op == Iop_CmpLT64S
+ || e->Iex.Binop.op == Iop_CmpEQ64) {
+
+ Bool syned = (e->Iex.Binop.op == Iop_CmpLT32S
+ || e->Iex.Binop.op == Iop_CmpLE32S
+ || e->Iex.Binop.op == Iop_CmpLT64S
+ || e->Iex.Binop.op == Iop_CmpLE64S);
+ Bool size32;
+ HReg dst = newVRegI(env);
+ HReg r1 = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ HReg r2 = iselWordExpr_R(env, e->Iex.Binop.arg2);
+
+ MIPSCondCode cc;
+
+ switch (e->Iex.Binop.op) {
+ case Iop_CmpEQ32:
+ cc = MIPScc_EQ;
+ size32 = True;
+ break;
+ case Iop_CmpNE32:
+ cc = MIPScc_NE;
+ size32 = True;
+ break;
+ case Iop_CmpNE64:
+ cc = MIPScc_NE;
+ size32 = True;
+ break;
+ case Iop_CmpLT32S:
+ cc = MIPScc_LT;
+ size32 = True;
+ break;
+ case Iop_CmpLT32U:
+ cc = MIPScc_LO;
+ size32 = True;
+ break;
+ case Iop_CmpLT64U:
+ cc = MIPScc_LO;
+ size32 = False;
+ break;
+ case Iop_CmpLE32S:
+ cc = MIPScc_LE;
+ size32 = True;
+ break;
+ case Iop_CmpLE64S:
+ cc = MIPScc_LE;
+ size32 = False;
+ break;
+ case Iop_CmpLT64S:
+ cc = MIPScc_LT;
+ size32 = False;
+ break;
+ case Iop_CmpEQ64:
+ cc = MIPScc_EQ;
+ size32 = False;
+ break;
+ default:
+ vpanic
+ ("iselCondCode(mips): CmpXX32 or CmpXX64");
+ }
+
+ addInstr(env, MIPSInstr_Cmp(syned, size32, dst, r1, r2, cc));
+ return dst;
+ }
+
+ if (e->Iex.Binop.op == Iop_Max32U) {
+ /*
+ tmp = argR - argL;
+ dst = argL;
+ bltz tmp,2;
+ dst = argR;
+
+ */
+ HReg argL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ MIPSRH *argR = iselWordExpr_RH(env, False /*signed */ ,
+ e->Iex.Binop.arg2);
+ HReg dst = newVRegI(env);
+ HReg tmp = newVRegI(env);
+ addInstr(env, MIPSInstr_Alu(Malu_SUB, tmp, argL, argR));
+ addInstr(env, MIPSInstr_MovCond(dst, argL, argR, tmp,
MIPScc_MI));
+
+ return dst;
+ }
+
+ if (e->Iex.Binop.op == Iop_Mul32 || e->Iex.Binop.op == Iop_Mul64)
{
+ Bool sz32 = (e->Iex.Binop.op == Iop_Mul32);
+ HReg r_dst = newVRegI(env);
+ HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);
+ addInstr(env, MIPSInstr_Mul(False/*Unsigned or Signed */ ,
+ False /*widen */ ,
+ sz32 /*32bit or 64bit */,
+ r_dst, r_srcL, r_srcR));
+ return r_dst;
+ }
+
+ if (e->Iex.Binop.op == Iop_MullU32 || e->Iex.Binop.op ==
Iop_MullS32) {
+ HReg r_dst = newVRegI(env);
+ HReg tHi = newVRegI(env);
+ HReg tLo = newVRegI(env);
+ HReg tLo_1 = newVRegI(env);
+ HReg tHi_1 = newVRegI(env);
+ HReg mask = newVRegI(env);
+
+ Bool syned = toBool(e->Iex.Binop.op == Iop_MullS32);
+ Bool size = toBool(e->Iex.Binop.op == Iop_MullS32)
+ || toBool(e->Iex.Binop.op == Iop_MullU32);
+ HReg r_srcL = iselWordExpr_R(env, e->Iex.Binop.arg1);
+ HReg r_srcR = iselWordExpr_R(env, e->Iex.Binop.arg2);
+ addInstr(env, MIPSInstr_Mul(syned /*Unsigned or Signed */ ,
+ True /*widen */ ,
+ size /*32bit or 64bit mul */ ,
+ r_dst, r_srcL, r_srcR));
+
+ addInstr(env, MIPSInstr_Mfhi(tHi));
+ addInstr(env, MIPSInstr_Mflo(tLo));
+
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, False, tHi_1,
+ tHi, MIPSRH_Imm(False, 32)));
+
+ addInstr(env, MIPSInstr_LI(mask, 0xffffffff));
+ addInstr(env, MIPSInstr_Alu(Malu_AND, tLo_1, tLo,
+ MIPSRH_Reg(mask)));
+
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_dst, tHi_1,
+ MIPSRH_Reg(tLo_1)));
+
+ return r_dst;
+ }
+
+ if (e->Iex.Binop.op == Iop_CmpF64) {
+ HReg r_srcL, r_srcR;
+ {
+ r_srcL = iselDblExpr(env, e->Iex.Binop.arg1);
+ r_srcR = iselDblExpr(env, e->Iex.Binop.arg2);
+ }
+ HReg tmp = newVRegI(env);
+ HReg r_ccMIPS = newVRegI(env);
+ HReg r_ccIR = newVRegI(env);
+ HReg r_ccIR_b0 = newVRegI(env);
+ HReg r_ccIR_b2 = newVRegI(env);
+ HReg r_ccIR_b6 = newVRegI(env);
+
+ /* Create in dst, the IRCmpF64Result encoded result. */
+ // chech for EQ
+ addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR,
+ toUChar(2)));
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, r_ccMIPS, tmp,
+ MIPSRH_Imm(False, 22)));
+ // chech for UN
+ addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR,
+ toUChar(1)));
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp,
+ MIPSRH_Imm(False, 23)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS,
+ MIPSRH_Reg(tmp)));
+ // chech for LT
+ addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR,
+ toUChar(12)));
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp,
+ tmp, MIPSRH_Imm(False, 21)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS,
+ MIPSRH_Reg(tmp)));
+ // chech for GT
+ addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR,
+ toUChar(15)));
+ addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp,
+ MIPSRH_Imm(False, 20)));
+
+ addInstr(env, MIPSInstr_Alu(Malu_NOR, tmp, tmp,
MIPSRH_Reg(tmp)));
+ addInstr(env, MIPSInstr_Alu(Malu_AND, tmp, tmp,
+ MIPSRH_Imm(False, 8)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS,
+ MIPSRH_Reg(tmp)));
+ /* Map compare result from PPC to IR,
+ conforming to CmpF64 definition. */
+ /*
+ FP cmp result | MIPS | IR
+ --------------------------
+ UN | 0x1 | 0x45
+ EQ | 0x2 | 0x40
+ GT | 0x4 | 0x00
+ LT | 0x8 | 0x01
+ */
+
+ // r_ccIR_b0 = r_ccPPC[0] | r_ccPPC[3]
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True, r_ccIR_b0,
r_ccMIPS,
+ MIPSRH_Imm(False, 0x3)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR_b0, r_ccMIPS,
+ MIPSRH_Reg(r_ccIR_b0)));
+ addInstr(env, MIPSInstr_Alu(Malu_AND, r_ccIR_b0, r_ccIR_b0,
+ MIPSRH_Imm(False, 0x1)));
+
+ // r_ccIR_b2 = r_ccPPC[0]
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccIR_b2,
r_ccMIPS,
+ MIPSRH_Imm(False, 0x2)));
+ addInstr(env, MIPSInstr_Alu(Malu_AND, r_ccIR_b2, r_ccIR_b2,
+ MIPSRH_Imm(False, 0x4)));
+
+ // r_ccIR_b6 = r_ccPPC[0] | r_ccPPC[1]
+ addInstr(env, MIPSInstr_Shft(Mshft_SRL, True, r_ccIR_b6,
+ r_ccMIPS, MIPSRH_Imm(False, 0x1)));
+ addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccIR_b6, r_ccMIPS,
+ MIPSRH_Reg(r_ccIR_b6)));
+ addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccIR_b6,
r_ccIR_b6,
+ MIPSRH_Imm(False, 0x6)));
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/ir_inject.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,267 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+/*---------------------------------------------------------------*/
+/*--- begin ir_inject.c ---*/
+/*---------------------------------------------------------------*/
+
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2012-2012 Florian Krohm (bri...@acm.org)
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "libvex_basictypes.h"
+#include "libvex_ir.h"
+#include "libvex.h"
+#include "main_util.h"
+
+/* Convenience macros for readibility */
+#define mkU8(v) IRExpr_Const(IRConst_U8(v))
+#define mkU32(v) IRExpr_Const(IRConst_U32(v))
+#define mkU64(v) IRExpr_Const(IRConst_U64(v))
+#define unop(kind, a) IRExpr_Unop(kind, a)
+#define binop(kind, a1, a2) IRExpr_Binop(kind, a1, a2)
+#define triop(kind, a1, a2, a3) IRExpr_Triop(kind, a1, a2, a3)
+#define qop(kind, a1, a2, a3, a4) IRExpr_Qop(kind, a1, a2, a3, a4)
+#define stmt(irsb, st) addStmtToIRSB(irsb, st)
+
+
+/* The IR Injection Control Block. vex_inject_ir will query its contents
+ to construct IR statements for testing purposes. */
+static IRICB iricb;
+
+
+void
+LibVEX_InitIRI(const IRICB *iricb_in)
+{
+ iricb = *iricb_in; // copy in
+}
+
+
+static IRExpr *
+load_aux(IREndness endian, IRType type, IRExpr *addr)
+{
+ if (type == Ity_D64) {
+ /* The insn selectors do not support loading a DFP value from memory.
+ So we need to fix it here by loading an integer value and
+ reinterpreting it as DFP. */
+ return unop(Iop_ReinterpI64asD64,
+ IRExpr_Load(endian, Ity_I64, addr));
+ }
+ if (type == Ity_I1) {
+ /* A Boolean value is stored as a 32-bit entity (see store_aux). */
+ return unop(Iop_32to1, IRExpr_Load(endian, Ity_I32, addr));
+ }
+
+ return IRExpr_Load(endian, type, addr);
+}
+
+
+/* Load a value from memory. Loads of more than 8 byte are split into
+ a series of 8-byte loads and combined using appropriate IROps. */
+static IRExpr *
+load(IREndness endian, IRType type, HWord haddr)
+{
+ IROp concat;
+ IRExpr *addr, *next_addr;
+
+ vassert(type == Ity_I1 || sizeofIRType(type) <= 16);
+
+ if (VEX_HOST_WORDSIZE == 8) {
+ addr = mkU64(haddr);
+ next_addr = binop(Iop_Add64, addr, mkU64(8));
+ } else if (VEX_HOST_WORDSIZE == 4) {
+ addr = mkU32(haddr);
+ next_addr = binop(Iop_Add32, addr, mkU32(8));
+ } else {
+ vpanic("invalid #bytes for address");
+ }
+
+ switch (type) {
+ case Ity_I128: concat = Iop_64HLto128; type = Ity_I64; goto load128;
+ case Ity_F128: concat = Iop_F64HLtoF128; type = Ity_F64; goto load128;
+ case Ity_D128: concat = Iop_D64HLtoD128; type = Ity_D64; goto load128;
+
+ load128:
+ /* Two loads of 64 bit each. */
+ if (endian == Iend_BE) {
+ /* The more significant bits are at the lower address. */
+ return binop(concat,
+ load_aux(endian, type, addr),
+ load_aux(endian, type, next_addr));
+ } else {
+ /* The more significant bits are at the higher address. */
+ return binop(concat,
+ load_aux(endian, type, next_addr),
+ load_aux(endian, type, addr));
+ }
+
+ default:
+ return load_aux(endian, type, addr);
+ }
+}
+
+
+static void
+store_aux(IRSB *irsb, IREndness endian, IRExpr *addr, IRExpr *data)
+{
+ if (typeOfIRExpr(irsb->tyenv, data) == Ity_D64) {
+ /* The insn selectors do not support writing a DFP value to memory.
+ So we need to fix it here by reinterpreting the DFP value as an
+ integer and storing that. */
+ data = unop(Iop_ReinterpD64asI64, data);
+ }
+ if (typeOfIRExpr(irsb->tyenv, data) == Ity_I1) {
+ /* We cannot store a single bit. So we store it in a 32-bit
container.
+ See also load_aux. */
+ data = unop(Iop_1Uto32, data);
+ }
+ stmt(irsb, IRStmt_Store(endian, addr, data));
+}
+
+
+/* Store a value to memory. If a value requires more than 8 bytes a series
+ of 8-byte loads will be generated. */
+static void __inline__
+store(IRSB *irsb, IREndness endian, HWord haddr, IRExpr *data)
+{
+ IROp high, low;
+ IRExpr *addr, *next_addr;
+
+ if (VEX_HOST_WORDSIZE == 8) {
+ addr = mkU64(haddr);
+ next_addr = binop(Iop_Add64, addr, mkU64(8));
+ } else if (VEX_HOST_WORDSIZE == 4) {
+ addr = mkU32(haddr);
+ next_addr = binop(Iop_Add32, addr, mkU32(8));
+ } else {
+ vpanic("invalid #bytes for address");
+ }
+
+ IRType type = typeOfIRExpr(irsb->tyenv, data);
+
+ vassert(type == Ity_I1 || sizeofIRType(type) <= 16);
+
+ switch (type) {
+ case Ity_I128: high = Iop_128HIto64; low = Iop_128to64; goto
store128;
+ case Ity_F128: high = Iop_F128HItoF64; low = Iop_F128LOtoF64; goto
store128;
+ case Ity_D128: high = Iop_D128HItoD64; low = Iop_D128LOtoD64; goto
store128;
+
+ store128:
+ /* Two stores of 64 bit each. */
+ if (endian == Iend_BE) {
+ /* The more significant bits are at the lower address. */
+ store_aux(irsb, endian, addr, unop(high, data));
+ store_aux(irsb, endian, next_addr, unop(low, data));
+ } else {
+ /* The more significant bits are at the higher address. */
+ store_aux(irsb, endian, addr, unop(low, data));
+ store_aux(irsb, endian, next_addr, unop(high, data));
+ }
+ return;
+
+ default:
+ store_aux(irsb, endian, addr, data);
+ return;
+ }
+}
+
+
+/* Inject IR stmts depending on the data provided in the control
+ block iricb. */
+void
+vex_inject_ir(IRSB *irsb, IREndness endian)
+{
+ IRExpr *data, *rounding_mode, *opnd1, *opnd2, *opnd3, *opnd4;
+
+ rounding_mode = NULL;
+ if (iricb.rounding_mode != NO_ROUNDING_MODE) {
+ rounding_mode = mkU32(iricb.rounding_mode);
+ }
+
+ switch (iricb.num_operands) {
+ case 1:
+ opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
+ if (rounding_mode)
+ data = binop(iricb.op, rounding_mode, opnd1);
+ else
+ data = unop(iricb.op, opnd1);
+ break;
+
+ case 2:
+ opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
+
+ if (iricb.shift_amount_is_immediate) {
+ // This implies that the IROp is a shift op
+ vassert(iricb.t_opnd2 == Ity_I8);
+ opnd2 = mkU8(*((Char *)iricb.opnd2));
+ } else {
+ opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
+ }
+
+ if (rounding_mode)
+ data = triop(iricb.op, rounding_mode, opnd1, opnd2);
+ else
+ data = binop(iricb.op, opnd1, opnd2);
+ break;
+
+ case 3:
+ opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
+ opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
+ opnd3 = load(endian, iricb.t_opnd3, iricb.opnd3);
+ if (rounding_mode)
+ data = qop(iricb.op, rounding_mode, opnd1, opnd2, opnd3);
+ else
+ data = triop(iricb.op, opnd1, opnd2, opnd3);
+ break;
+
+ case 4:
+ vassert(rounding_mode == NULL);
+ opnd1 = load(endian, iricb.t_opnd1, iricb.opnd1);
+ opnd2 = load(endian, iricb.t_opnd2, iricb.opnd2);
+ opnd3 = load(endian, iricb.t_opnd3, iricb.opnd3);
+ opnd4 = load(endian, iricb.t_opnd4, iricb.opnd4);
+ data = qop(iricb.op, opnd1, opnd2, opnd3, opnd4);
+ break;
+
+ default:
+ vpanic("unsupported operator");
+ }
+
+ store(irsb, endian, iricb.result, data);
+
+ if (0) {
+ vex_printf("BEGIN inject\n");
+ if (sizeofIRType(iricb.t_result) <= 8) {
+ ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
+ } else if (sizeofIRType(iricb.t_result) == 16) {
+ ppIRStmt(irsb->stmts[irsb->stmts_used - 2]);
+ vex_printf("\n");
+ ppIRStmt(irsb->stmts[irsb->stmts_used - 1]);
+ }
+ vex_printf("\nEND inject\n");
+ }
+}
+
+/*---------------------------------------------------------------*/
+/*--- end ir_inject.c ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/s390_disasm.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,461 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+/*---------------------------------------------------------------*/
+/*--- begin s390_disasm.c ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright IBM Corp. 2010-2012
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+/* Contributed by Florian Krohm */
+
+#include <stdarg.h>
+#include "libvex_basictypes.h"
+#include "main_util.h" // vassert
+#include "main_globals.h" // vex_traceflags
+#include "s390_disasm.h"
+
+/* The format that is used to write out a mnemonic. */
+static const HChar s390_mnm_fmt[] = "%-8s";
+
+
+/* Return the name of a general purpose register for dis-assembly
purposes. */
+static const HChar *
+gpr_operand(UInt archreg)
+{
+ static const HChar names[16][5] = {
+ "%r0", "%r1", "%r2", "%r3",
+ "%r4", "%r5", "%r6", "%r7",
+ "%r8", "%r9", "%r10", "%r11",
+ "%r12", "%r13", "%r14", "%r15",
+ };
+
+ vassert(archreg < 16);
+
+ return names[archreg];
+}
+
+
+/* Return the name of a floating point register for dis-assembly purposes.
*/
+static const HChar *
+fpr_operand(UInt archreg)
+{
+ static const HChar names[16][5] = {
+ "%f0", "%f1", "%f2", "%f3",
+ "%f4", "%f5", "%f6", "%f7",
+ "%f8", "%f9", "%f10", "%f11",
+ "%f12", "%f13", "%f14", "%f15",
+ };
+
+ vassert(archreg < 16);
+
+ return names[archreg];
+}
+
+
+/* Return the name of an access register for dis-assembly purposes. */
+static const HChar *
+ar_operand(UInt archreg)
+{
+ static const HChar names[16][5] = {
+ "%a0", "%a1", "%a2", "%a3",
+ "%a4", "%a5", "%a6", "%a7",
+ "%a8", "%a9", "%a10", "%a11",
+ "%a12", "%a13", "%a14", "%a15",
+ };
+
+ vassert(archreg < 16);
+
+ return names[archreg];
+}
+
+
+/* Build and return the extended mnemonic for the compare and branch
+ opcodes as introduced by z10. See also the opcodes in file
+ opcodes/s390-opc.txt (from binutils) that have a '$' in their name. */
+static const HChar *
+cab_operand(const HChar *base, UInt mask)
+{
+ HChar *to;
+ const HChar *from;
+
+ static HChar buf[10]; /* Maximum is 6 + 2 */
+
+ static const HChar *suffix[] = {
+ "", "h", "l", "ne", "e", "nl", "nh", ""
+ };
+
+ /* strcpy(buf, from); */
+ for (from = base, to = buf; *from; ++from, ++to) {
+ *to = *from;
+ }
+ /* strcat(buf, suffix); */
+ for (from = suffix[mask >> 1]; *from; ++from, ++to) {
+ *to = *from;
+ }
+ *to = '\0';
+
+ return buf;
+}
+
+/* Common function used to construct a mnemonic based on a condition code
+ mask. */
+static const HChar *
+construct_mnemonic(const HChar *prefix, const HChar *suffix, UInt mask)
+{
+ HChar *to;
+ const HChar *from;
+
+ static HChar buf[10];
+
+ static HChar mask_id[16][4] = {
+ "", /* 0 -> unused */
+ "o", "h", "nle", "l", "nhe", "lh", "ne",
+ "e", "nlh", "he", "nl", "le", "nh", "no",
+ "" /* 15 -> unused */
+ };
+
+ /* Guard against buffer overflow */
+ vassert(vex_strlen(prefix) + vex_strlen(suffix) + sizeof mask_id[0] <=
sizeof buf);
+
+ /* strcpy(buf, prefix); */
+ for (from = prefix, to = buf; *from; ++from, ++to) {
+ *to = *from;
+ }
+ /* strcat(buf, mask_id); */
+ for (from = mask_id[mask]; *from; ++from, ++to) {
+ *to = *from;
+ }
+ /* strcat(buf, suffix); */
+ for (from = suffix; *from; ++from, ++to) {
+ *to = *from;
+ }
+ *to = '\0';
+
+ return buf;
+}
+
+
+/* Return the special mnemonic for the BCR opcode */
+static const HChar *
+bcr_operand(UInt m1)
+{
+ if (m1 == 0) return "nopr";
+ if (m1 == 15) return "br";
+
+ return construct_mnemonic("b", "r", m1);
+}
+
+
+/* Return the special mnemonic for the BC opcode */
+static const HChar *
+bc_operand(UInt m1)
+{
+ if (m1 == 0) return "nop";
+ if (m1 == 15) return "b";
+
+ return construct_mnemonic("b", "", m1);
+}
+
+
+/* Return the special mnemonic for the BRC opcode */
+static const HChar *
+brc_operand(UInt m1)
+{
+ if (m1 == 0) return "brc";
+ if (m1 == 15) return "j";
+
+ return construct_mnemonic("j", "", m1);
+}
+
+
+/* Return the special mnemonic for the BRCL opcode */
+static const HChar *
+brcl_operand(UInt m1)
+{
+ if (m1 == 0) return "brcl";
+ if (m1 == 15) return "jg";
+
+ return construct_mnemonic("jg", "", m1);
+}
+
+
+/* Return the special mnemonic for a conditional load/store opcode */
+static const HChar *
+cls_operand(Int kind, UInt mask)
+{
+ const HChar *prefix;
+
+ switch (kind) {
+ case S390_XMNM_LOCR: prefix = "locr"; break;
+ case S390_XMNM_LOCGR: prefix = "locgr"; break;
+ case S390_XMNM_LOC: prefix = "loc"; break;
+ case S390_XMNM_LOCG: prefix = "locg"; break;
+ case S390_XMNM_STOC: prefix = "stoc"; break;
+ case S390_XMNM_STOCG: prefix = "stocg"; break;
+ default:
+ vpanic("cls_operand");
+ }
+
+ return construct_mnemonic(prefix, "", mask);
+}
+
+
+/* An operand with a base register, an index register, and a displacement.
+ If the displacement is signed, the rightmost 20 bit of D need to be
+ sign extended */
+static HChar *
+dxb_operand(HChar *p, UInt d, UInt x, UInt b, Bool displacement_is_signed)
+{
+ if (displacement_is_signed) {
+ Int displ = ((Int)d << 12) >> 12; /* sign extend */
+
+ p += vex_sprintf(p, "%d", displ);
+ } else {
+ p += vex_sprintf(p, "%u", d);
+ }
+ if (x != 0) {
+ p += vex_sprintf(p, "(%s", gpr_operand(x));
+ if (b != 0) {
+ p += vex_sprintf(p, ",%s", gpr_operand(b));
+ }
+ p += vex_sprintf(p, ")");
+ } else {
+ if (b != 0) {
+ p += vex_sprintf(p, "(%s)", gpr_operand(b));
+ }
+ }
+
+ return p;
+}
+
+
+/* An operand with base register, unsigned length, and a 12-bit
+ unsigned displacement */
+static HChar *
+udlb_operand(HChar *p, UInt d, UInt length, UInt b)
+{
+ p += vex_sprintf(p, "%u", d);
+ p += vex_sprintf(p, "(%u", length + 1); // actual length is +1
+ if (b != 0) {
+ p += vex_sprintf(p, ",%s", gpr_operand(b));
+ }
+ p += vex_sprintf(p, ")");
+
+ return p;
+}
+
+
+/* The first argument is the command that says how to write the
disassembled
+ insn. It is understood that the mnemonic comes first and that arguments
+ are separated by a ','. The command holds the arguments. Each argument
is
+ encoded using a 4-bit S390_ARG_xyz value. The first argument is placed
+ in the least significant bits of the command and so on. There are at
most
+ 5 arguments in an insn and a sentinel (S390_ARG_DONE) is needed to
identify
+ the end of the argument list. 6 * 4 = 24 bits are required for the
+ command. */
+void
+s390_disasm(UInt command, ...)
+{
+ va_list args;
+ unsigned argkind;
+ HChar buf[128]; /* holds the disassembled insn */
+ HChar *p;
+ HChar separator;
+ Int mask_suffix = -1;
+
+ va_start(args, command);
+
+ p = buf;
+ separator = 0;
+
+ while (42) {
+ argkind = command & 0xF;
+ command >>= 4;
+
+ if (argkind == S390_ARG_DONE) goto done;
+
+ if (argkind == S390_ARG_CABM) separator = 0; /* optional */
+
+ /* Write out the separator */
+ if (separator) *p++ = separator;
+
+ /* argument */
+ switch (argkind) {
+ case S390_ARG_MNM:
+ p += vex_sprintf(p, s390_mnm_fmt, va_arg(args, HChar *));
+ separator = ' ';
+ continue;
+
+ case S390_ARG_XMNM: {
+ UInt mask, kind;
+ const HChar *mnm;
+
+ kind = va_arg(args, UInt);
+
+ separator = ' ';
+ switch (kind) {
+ case S390_XMNM_BC:
+ case S390_XMNM_BCR:
+ mask = va_arg(args, UInt);
+ mnm = kind == S390_XMNM_BCR ? bcr_operand(mask) :
bc_operand(mask);
+ p += vex_sprintf(p, s390_mnm_fmt, mnm);
+ /* mask == 0 is a NOP and has no argument */
+ if (mask == 0) goto done;
+ break;
+
+ case S390_XMNM_BRC:
+ case S390_XMNM_BRCL:
+ mask = va_arg(args, UInt);
+ mnm = kind == S390_XMNM_BRC ? brc_operand(mask) :
brcl_operand(mask);
+ p += vex_sprintf(p, s390_mnm_fmt, mnm);
+
+ /* mask == 0 has no special mnemonic */
+ if (mask == 0) {
+ p += vex_sprintf(p, " 0");
+ separator = ',';
+ }
+ break;
+
+ case S390_XMNM_CAB:
+ mnm = va_arg(args, HChar *);
+ mask = va_arg(args, UInt);
+ p += vex_sprintf(p, s390_mnm_fmt, cab_operand(mnm, mask));
+ break;
+
+ case S390_XMNM_LOCR:
+ case S390_XMNM_LOCGR:
+ case S390_XMNM_LOC:
+ case S390_XMNM_LOCG:
+ case S390_XMNM_STOC:
+ case S390_XMNM_STOCG:
+ mask = va_arg(args, UInt);
+ mnm = cls_operand(kind, mask);
+ p += vex_sprintf(p, s390_mnm_fmt, mnm);
+ /* There are no special opcodes when mask == 0 or 15. In that
case
+ the integer mask is appended as the final operand */
+ if (mask == 0 || mask == 15) mask_suffix = mask;
+ break;
+ }
+ }
+ continue;
+
+ case S390_ARG_GPR:
+ p += vex_sprintf(p, "%s", gpr_operand(va_arg(args, UInt)));
+ break;
+
+ case S390_ARG_FPR:
+ p += vex_sprintf(p, "%s", fpr_operand(va_arg(args, UInt)));
+ break;
+
+ case S390_ARG_AR:
+ p += vex_sprintf(p, "%s", ar_operand(va_arg(args, UInt)));
+ break;
+
+ case S390_ARG_UINT:
+ p += vex_sprintf(p, "%u", va_arg(args, UInt));
+ break;
+
+ case S390_ARG_INT:
+ p += vex_sprintf(p, "%d", (Int)(va_arg(args, UInt)));
+ break;
+
+ case S390_ARG_PCREL: {
+ Int offset = (Int)(va_arg(args, UInt));
+
+ /* Convert # halfwords to # bytes */
+ offset <<= 1;
+
+ if (offset < 0) {
+ p += vex_sprintf(p, ".%d", offset);
+ } else {
+ p += vex_sprintf(p, ".+%u", offset);
+ }
+ break;
+ }
+
+ case S390_ARG_SDXB: {
+ UInt dh, dl, x, b;
+
+ dh = va_arg(args, UInt);
+ dl = va_arg(args, UInt);
+ x = va_arg(args, UInt);
+ b = va_arg(args, UInt);
+
+ p = dxb_operand(p, (dh << 12) | dl, x, b, 1 /*
signed_displacement */);
+ break;
+ }
+
+ case S390_ARG_UDXB: {
+ UInt d, x, b;
+
+ d = va_arg(args, UInt);
+ x = va_arg(args, UInt);
+ b = va_arg(args, UInt);
+
+ p = dxb_operand(p, d, x, b, 0 /* signed_displacement */);
+ break;
+ }
+
+ case S390_ARG_UDLB: {
+ UInt d, l, b;
+
+ d = va_arg(args, UInt);
+ l = va_arg(args, UInt);
+ b = va_arg(args, UInt);
+
+ p = udlb_operand(p, d, l, b);
+ break;
+ }
+
+ case S390_ARG_CABM: {
+ UInt mask;
+
+ mask = va_arg(args, UInt) & 0xE;
+ if (mask == 0 || mask == 14) {
+ p += vex_sprintf(p, ",%u", mask);
+ }
+ break;
+ }
+ }
+
+ separator = ',';
+ }
+
+ done:
+ va_end(args);
+
+ if (mask_suffix != -1)
+ p += vex_sprintf(p, ",%d", mask_suffix);
+ *p = '\0';
+
+ vassert(p < buf + sizeof buf); /* detect buffer overwrite */
+
+ /* Finally, write out the disassembled insn */
+ vex_printf("%s\n", buf);
+}
+
+/*---------------------------------------------------------------*/
+/*--- end s390_disasm.c ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/priv/s390_disasm.h Thu Nov 22 04:55:39 2012
@@ -0,0 +1,93 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+/*---------------------------------------------------------------*/
+/*--- begin s390_disasm.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright IBM Corp. 2010-2012
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __VEX_S390_DISASM_H
+#define __VEX_S390_DISASM_H
+
+#include "libvex_basictypes.h"
+
+/* Macros to encode a command for s390_disasm. */
+#undef P
+#define P(a) (S390_ARG_##a)
+#undef ENC1
+#define ENC1(a) ((P(DONE) << 4) | P(a))
+#undef ENC2
+#define ENC2(a,b) ((P(DONE) << 8) | (P(b) << 4) | P(a))
+#undef ENC3
+#define ENC3(a,b,c) ((P(DONE) << 12) | (P(c) << 8) | (P(b) << 4) | P(a))
+#undef ENC4
+#define ENC4(a,b,c,d) ((P(DONE) << 16) | (P(d) << 12) | (P(c) << 8) | \
+ (P(b) << 4) | P(a))
+#undef ENC5
+#define ENC5(a,b,c,d,e) ((P(DONE) << 20) | (P(e) << 16) | (P(d) << 12) | \
+ (P(c) << 8) | (P(b) << 4) | P(a))
+#undef ENC6
+#define ENC6(a,b,c,d,e,f) ((P(DONE) << 24) | (P(f) << 20) | (P(e) << 16) |
\
+ (P(d) << 12) | (P(c) << 8) | (P(b) << 4) | P(a))
+
+/* The different kinds of operands in an asm insn */
+enum {
+ S390_ARG_DONE = 0,
+ S390_ARG_GPR = 1,
+ S390_ARG_FPR = 2,
+ S390_ARG_AR = 3,
+ S390_ARG_INT = 4,
+ S390_ARG_UINT = 5,
+ S390_ARG_PCREL = 6,
+ S390_ARG_SDXB = 7,
+ S390_ARG_UDXB = 8,
+ S390_ARG_UDLB = 9,
+ S390_ARG_CABM = 10,
+ S390_ARG_MNM = 11,
+ S390_ARG_XMNM = 12
+};
+
+/* The different kinds of extended mnemonics */
+enum {
+ S390_XMNM_CAB = 0,
+ S390_XMNM_BCR = 1,
+ S390_XMNM_BC = 2,
+ S390_XMNM_BRC = 3,
+ S390_XMNM_BRCL = 4,
+ S390_XMNM_LOCR = 5,
+ S390_XMNM_LOCGR = 6,
+ S390_XMNM_LOC = 7,
+ S390_XMNM_LOCG = 8,
+ S390_XMNM_STOC = 9,
+ S390_XMNM_STOCG = 10
+};
+
+void s390_disasm(UInt command, ...);
+
+/*---------------------------------------------------------------*/
+/*--- end s390_disasm.h ---*/
+/*---------------------------------------------------------------*/
+
+#endif /* __VEX_S390_DISASM_H */
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/pub/libvex_emnote.h Thu Nov 22 04:55:39 2012
@@ -0,0 +1,123 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin libvex_emnote.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2004-2012 OpenWorks LLP
+ in...@open-works.net
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+
+ Neither the names of the U.S. Department of Energy nor the
+ University of California nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without prior written permission.
+*/
+
+#ifndef __LIBVEX_EMNOTE_H
+#define __LIBVEX_EMNOTE_H
+
+#include "libvex_basictypes.h"
+
+/* VEX can sometimes generate code which returns to the dispatcher
+ with the guest state pointer set to VEX_TRC_JMP_EMWARN or
+ VEX_TRC_JMP_EMFAIL. This means that VEX is trying to tell Valgrind
+ something noteworthy about emulation progress. For example, that
Valgrind
+ is doing imprecise emulation in some sense. The guest's pseudo-register
+ "guest_EMNOTE" will hold a value of type VexEmNote, which describes
+ the nature of the warning. Currently the limitations that are
+ warned about apply primarily to floating point support.
+
+ All guest states must have a 32-bit (UInt) guest_EMNOTE pseudo-
+ register, that emulation warnings can be written in to.
+
+ Note that guest_EMNOTE only carries a valid value at the jump
+ marked as VEX_TRC_JMP_EMWARN / VEX_TRC_JMP_EMFAIL. You can't assume
+ it will continue to carry a valid value from any amount of time after
+ the jump.
+*/
+
+typedef
+ enum {
+ /* no note indicated */
+ EmNote_NONE=0,
+
+ /* unmasking x87 FP exceptions is not supported */
+ EmWarn_X86_x87exns,
+
+ /* change of x87 FP precision away from 64-bit (mantissa) */
+ EmWarn_X86_x87precision,
+
+ /* unmasking SSE FP exceptions is not supported */
+ EmWarn_X86_sseExns,
+
+ /* setting mxcsr.fz is not supported */
+ EmWarn_X86_fz,
+
+ /* setting mxcsr.daz is not supported */
+ EmWarn_X86_daz,
+
+ /* settings to %eflags.ac (alignment check) are noted but ignored */
+ EmWarn_X86_acFlag,
+
+ /* unmasking PPC32/64 FP exceptions is not supported */
+ EmWarn_PPCexns,
+
+ /* overflow/underflow of the PPC64 _REDIR stack (ppc64 only) */
+ EmWarn_PPC64_redir_overflow,
+ EmWarn_PPC64_redir_underflow,
+
+ /* insn specifies a rounding mode other than "according to FPC"
+ which requires the floating point extension facility. But that
+ facility is not available on this host */
+ EmWarn_S390X_fpext_rounding,
+
+ /* insn (e.g. srnmb) specifies an invalid rounding mode */
+ EmWarn_S390X_invalid_rounding,
+
+ /* stfle insn is not supported on this host */
+ EmFail_S390X_stfle,
+
+ /* stckf insn is not supported on this host */
+ EmFail_S390X_stckf,
+
+ /* ecag insn is not supported on this host */
+ EmFail_S390X_ecag,
+
+ /* insn needs floating point extension facility which is not
+ available on this host */
+ EmFail_S390X_fpext,
+
+ EmNote_NUMBER
+ }
+ VexEmNote;
+
+
+/* Produces a short string describing the warning. */
+extern const HChar* LibVEX_EmNote_string ( VexEmNote );
+
+
+#endif /* ndef __LIBVEX_EMNOTE_H */
+
+/*---------------------------------------------------------------*/
+/*--- libvex_emnote.h ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/VEX/pub/libvex_guest_mips32.h Thu Nov 22 04:55:39 2012
@@ -0,0 +1,160 @@
+
+/*---------------------------------------------------------------*/
+/*--- begin libvex_guest_mips32.h ---*/
+/*---------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __LIBVEX_PUB_GUEST_MIPS32_H
+#define __LIBVEX_PUB_GUEST_MIPS32_H
+
+#include "libvex_basictypes.h"
+
+
+/*---------------------------------------------------------------*/
+/*--- Vex's representation of the MIPS32 CPU state. ---*/
+/*---------------------------------------------------------------*/
+
+typedef
+ struct {
+ /* CPU Registers */
+ /* 0 */ UInt guest_r0; /* Hardwired to 0 */
+ /* 4 */ UInt guest_r1; /* Assembler temporary */
+ /* 8 */ UInt guest_r2; /* Values for function returns ...*/
+ /* 12 */ UInt guest_r3; /* ...and expression evaluation */
+ /* 16 */ UInt guest_r4; /* Function arguments */
+ /* 20 */ UInt guest_r5;
+ /* 24 */ UInt guest_r6;
+ /* 28 */ UInt guest_r7;
+ /* 32 */ UInt guest_r8; /* Temporaries */
+ /* 36 */ UInt guest_r9;
+ /* 40 */ UInt guest_r10;
+ /* 44 */ UInt guest_r11;
+ /* 48 */ UInt guest_r12;
+ /* 52 */ UInt guest_r13;
+ /* 56 */ UInt guest_r14;
+ /* 60 */ UInt guest_r15;
+ /* 64 */ UInt guest_r16; /* Saved temporaries */
+ /* 68 */ UInt guest_r17;
+ /* 72 */ UInt guest_r18;
+ /* 76 */ UInt guest_r19;
+ /* 80 */ UInt guest_r20;
+ /* 84 */ UInt guest_r21;
+ /* 88 */ UInt guest_r22;
+ /* 92 */ UInt guest_r23;
+ /* 96 */ UInt guest_r24; /* Temporaries */
+ /* 100 */ UInt guest_r25;
+ /* 104 */ UInt guest_r26; /* Reserved for OS kernel */
+ /* 108 */ UInt guest_r27;
+ /* 112 */ UInt guest_r28; /* Global pointer */
+ /* 116 */ UInt guest_r29; /* Stack pointer */
+ /* 120 */ UInt guest_r30; /* Frame pointer */
+ /* 124 */ UInt guest_r31; /* Return address */
+ /* 128 */ UInt guest_PC; /* Program counter */
+ /* 132 */ UInt guest_HI;/* Multiply and divide register higher
result */
+ /* 136 */ UInt guest_LO;/* Multiply and divide register lower
result */
+
+ /* FPU Registers */
+ /* 140 */ UInt guest_f0; /* Floting point general purpose
registers */
+ /* 144 */ UInt guest_f1;
+ /* 148 */ UInt guest_f2;
+ /* 152 */ UInt guest_f3;
+ /* 156 */ UInt guest_f4;
+ /* 160 */ UInt guest_f5;
+ /* 164 */ UInt guest_f6;
+ /* 168 */ UInt guest_f7;
+ /* 172 */ UInt guest_f8;
+ /* 176 */ UInt guest_f9;
+ /* 180 */ UInt guest_f10;
+ /* 184 */ UInt guest_f11;
+ /* 188 */ UInt guest_f12;
+ /* 192 */ UInt guest_f13;
+ /* 196 */ UInt guest_f14;
+ /* 200 */ UInt guest_f15;
+ /* 204 */ UInt guest_f16;
+ /* 208 */ UInt guest_f17;
+ /* 212 */ UInt guest_f18;
+ /* 216 */ UInt guest_f19;
+ /* 220 */ UInt guest_f20;
+ /* 224 */ UInt guest_f21;
+ /* 228 */ UInt guest_f22;
+ /* 232 */ UInt guest_f23;
+ /* 236 */ UInt guest_f24;
+ /* 240 */ UInt guest_f25;
+ /* 244 */ UInt guest_f26;
+ /* 248 */ UInt guest_f27;
+ /* 252 */ UInt guest_f28;
+ /* 256 */ UInt guest_f29;
+ /* 260 */ UInt guest_f30;
+ /* 264 */ UInt guest_f31;
+
+ /* 268 */ UInt guest_FIR;
+ /* 272 */ UInt guest_FCCR;
+ /* 276 */ UInt guest_FEXR;
+ /* 280 */ UInt guest_FENR;
+ /* 284 */ UInt guest_FCSR;
+
+ /* TLS pointer for the thread. It's read-only in user space.
+ On Linux it is set in user space by various thread-related
+ syscalls.
+ User Local Register.
+ This register provides read access to the coprocessor 0
+ UserLocal register, if it is implemented. In some operating
+ environments, the UserLocal register is a pointer to a
+ thread-specific storage block.
+ */
+ /* 288 */ UInt guest_ULR;
+
+ /* Emulation notes */
+ UInt guest_EMNOTE; /* 292 */
+
+ /* For clflush: record start and length of area to invalidate */
+ UInt guest_TISTART; /* 296 */
+ UInt guest_TILEN; /* 300 */
+ UInt guest_NRADDR; /* 304 */
+
+ UInt host_EvC_FAILADDR; /* 308 */
+ UInt host_EvC_COUNTER; /* 312 */
+ UInt guest_COND; /* 316 */
+} VexGuestMIPS32State;
+/*---------------------------------------------------------------*/
+/*--- Utility functions for MIPS32 guest stuff. ---*/
+/*---------------------------------------------------------------*/
+
+/* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
+
+/* Initialise all guest MIPS32 state. */
+
+extern
+void LibVEX_GuestMIPS32_initialise ( /*OUT*/VexGuestMIPS32State* vex_state
);
+
+
+#endif /* ndef __LIBVEX_PUB_GUEST_MIPS32_H */
+
+
+/*---------------------------------------------------------------*/
+/*--- libvex_guest_mips32.h ---*/
+/*---------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/auxprogs/s390-check-opcodes.pl Thu Nov 22 04:55:39 2012
@@ -0,0 +1,168 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+#------------------------------------------------------------------
+# This script assists in updating s390-opcodes.csv
+# It utilizes <binutils>/opcodes/s390-opc.txt and
+# <valgrind>/VEX/priv/guest_s390_toIR.c and will
+# - identify new opcodes that are present in s390-opc.txt
+# (s390-opc.txt is the golden list)
+# - identify opcodes that are implemented in guest_s390_toIR.c
+# but have an out-of-date status in the CSV file.
+#------------------------------------------------------------------
+my $num_arg = $#ARGV + 1;
+
+if ($num_arg != 3) {
+ die "usage: s390-check-opcodes s390-opcodes.csv s390-opc.txt
guest_s390_toIR.c\n";
+}
+
+my $csv_file = $ARGV[0];
+my $opc_file = $ARGV[1];
+my $toir_file = $ARGV[2];
+
+my %opc_desc = ();
+my %csv_desc = ();
+my %csv_implemented = ();
+my %toir_implemented = ();
+
+
+#----------------------------------------------------
+# Read s390-opc.txt (binutils)
+#----------------------------------------------------
+open(OPC, "$opc_file") || die "cannot open $opc_file\n";
+while (my $line = <OPC>) {
+ chomp $line;
+ next if ($line =~ "^[ ]*#"); # comments
+ my $description = (split /"/,$line)[1];
+ my ($encoding,$mnemonic,$format) = split /\s+/,$line;
+
+ # Ignore opcodes that have wildcards in them ('$', '*')
+ # Those provide alternate mnemonics for specific instances of this
opcode
+ next if ($mnemonic =~ /\$/);
+ next if ($mnemonic =~ /\*/);
+
+ # Ignore certain opcodes which are special cases of other opcodes
+ next if ($mnemonic eq "br"); # special case of bcr
+ next if ($mnemonic eq "nopr"); # special case of bcr
+ next if ($mnemonic eq "b"); # special case of bc
+ next if ($mnemonic eq "nop"); # special case of bc
+ next if ($mnemonic eq "j"); # special case of brc
+ next if ($mnemonic eq "jg"); # special case of brcl
+ next if ($mnemonic eq "tmh"); # alternate mnemonic for tmlh
+ next if ($mnemonic eq "tml"); # alternate mnemonic for tmll
+ next if ($mnemonic eq "lrdr"); # alternate mnemonic for ldxr
+ next if ($mnemonic eq "lrer"); # alternate mnemonic for ledr
+ next if ($mnemonic eq "me"); # alternate mnemonic for mde
+ next if ($mnemonic eq "mer"); # alternate mnemonic for mder
+ next if ($mnemonic eq "cuutf"); # alternate mnemonic for cu21
+ next if ($mnemonic eq "cutfu"); # alternate mnemonic for cu12
+
+ $description =~ s/^[\s]+//g; # remove leading blanks
+ $description =~ s/[\s]+$//g; # remove trailing blanks
+ $description =~ s/[ ][ ]+/ /g; # replace multiple blanks with a
single one
+
+
+# Certain opcodes are listed more than once. Let the first description win
+ if ($opc_desc{$mnemonic}) {
+ # already there
+# if ($opc_desc{$mnemonic} ne $description) {
+# print "multiple description for opcode $mnemonic\n";
+# print " old: |" . $opc_desc{$mnemonic} . "|\n";
+# print " new: |" . $description . "|\n";
+# }
+ } else {
+ $opc_desc{$mnemonic} = $description;
+ }
+
+ if ($description =~ /,/) {
+ print "warning: description of $mnemonic contains comma\n";
+ }
+}
+close(OPC);
+
+#----------------------------------------------------
+# Read CSV file (valgrind)
+#----------------------------------------------------
+open(CSV, "$csv_file") || die "cannot open $csv_file\n";
+while (my $line = <CSV>) {
+ chomp $line;
+ next if ($line =~ "^[ ]*#"); # comments
+ my ($mnemonic,$description,$status) = split /,/,$line;
+
+ $mnemonic =~ s/"//g;
+ $description =~ s/"//g;
+
+# Complain about duplicate entries. We don't want them.
+ if ($csv_desc{$mnemonic}) {
+ print "$mnemonic: duplicate entry\n";
+ } else {
+ $csv_desc{$mnemonic} = $description;
+ }
+# Remember whether it is implemented or not
+ next if ($line =~ /not\s+implemented/);
+ next if ($line =~ /N\/A/);
+ next if ($line =~ /won't do/);
+ if ($line =~ /implemented/) {
+ $csv_implemented{$mnemonic} = 1;
+ } else {
+ print "*** unknown implementation status of $mnemonic\n";
+ }
+}
+close(CSV);
+
+#----------------------------------------------------
+# Read s390_guest_toIR.c file. Compile list of implemented opcodes
+#----------------------------------------------------
+open(TOIR, "$toir_file") || die "cannot open $toir_file\n";
+while (my $line = <TOIR>) {
+ chomp $line;
+ next if (! ($line =~ /^s390_irgen_[A-Z]/));
+ $line =~ /^s390_irgen_([A-Z][A-Z0-9]*)/;
+ my $op = $1;
+ $op =~ tr/A-Z/a-z/;
+ $toir_implemented{$op} = 1;
+}
+close(TOIR);
+
+#----------------------------------------------------
+# 1) Make sure there are no missing/extra opcodes
+#----------------------------------------------------
+foreach my $opc (keys %opc_desc) {
+ if (! $csv_desc{$opc}) {
+ print "*** opcode $opc not listed in $csv_file\n";
+ }
+}
+foreach my $opc (keys %csv_desc) {
+ if (! $opc_desc{$opc}) {
+ print "*** opcode $opc not listed in $opc_file\n";
+ }
+}
+
+#----------------------------------------------------
+# 2) Make sure opcode descriptions are the same
+#----------------------------------------------------
+foreach my $opc (keys %opc_desc) {
+ if ($opc_desc{$opc} ne $csv_desc{$opc}) {
+ print "*** opcode $opc differs: $opc_desc{$opc}\n";
+ }
+}
+
+#----------------------------------------------------
+# 3) Make sure implemented'ness is correct
+#----------------------------------------------------
+foreach my $opc (keys %toir_implemented) {
+ if (! $csv_implemented{$opc}) {
+ print "*** opcode $opc is implemented but CSV file does not say
so\n";
+ }
+}
+
+foreach my $opc (keys %csv_implemented) {
+ if (! $toir_implemented{$opc}) {
+ print "*** opcode $opc is not implemented but CSV file says so\n";
+ }
+}
+
+print "there are " . int(keys %toir_implemented) . " implemented
opcodes\n";
+exit 0
=======================================
--- /dev/null
+++ /trunk/valgrind/configure.in.orig Thu Nov 22 04:55:39 2012
@@ -0,0 +1,2132 @@
+
+##------------------------------------------------------------##
+#
+# The multiple-architecture stuff in this file is pretty
+# cryptic. Read docs/internals/multiple-architectures.txt
+# for at least a partial explanation of what is going on.
+#
+##------------------------------------------------------------##
+
+# Process this file with autoconf to produce a configure script.
+AC_INIT([Valgrind],[3.8.0.SVN],[valgrin...@lists.sourceforge.net])
+AC_CONFIG_SRCDIR(coregrind/m_main.c)
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([foreign])
+
+AM_MAINTAINER_MODE
+
+#----------------------------------------------------------------------------
+# Checks for various programs.
+#----------------------------------------------------------------------------
+CFLAGS="-Wno-long-long $CFLAGS"
+
+AC_PROG_LN_S
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_CPP
+AC_PROG_CXX
+# AC_PROG_OBJC apparently causes problems on older Linux distros (eg. with
+# autoconf 2.59). If we ever have any Objective-C code in the Valgrind
code
+# base (eg. most likely as Darwin-specific tests) we'll need one of the
+# following:
+# - put AC_PROG_OBJC in a Darwin-specific part of this file
+# - Use AC_PROG_OBJC here and up the minimum autoconf version
+# - Use the following, which is apparently equivalent:
+# m4_ifdef([AC_PROG_OBJC],
+# [AC_PROG_OBJC],
+# [AC_CHECK_TOOL([OBJC], [gcc])
+# AC_SUBST([OBJC])
+# AC_SUBST([OBJCFLAGS])
+# ])
+AC_PROG_RANLIB
+# provide a very basic definition for AC_PROG_SED if it's not provided by
+# autoconf (as e.g. in autoconf 2.59).
+m4_ifndef([AC_PROG_SED],
+ [AC_DEFUN([AC_PROG_SED],
+ [AC_ARG_VAR([SED])
+ AC_CHECK_PROGS([SED],[gsed sed])])])
+AC_PROG_SED
+
+# If no AR variable was specified, look up the name of the archiver.
Otherwise
+# do not touch the AR variable.
+if test "x$AR" = "x"; then
+ AC_PATH_PROGS([AR], [`echo $LD | $SED 's/ld$/ar/'` "ar"], [ar])
+fi
+AC_ARG_VAR([AR],[Archiver command])
+
+# Check for the compiler support
+if test "${GCC}" != "yes" ; then
+ AC_MSG_ERROR([Valgrind relies on GCC to be compiled])
+fi
+
+# figure out where perl lives
+AC_PATH_PROG(PERL, perl)
+
+# figure out where gdb lives
+AC_PATH_PROG(GDB, gdb, "/no/gdb/was/found/at/configure/time")
+AC_DEFINE_UNQUOTED(GDB_PATH, "$GDB", [path to GDB])
+
+# some older automake's don't have it so try something on our own
+ifdef([AM_PROG_AS],[AM_PROG_AS],
+[
+AS="${CC}"
+AC_SUBST(AS)
+
+ASFLAGS=""
+AC_SUBST(ASFLAGS)
+])
+
+
+# Check if 'diff' supports -u (universal diffs) and use it if possible.
+
+AC_MSG_CHECKING([for diff -u])
+AC_SUBST(DIFF)
+
+# Comparing two identical files results in 0.
+tmpfile="tmp-xxx-yyy-zzz"
+touch $tmpfile;
+if diff -u $tmpfile $tmpfile ; then
+ AC_MSG_RESULT([yes])
+ DIFF="diff -u"
+else
+ AC_MSG_RESULT([no])
+ DIFF="diff"
+fi
+rm $tmpfile
+
+
+# We don't want gcc < 3.0
+AC_MSG_CHECKING([for a supported version of gcc])
+
+# Obtain the compiler version.
+#
+# A few examples of how the ${CC} --version output looks like:
+#
+# Arch Linux: i686-pc-linux-gnu-gcc (GCC) 4.6.2
+# Debian Linux: gcc (Debian 4.3.2-1.1) 4.3.2
+# openSUSE: gcc (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision
167585]
+# Exherbo Linux: x86_64-pc-linux-gnu-gcc (Exherbo gcc-4.6.2) 4.6.2
+# OS/X 10.6: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build
5666) (dot 3)
+# OS/X 10.7: i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple
Inc. build 5658) (LLVM build 2335.15.00)
+# Clang: clang version 2.9 (tags/RELEASE_29/final)
+#
+[gcc_version=`${CC} --version \
+ | $SED -n -e 's/[^ ]*gcc[^ ]* ([^)]*) \([0-9.]*\).*$/\1/p' \
+ -e 's/[^ ]*clang version \([0-9.]*\).*$/\1/p'`]
+
+is_clang="notclang"
+if test "x`${CC} --version | head -n 1 | $SED 's/\(clang\)
version.*/\1/'`" = "xclang" ; then
+ is_clang="clang"
+fi
+
+case "${is_clang}-${gcc_version}" in
+ notclang-3.*)
+ AC_MSG_RESULT([ok (${gcc_version})])
+ ;;
+ notclang-4.*)
+ AC_MSG_RESULT([ok (${gcc_version})])
+ ;;
+ clang-2.9)
+ AC_MSG_RESULT([ok (clang-${gcc_version})])
+ ;;
+ *)
+ AC_MSG_RESULT([no (${gcc_version})])
+ AC_MSG_ERROR([please use gcc >= 3.0 or clang >= 2.9])
+ ;;
+esac
+
+AC_PROG_EGREP
+AC_DEFINE_UNQUOTED(EGREP_PATH, "$EGREP", [path to egrep])
+
+AC_PATH_PROG(STRINGS, strings)
+AC_DEFINE_UNQUOTED(STRINGS_PATH, "$STRINGS", [path to strings])
+
+AC_PATH_PROG(SH, sh)
+AC_DEFINE_UNQUOTED(SH_PATH, "$SH", [path to sh])
+
+#----------------------------------------------------------------------------
+# Arch/OS/platform tests.
+#----------------------------------------------------------------------------
+# We create a number of arch/OS/platform-related variables. We prefix them
+# all with "VGCONF_" which indicates that they are defined at
+# configure-time, and distinguishes them from the VGA_*/VGO_*/VGP_*
+# variables used when compiling C files.
+
+AC_CANONICAL_HOST
+
+AC_MSG_CHECKING([for a supported CPU])
+
+# ARCH_MAX reflects the most that this CPU can do: for example if it
+# is a 64-bit capable PowerPC, then it must be set to ppc64 and not ppc32.
+# Ditto for amd64. It is used for more configuration below, but is not
used
+# outside this file.
+case "${host_cpu}" in
+ i?86)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="x86"
+ ;;
+
+ x86_64)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="amd64"
+ ;;
+
+ powerpc64)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="ppc64"
+ ;;
+
+ powerpc)
+ # On Linux this means only a 32-bit capable CPU.
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="ppc32"
+ ;;
+
+ s390x)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="s390x"
+ ;;
+
+ armv7*)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="arm"
+ ;;
+
+ *)
+ AC_MSG_RESULT([no (${host_cpu})])
+ AC_MSG_ERROR([Unsupported host architecture. Sorry])
+ ;;
+esac
+
+#----------------------------------------------------------------------------
+
+# Sometimes it's convenient to subvert the bi-arch build system and
+# just have a single build even though the underlying platform is
+# capable of both. Hence handle --enable-only64bit and
+# --enable-only32bit. Complain if both are issued :-)
+# [Actually, if either of these options are used, I think both get built,
+# but only one gets installed. So if you use an in-place build, both can
be
+# used. --njn]
+
+# Check if a 64-bit only build has been requested
+AC_CACHE_CHECK([for a 64-bit only build], vg_cv_only64bit,
+ [AC_ARG_ENABLE(only64bit,
+ [ --enable-only64bit do a 64-bit only build],
+ [vg_cv_only64bit=$enableval],
+ [vg_cv_only64bit=no])])
+
+# Check if a 32-bit only build has been requested
+AC_CACHE_CHECK([for a 32-bit only build], vg_cv_only32bit,
+ [AC_ARG_ENABLE(only32bit,
+ [ --enable-only32bit do a 32-bit only build],
+ [vg_cv_only32bit=$enableval],
+ [vg_cv_only32bit=no])])
+
+# Stay sane
+if test x$vg_cv_only64bit = xyes -a x$vg_cv_only32bit = xyes; then
+ AC_MSG_ERROR(
+ [Nonsensical: both --enable-only64bit and --enable-only32bit.])
+fi
+
+#----------------------------------------------------------------------------
+
+# VGCONF_OS is the primary build OS, eg. "linux". It is passed in to
+# compilation of many C files via -VGO_$(VGCONF_OS) and
+# -VGP_$(VGCONF_ARCH_PRI)_$(VGCONF_OS).
+AC_MSG_CHECKING([for a supported OS])
+AC_SUBST(VGCONF_OS)
+
+DEFAULT_SUPP=""
+
+case "${host_os}" in
+ *linux*)
+ AC_MSG_RESULT([ok (${host_os})])
+ VGCONF_OS="linux"
+
+ # Ok, this is linux. Check the kernel version
+ AC_MSG_CHECKING([for the kernel version])
+
+ kernel=`uname -r`
+
+ case "${kernel}" in
+ 2.6.*|3.*)
+ AC_MSG_RESULT([2.6.x/3.x family (${kernel})])
+ AC_DEFINE([KERNEL_2_6], 1, [Define to 1 if you're using Linux
2.6.x or Linux 3.x])
+ ;;
+
+ 2.4.*)
+ AC_MSG_RESULT([2.4 family (${kernel})])
+ AC_DEFINE([KERNEL_2_4], 1, [Define to 1 if you're using Linux
2.4.x])
+ ;;
+
+ *)
+ AC_MSG_RESULT([unsupported (${kernel})])
+ AC_MSG_ERROR([Valgrind works on kernels 2.4, 2.6])
+ ;;
+ esac
+
+ ;;
+
+ *darwin*)
+ AC_MSG_RESULT([ok (${host_os})])
+ VGCONF_OS="darwin"
+ AC_DEFINE([DARWIN_10_5], 100500, [DARWIN_VERS value for Mac OS X
10.5])
+ AC_DEFINE([DARWIN_10_6], 100600, [DARWIN_VERS value for Mac OS X
10.6])
+ AC_DEFINE([DARWIN_10_7], 100700, [DARWIN_VERS value for Mac OS X
10.7])
+
+ AC_MSG_CHECKING([for the kernel version])
+ kernel=`uname -r`
+
+ # Nb: for Darwin we set DEFAULT_SUPP here. That's because Darwin
+ # has only one relevant version, the OS version. The `uname` check
+ # is a good way to get that version (i.e. "Darwin 9.6.0" is Mac OS
+ # X 10.5.6, and "Darwin 10.x" is Mac OS X 10.6.x Snow Leopard,
+ # and possibly "Darwin 11.x" is Mac OS X 10.7.x Lion),
+ # and we don't know of an macros similar to __GLIBC__ to get that
info.
+ #
+ # XXX: `uname -r` won't do the right thing for cross-compiles, but
+ # that's not a problem yet.
+ #
+ # jseward 21 Sept 2011: I seriously doubt whether V 3.7.0 will work
+ # on OS X 10.5.x; I haven't tested yet, and only plan to test 3.7.0
+ # on 10.6.8 and 10.7.1. Although tempted to delete the configure
+ # time support for 10.5 (the 9.* pattern just below), I'll leave it
+ # in for now, just in case anybody wants to give it a try. But I'm
+ # assuming that 3.7.0 is a Snow Leopard and Lion-only release.
+ case "${kernel}" in
+ 9.*)
+ AC_MSG_RESULT([Darwin 9.x (${kernel}) / Mac OS X 10.5 Leopard])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_5, [Darwin / Mac OS X version])
+ DEFAULT_SUPP="darwin9.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="darwin9-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 10.*)
+ AC_MSG_RESULT([Darwin 10.x (${kernel}) / Mac OS X 10.6 Snow Leopard])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_6, [Darwin / Mac OS X version])
+ DEFAULT_SUPP="darwin10.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 11.*)
+ AC_MSG_RESULT([Darwin 11.x (${kernel}) / Mac OS X 10.7 Lion])
+ AC_DEFINE([DARWIN_VERS], DARWIN_10_7, [Darwin / Mac OS X version])
+ # FIXME: change these to xx11.supp
+ DEFAULT_SUPP="darwin11.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="darwin10-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ *)
+ AC_MSG_RESULT([unsupported (${kernel})])
+ AC_MSG_ERROR([Valgrind works on Darwin 10.x and 11.x (Mac OS X
10.6/7)])
+ ;;
+ esac
+ ;;
+
+ *)
+ AC_MSG_RESULT([no (${host_os})])
+ AC_MSG_ERROR([Valgrind is operating system specific. Sorry.])
+ ;;
+esac
+
+#----------------------------------------------------------------------------
+
+# If we are building on a 64 bit platform test to see if the system
+# supports building 32 bit programs and disable 32 bit support if it
+# does not support building 32 bit programs
+
+case "$ARCH_MAX-$VGCONF_OS" in
+ amd64-linux|ppc64-linux)
+ AC_MSG_CHECKING([for 32 bit build support])
+ safe_CFLAGS=$CFLAGS
+ CFLAGS="-m32"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ return 0;
+ ]])], [
+ AC_MSG_RESULT([yes])
+ ], [
+ vg_cv_only64bit="yes"
+ AC_MSG_RESULT([no])
+ ])
+ CFLAGS=$safe_CFLAGS;;
+esac
+
+if test x$vg_cv_only64bit = xyes -a x$vg_cv_only32bit = xyes; then
+ AC_MSG_ERROR(
+ [--enable-only32bit was specified but system does not support 32 bit
builds])
+fi
+
+#----------------------------------------------------------------------------
+
+# VGCONF_ARCH_PRI is the arch for the primary build target, eg. "amd64".
By
+# default it's the same as ARCH_MAX. But if, say, we do a build on an
amd64
+# machine, but --enable-only32bit has been requested, then ARCH_MAX (see
+# above) will be "amd64" since that reflects the most that this cpu can do,
+# but VGCONF_ARCH_PRI will be downgraded to "x86", since that reflects the
+# arch corresponding to the primary build (VGCONF_PLATFORM_PRI_CAPS). It
is
+# passed in to compilation of many C files via -VGA_$(VGCONF_ARCH_PRI) and
+# -VGP_$(VGCONF_ARCH_PRI)_$(VGCONF_OS).
+AC_SUBST(VGCONF_ARCH_PRI)
+
+# VGCONF_ARCH_SEC is the arch for the secondary build target, eg. "x86".
+# It is passed in to compilation of many C files via
-VGA_$(VGCONF_ARCH_SEC)
+# and -VGP_$(VGCONF_ARCH_SEC)_$(VGCONF_OS), if there is a secondary target.
+# It is empty if there is no secondary target.
+AC_SUBST(VGCONF_ARCH_SEC)
+
+# VGCONF_PLATFORM_PRI_CAPS is the primary build target, eg. "AMD64_LINUX".
+# The entire system, including regression and performance tests, will be
+# built for this target. The "_CAPS" indicates that the name is in capital
+# letters, and it also uses '_' rather than '-' as a separator, because
it's
+# used to create various Makefile variables, which are all in caps by
+# convention and cannot contain '-' characters. This is in contrast to
+# VGCONF_ARCH_PRI and VGCONF_OS which are not in caps.
+AC_SUBST(VGCONF_PLATFORM_PRI_CAPS)
+
+# VGCONF_PLATFORM_SEC_CAPS is the secondary build target, if there is one.
+# Valgrind and tools will also be built for this target, but not the
+# regression or performance tests.
+#
+# By default, the primary arch is the same as the "max" arch, as commented
+# above (at the definition of ARCH_MAX). We may choose to downgrade it in
+# the big case statement just below here, in the case where we're building
+# on a 64 bit machine but have been requested only to do a 32 bit build.
+AC_SUBST(VGCONF_PLATFORM_SEC_CAPS)
+
+AC_MSG_CHECKING([for a supported CPU/OS combination])
+
+# NB. The load address for a given platform may be specified in more
+# than one place, in some cases, depending on whether we're doing a biarch,
+# 32-bit only or 64-bit only build. eg see case for amd64-linux below.
+# Be careful to give consistent values in all subcases. Also, all four
+# valt_load_addres_{pri,sec}_{norml,inner} values must always be set,
+# even if it is to "0xUNSET".
+#
+case "$ARCH_MAX-$VGCONF_OS" in
+ x86-linux)
+ VGCONF_ARCH_PRI="x86"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="X86_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ amd64-linux)
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ if test x$vg_cv_only64bit = xyes; then
+ VGCONF_ARCH_PRI="amd64"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ elif test x$vg_cv_only32bit = xyes; then
+ VGCONF_ARCH_PRI="x86"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="X86_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ else
+ VGCONF_ARCH_PRI="amd64"
+ VGCONF_ARCH_SEC="x86"
+ VGCONF_PLATFORM_PRI_CAPS="AMD64_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS="X86_LINUX"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
+ fi
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ ppc32-linux)
+ VGCONF_ARCH_PRI="ppc32"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ ppc64-linux)
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ if test x$vg_cv_only64bit = xyes; then
+ VGCONF_ARCH_PRI="ppc64"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="PPC64_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ elif test x$vg_cv_only32bit = xyes; then
+ VGCONF_ARCH_PRI="ppc32"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="PPC32_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ else
+ VGCONF_ARCH_PRI="ppc64"
+ VGCONF_ARCH_SEC="ppc32"
+ VGCONF_PLATFORM_PRI_CAPS="PPC64_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS="PPC32_LINUX"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
+ fi
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ # Darwin gets identified as 32-bit even when it supports 64-bit.
+ # (Not sure why, possibly because 'uname' returns "i386"?) Just about
+ # all Macs support both 32-bit and 64-bit, so we just build both. If
+ # someone has a really old 32-bit only machine they can (hopefully?)
+ # build with --enable-only32bit. See bug 243362.
+ x86-darwin|amd64-darwin)
+ ARCH_MAX="amd64"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ if test x$vg_cv_only64bit = xyes; then
+ VGCONF_ARCH_PRI="amd64"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="AMD64_DARWIN"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x138000000"
+ valt_load_address_pri_inner="0x128000000"
+ elif test x$vg_cv_only32bit = xyes; then
+ VGCONF_ARCH_PRI="x86"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="X86_DARWIN"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ VGCONF_ARCH_PRI_CAPS="x86"
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ else
+ VGCONF_ARCH_PRI="amd64"
+ VGCONF_ARCH_SEC="x86"
+ VGCONF_PLATFORM_PRI_CAPS="AMD64_DARWIN"
+ VGCONF_PLATFORM_SEC_CAPS="X86_DARWIN"
+ valt_load_address_pri_norml="0x138000000"
+ valt_load_address_pri_inner="0x128000000"
+ valt_load_address_sec_norml="0x38000000"
+ valt_load_address_sec_inner="0x28000000"
+ fi
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ arm-linux)
+ VGCONF_ARCH_PRI="arm"
+ VGCONF_PLATFORM_PRI_CAPS="ARM_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([ok (${host_cpu}-${host_os})])
+ ;;
+ s390x-linux)
+ VGCONF_ARCH_PRI="s390x"
+ VGCONF_ARCH_SEC=""
+ VGCONF_PLATFORM_PRI_CAPS="S390X_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ # we want to have the generated code close to the dispatcher
+ valt_load_address_pri_norml="0x401000000"
+ valt_load_address_pri_inner="0x410000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
+ ;;
+ *)
+ VGCONF_ARCH_PRI="unknown"
+ VGCONF_ARCH_SEC="unknown"
+ VGCONF_PLATFORM_PRI_CAPS="UNKNOWN"
+ VGCONF_PLATFORM_SEC_CAPS="UNKNOWN"
+ valt_load_address_pri_norml="0xUNSET"
+ valt_load_address_pri_inner="0xUNSET"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([no (${ARCH_MAX}-${VGCONF_OS})])
+ AC_MSG_ERROR([Valgrind is platform specific. Sorry. Please
consider doing a port.])
+ ;;
+esac
+
+#----------------------------------------------------------------------------
+
+# Set up VGCONF_ARCHS_INCLUDE_<arch>. Either one or two of these become
+# defined.
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_X86,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_DARWIN )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_AMD64,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC32,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_PPC64,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_ARM,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_S390X,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX )
+
+# Set up VGCONF_PLATFORMS_INCLUDE_<platform>. Either one or two of these
+# become defined.
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xPPC32_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_ARM_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_S390X_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xS390X_LINUX)
+
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_DARWIN,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
+ -o x$VGCONF_PLATFORM_SEC_CAPS = xX86_DARWIN)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_AMD64_DARWIN,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN)
+
+
+# Similarly, set up VGCONF_OS_IS_<os>. Exactly one of these becomes
defined.
+# Relies on the assumption that the primary and secondary targets are
+# for the same OS, so therefore only necessary to test the primary.
+AM_CONDITIONAL(VGCONF_OS_IS_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX)
+AM_CONDITIONAL(VGCONF_OS_IS_DARWIN,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN)
+
+
+# Sometimes, in the Makefile.am files, it's useful to know whether or not
+# there is a secondary target.
+AM_CONDITIONAL(VGCONF_HAVE_PLATFORM_SEC,
+ test x$VGCONF_PLATFORM_SEC_CAPS != x)
+
+
+#----------------------------------------------------------------------------
+# Inner Valgrind?
+#----------------------------------------------------------------------------
+
+# Check if this should be built as an inner Valgrind, to be run within
+# another Valgrind. Choose the load address accordingly.
+AC_SUBST(VALT_LOAD_ADDRESS_PRI)
+AC_SUBST(VALT_LOAD_ADDRESS_SEC)
+AC_CACHE_CHECK([for use as an inner Valgrind], vg_cv_inner,
+ [AC_ARG_ENABLE(inner,
+ [ --enable-inner enables self-hosting],
+ [vg_cv_inner=$enableval],
+ [vg_cv_inner=no])])
+if test "$vg_cv_inner" = yes; then
+ AC_DEFINE([ENABLE_INNER], 1, [configured to run as an inner Valgrind])
+ VALT_LOAD_ADDRESS_PRI=$valt_load_address_pri_inner
+ VALT_LOAD_ADDRESS_SEC=$valt_load_address_sec_inner
+else
+ VALT_LOAD_ADDRESS_PRI=$valt_load_address_pri_norml
+ VALT_LOAD_ADDRESS_SEC=$valt_load_address_sec_norml
+fi
+
+
+#----------------------------------------------------------------------------
+# Extra fine-tuning of installation directories
+#----------------------------------------------------------------------------
+AC_ARG_WITH(tmpdir,
+ [ --with-tmpdir=PATH Specify path for temporary files],
+ tmpdir="$withval",
+ tmpdir="/tmp")
+AC_DEFINE_UNQUOTED(VG_TMPDIR, "$tmpdir", [Temporary files directory])
+
+
+#----------------------------------------------------------------------------
+# Libc and suppressions
+#----------------------------------------------------------------------------
+# This variable will collect the suppression files to be used.
+AC_SUBST(DEFAULT_SUPP)
+
+AC_CHECK_HEADER([features.h])
+
+if test x$ac_cv_header_features_h = xyes; then
+ rm -f conftest.$ac_ext
+ cat <<_ACEOF >conftest.$ac_ext
+#include <features.h>
+#if defined(__GNU_LIBRARY__) && defined(__GLIBC__) &&
defined(__GLIBC_MINOR__)
+glibc version is: __GLIBC__ __GLIBC_MINOR__
+#endif
+_ACEOF
+ GLIBC_VERSION="`$CPP conftest.$ac_ext | $SED -n 's/^glibc version is:
//p' | $SED 's/ /./g'`"
+fi
+
+# not really a version check
+AC_EGREP_CPP([DARWIN_LIBC], [
+#include <sys/cdefs.h>
+#if defined(__DARWIN_VERS_1050)
+ DARWIN_LIBC
+#endif
+],
+GLIBC_VERSION="darwin")
+
+# not really a version check
+AC_EGREP_CPP([BIONIC_LIBC], [
+#if defined(__ANDROID__)
+ BIONIC_LIBC
+#endif
+],
+GLIBC_VERSION="bionic")
+
+
+AC_MSG_CHECKING([the GLIBC_VERSION version])
+
+case "${GLIBC_VERSION}" in
+ 2.2)
+ AC_MSG_RESULT(2.2 family)
+ AC_DEFINE([GLIBC_2_2], 1, [Define to 1 if you're using glibc 2.2.x])
+ DEFAULT_SUPP="glibc-2.2.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.2-LinuxThreads-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+
+ 2.3)
+ AC_MSG_RESULT(2.3 family)
+ AC_DEFINE([GLIBC_2_3], 1, [Define to 1 if you're using glibc 2.3.x])
+ DEFAULT_SUPP="glibc-2.3.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+
+ 2.4)
+ AC_MSG_RESULT(2.4 family)
+ AC_DEFINE([GLIBC_2_4], 1, [Define to 1 if you're using glibc 2.4.x])
+ DEFAULT_SUPP="glibc-2.4.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+
+ 2.5)
+ AC_MSG_RESULT(2.5 family)
+ AC_DEFINE([GLIBC_2_5], 1, [Define to 1 if you're using glibc 2.5.x])
+ DEFAULT_SUPP="glibc-2.5.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.6)
+ AC_MSG_RESULT(2.6 family)
+ AC_DEFINE([GLIBC_2_6], 1, [Define to 1 if you're using glibc 2.6.x])
+ DEFAULT_SUPP="glibc-2.6.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.7)
+ AC_MSG_RESULT(2.7 family)
+ AC_DEFINE([GLIBC_2_7], 1, [Define to 1 if you're using glibc 2.7.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.8)
+ AC_MSG_RESULT(2.8 family)
+ AC_DEFINE([GLIBC_2_8], 1, [Define to 1 if you're using glibc 2.8.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.9)
+ AC_MSG_RESULT(2.9 family)
+ AC_DEFINE([GLIBC_2_9], 1, [Define to 1 if you're using glibc 2.9.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.10)
+ AC_MSG_RESULT(2.10 family)
+ AC_DEFINE([GLIBC_2_10], 1, [Define to 1 if you're using glibc 2.10.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.11)
+ AC_MSG_RESULT(2.11 family)
+ AC_DEFINE([GLIBC_2_11], 1, [Define to 1 if you're using glibc 2.11.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.12)
+ AC_MSG_RESULT(2.12 family)
+ AC_DEFINE([GLIBC_2_12], 1, [Define to 1 if you're using glibc 2.12.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.13)
+ AC_MSG_RESULT(2.13 family)
+ AC_DEFINE([GLIBC_2_13], 1, [Define to 1 if you're using glibc 2.13.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ 2.14)
+ AC_MSG_RESULT(2.14 family)
+ AC_DEFINE([GLIBC_2_14], 1, [Define to 1 if you're using glibc 2.14.x])
+ DEFAULT_SUPP="glibc-2.X.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.34567-NPTL-helgrind.supp ${DEFAULT_SUPP}"
+ DEFAULT_SUPP="glibc-2.X-drd.supp ${DEFAULT_SUPP}"
+ ;;
+ darwin)
+ AC_MSG_RESULT(Darwin)
+ AC_DEFINE([DARWIN_LIBC], 1, [Define to 1 if you're using Darwin])
+ # DEFAULT_SUPP set by kernel version check above.
+ ;;
+ bionic)
+ AC_MSG_RESULT(Bionic)
+ AC_DEFINE([BIONIC_LIBC], 1, [Define to 1 if you're using Bionic])
+ DEFAULT_SUPP="bionic.supp ${DEFAULT_SUPP}"
+ ;;
+
+ *)
+ AC_MSG_RESULT([unsupported version ${GLIBC_VERSION}])
+ AC_MSG_ERROR([Valgrind requires glibc version 2.2 - 2.14])
+ AC_MSG_ERROR([or Darwin libc])
+ ;;
+esac
+
+AC_SUBST(GLIBC_VERSION)
+
+if test x$ac_cv_header_features_h = xyes; then
+ rm -f conftest.$ac_ext
+ cat <<_ACEOF >conftest.$ac_ext
+#include <features.h>
+#if defined(__GNU_LIBRARY__) && defined(__GLIBC__) &&
defined(__GLIBC_MINOR__)
+glibc major version is: __GLIBC__
+#endif
+_ACEOF
+ GLIBC_MAJOR="`$CPP conftest.$ac_ext | $SED -n 's/^glibc major version
is: //p'`"
+fi
+
+AC_MSG_CHECKING([the GLIBC_MAJOR version])
+
+case "${GLIBC_MAJOR}" in
+ 2)
+ AC_MSG_RESULT(2.X family)
+ AC_DEFINE([GLIBC_2_X], 1, [Define to 1 if you're using glibc 2.x.x])
+ DEFAULT_SUPP="glibc-X.X.supp ${DEFAULT_SUPP}"
+ ;;
+ *)
+ ;;
+esac
+
+AC_SUBST(GLIBC_MAJOR)
+
+
+# Add default suppressions for the X client libraries. Make no
+# attempt to detect whether such libraries are installed on the
+# build machine (or even if any X facilities are present); just
+# add the suppressions antidisirregardless.
+DEFAULT_SUPP="xfree-4.supp ${DEFAULT_SUPP}"
+DEFAULT_SUPP="xfree-3.supp ${DEFAULT_SUPP}"
+
+# Add glibc and X11 suppressions for exp-sgcheck
+DEFAULT_SUPP="exp-sgcheck.supp ${DEFAULT_SUPP}"
+
+
+#----------------------------------------------------------------------------
+# Platform variants?
+#----------------------------------------------------------------------------
+
+# 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
arm-linux,
+# but not quite. So this introduces the concept of platform variant tags,
+# which get passed in the compile as -DVGPV_<arch>_<os>_<variant> along
+# with the main -DVGP_<arch>_<os> definition.
+#
+# In almost all cases, the <variant> bit is "vanilla". But for Android
+# it is "android" instead.
+#
+# Consequently (eg), plain arm-linux would build with
+#
+# -DVGP_arm_linux -DVGPV_arm_linux_vanilla
+#
+# whilst an Android build would have
+#
+# -DVGP_arm_linux -DVGPV_arm_linux_android
+#
+# The setup of the platform variant is pushed relatively far down this
+# file in order that we can inspect any of the variables set above.
+
+# In the normal case ..
+VGCONF_PLATVARIANT="vanilla"
+
+# Android on ARM ?
+if test "$VGCONF_ARCH_PRI-$VGCONF_OS" = "arm-linux" \
+ -a "$GLIBC_VERSION" = "bionic";
+then
+ VGCONF_PLATVARIANT="android"
+fi
+
+AC_SUBST(VGCONF_PLATVARIANT)
+
+
+# FIXME: do we also want to define automake variables
+# VGCONF_PLATVARIANT_IS_<WHATEVER>, where WHATEVER is (currently)
+# VANILLA or ANDROID ? This would be in the style of VGCONF_ARCHS_INCLUDE,
+# VGCONF_PLATFORMS_INCLUDE and VGCONF_OS_IS above? Could easily enough
+# do that. Problem is that we can't do and-ing in Makefile.am's, but
+# that's what we'd need to do to use this, since what we'd want to write
+# is something like
+#
+# VGCONF_PLATFORMS_INCLUDE_ARM_LINUX && VGCONF_PLATVARIANT_IS_ANDROID
+#
+# Hmm. Can't think of a nice clean solution to this.
+
+AM_CONDITIONAL(VGCONF_PLATVARIANT_IS_VANILLA,
+ test x$VGCONF_PLATVARIANT = xvanilla)
+AM_CONDITIONAL(VGCONF_PLATVARIANT_IS_ANDROID,
+ test x$VGCONF_PLATVARIANT = xandroid)
+
+
+#----------------------------------------------------------------------------
+# Checking for various library functions and other definitions
+#----------------------------------------------------------------------------
+
+# Check for CLOCK_MONOTONIC
+
+AC_MSG_CHECKING([for CLOCK_MONOTONIC])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <time.h>
+]], [[
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ return 0;
+]])], [
+AC_MSG_RESULT([yes])
+AC_DEFINE([HAVE_CLOCK_MONOTONIC], 1,
+ [Define to 1 if you have the `CLOCK_MONOTONIC' constant.])
+], [
+AC_MSG_RESULT([no])
+])
+
+
+# Check for PTHREAD_RWLOCK_T
+
+AC_MSG_CHECKING([for pthread_rwlock_t])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <pthread.h>
+]], [[
+ pthread_rwlock_t rwl;
+]])], [
+AC_MSG_RESULT([yes])
+AC_DEFINE([HAVE_PTHREAD_RWLOCK_T], 1,
+ [Define to 1 if you have the `pthread_rwlock_t' type.])
+], [
+AC_MSG_RESULT([no])
+])
+
+
+# Check for PTHREAD_MUTEX_ADAPTIVE_NP
+
+AC_MSG_CHECKING([for PTHREAD_MUTEX_ADAPTIVE_NP])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <pthread.h>
+]], [[
+ return (PTHREAD_MUTEX_ADAPTIVE_NP);
+]])], [
+AC_MSG_RESULT([yes])
+AC_DEFINE([HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], 1,
+ [Define to 1 if you have the `PTHREAD_MUTEX_ADAPTIVE_NP'
constant.])
+], [
+AC_MSG_RESULT([no])
+])
+
+
+# Check for PTHREAD_MUTEX_ERRORCHECK_NP
+
+AC_MSG_CHECKING([for PTHREAD_MUTEX_ERRORCHECK_NP])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <pthread.h>
+]], [[
+ return (PTHREAD_MUTEX_ERRORCHECK_NP);
+]])], [
+AC_MSG_RESULT([yes])
+AC_DEFINE([HAVE_PTHREAD_MUTEX_ERRORCHECK_NP], 1,
+ [Define to 1 if you have the `PTHREAD_MUTEX_ERRORCHECK_NP'
constant.])
+], [
+AC_MSG_RESULT([no])
+])
+
+
+# Check for PTHREAD_MUTEX_RECURSIVE_NP
+
+AC_MSG_CHECKING([for PTHREAD_MUTEX_RECURSIVE_NP])
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#define _GNU_SOURCE
+#include <pthread.h>
+]], [[
+ return (PTHREAD_MUTEX_RECURSIVE_NP);
+]])], [
+AC_MSG_RESULT([yes])
+AC_DEFINE([HAVE_PTHREAD_MUTEX_RECURSIVE_NP], 1,
+ [Define to 1 if you have the `PTHREAD_MUTEX_RECURSIVE_NP'
constant.])
+], [
+AC_MSG_RESULT([no])
+])
+
+
+# Check for PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/link_tool_exe_darwin.in.orig Thu Nov 22
04:55:39 2012
@@ -0,0 +1,192 @@
+#! @PERL@
+
+# This script handles linking the tool executables on Linux,
+# statically and at an alternative load address.
+#
+# Linking statically sidesteps all sorts of complications to do with
+# having two copies of the dynamic linker (valgrind's and the
+# client's) coexisting in the same process. The alternative load
+# address is needed because Valgrind itself will load the client at
+# whatever address it specifies, which is almost invariably the
+# default load address. Hence we can't allow Valgrind itself (viz,
+# the tool executable) to be loaded at that address.
+#
+# Unfortunately there's no standard way to do 'static link at
+# alternative address', so these link_tool_exe_*.in scripts handle
+# the per-platform hoop-jumping.
+#
+# What we get passed here is:
+# first arg
+# the alternative load address
+# all the rest of the args
+# the gcc invokation to do the final link, that
+# the build system would have done, left to itself
+#
+# We just let the script 'die' if something is wrong, rather than do
+# proper error reporting. We don't expect the users to run this
+# directly. It is only run as part of the build process, with
+# carefully constrained inputs.
+#
+#
+# So: what we actually do is:
+#
+# Look at the specified gcc invokation. Ignore all parts of it except
+# the *.a, *.o and -o outfile parts. Wrap them up in a new command
+# which looks (eg) as follows:
+#
+# (64-bit):
+#
+# /usr/bin/ld -static -arch x86_64 -macosx_version_min 10.5 \
+# -o memcheck-amd64-darwin -u __start -e __start \
+# -image_base 0x138000000 -stack_addr 0x13c000000 \
+# -stack_size 0x800000 \
+# memcheck_amd*.o \
+# ../coregrind/libcoregrind-amd64-darwin.a \
+# ../VEX/libvex-amd64-darwin.a
+#
+# (32-bit)
+#
+# /usr/bin/ld -static -arch i386 -macosx_version_min 10.5 \
+# -o memcheck-x86-darwin -u __start -e __start \
+# -image_base 0x38000000 -stack_addr 0x3c000000 \
+# -stack_size 0x800000 \
+# memcheck_x86*.o \
+# ../coregrind/libcoregrind-x86-darwin.a \
+# ../VEX/libvex-x86-darwin.a
+#
+# The addresses shown above will actually work, although "for real" we
+# of course need to take it from argv[1]. In these examples the stack
+# is placed 64M after the executable start. It is probably safer to
+# place it 64M before the executable's start point, so the executable
+# + data + bss can grow arbitrarily in future without colliding with
+# the stack.
+#
+# There's one more twist: we need to know the word size of the
+# executable for which we are linking. We need to know this because
+# we must tell the linker that, by handing it either "-arch x86_64" or
+# "-arch i386". Fortunately we can figure this out by scanning the
+# gcc invokation, which itself must contain either "-arch x86_64" or
+# "-arch i386".
+
+use warnings;
+use strict;
+use Cwd 'abs_path';
+use File::Basename;
+# we need to be able to do 64-bit arithmetic:
+use Math::BigInt;
+
+
+# User configurable constants: how far before the exe should we
+# place the stack?
+my $TX_STACK_OFFSET_BEFORE_TEXT = 64 * 1024 * 1024;
+
+# and how big should the stack be?
+my $TX_STACK_SIZE = 8 * 1024 * 1024;
+
+
+# string -> bool
+sub is_dota_or_doto($)
+{
+ my ($str) = @_;
+ if ($str =~ /.\.a$/ || $str =~ /.\.o$/) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+# expect at least: alt-load-address gcc -o foo bar.o
+die "Not enough arguments"
+ if (($#ARGV + 1) < 5);
+
+my $ala = $ARGV[0];
+
+# check for plausible-ish alt load address
+die "Bogus alt-load address (1)"
+ if (length($ala) < 3 || index($ala, "0x") != 0);
+
+die "Bogus alt-load address (2)"
+ if ($ala !~ /^0x[0-9a-fA-F]+$/);
+
+
+# get hold of the outfile name (following "-o")
+my $outname = "";
+
+foreach my $n (2 .. $#ARGV - 1) {
+ my $str = $ARGV[$n];
+ if ($str eq "-o" && $outname eq "") {
+ $outname = $ARGV[$n + 1];
+ }
+}
+
+die "Can't find '-o outfilename' in command line"
+ if ($outname eq "");
+
+
+# get hold of the string following "-arch"
+my $archstr = "";
+
+foreach my $n (2 .. $#ARGV - 1) {
+ my $str = $ARGV[$n];
+ if ($str eq "-arch" && $archstr eq "") {
+ $archstr = $ARGV[$n + 1];
+ }
+}
+
+die "Can't find '-arch archstr' in command line"
+ if ($archstr eq "");
+
+
+# build the command line
+my $cmd = "/usr/bin/ld";
+
+$cmd = "$cmd -static";
+$cmd = "$cmd -arch $archstr";
+$cmd = "$cmd -macosx_version_min 10.5";
+$cmd = "$cmd -o $outname";
+$cmd = "$cmd -u __start -e __start";
+
+my $stack_addr = Math::BigInt->new( $ala ) - $TX_STACK_OFFSET_BEFORE_TEXT;
+my $stack_addr_str = $stack_addr->as_hex();
+my $stack_size_str = Math::BigInt::as_hex($TX_STACK_SIZE);
+
+$cmd = "$cmd -image_base $ala";
+$cmd = "$cmd -stack_addr $stack_addr_str";
+$cmd = "$cmd -stack_size $stack_size_str";
+
+foreach my $n (2 .. $#ARGV) {
+ my $str = $ARGV[$n];
+ if (is_dota_or_doto($str)) {
+ $cmd = "$cmd $str";
+ }
+}
+
+print "link_tool_exe_darwin: $cmd\n";
+
+# Execute the command:
+my $r = system("$cmd");
+
+if ($r != 0) {
+ exit 1;
+}
+
+
+# and now kludge the tool exe
+# see bug 267997
+
+$cmd = dirname(abs_path($0)) . "/../coregrind/fixup_macho_loadcmds";
+$cmd = "$cmd $stack_addr_str $stack_size_str $outname";
+
+print "link_tool_exe_darwin: $cmd\n";
+
+$r = system("$cmd");
+
+if ($r != 0) {
+ exit 1;
+}
+
+
+
+
+exit 0;
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_aspacemgr/aspacemgr-linux.c.orig Thu Nov 22
04:55:39 2012
@@ -0,0 +1,3647 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The address space manager: segment initialisation and ---*/
+/*--- tracking, stack operations ---*/
+/*--- ---*/
+/*--- Implementation for Linux (and Darwin!) m_aspacemgr-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2011 Julian Seward
+ jse...@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#if defined(VGO_linux) || defined(VGO_darwin)
+
+/* *************************************************************
+ DO NOT INCLUDE ANY OTHER FILES HERE.
+ ADD NEW INCLUDES ONLY TO priv_aspacemgr.h
+ AND THEN ONLY AFTER READING DIRE WARNINGS THERE TOO.
+ ************************************************************* */
+
+#include "priv_aspacemgr.h"
+#include "config.h"
+
+
+/* Note: many of the exported functions implemented below are
+ described more fully in comments in pub_core_aspacemgr.h.
+*/
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Overview. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Purpose
+ ~~~~~~~
+ The purpose of the address space manager (aspacem) is:
+
+ (1) to record the disposition of all parts of the process' address
+ space at all times.
+
+ (2) to the extent that it can, influence layout in ways favourable
+ to our purposes.
+
+ It is important to appreciate that whilst it can and does attempt
+ to influence layout, and usually succeeds, it isn't possible to
+ impose absolute control: in the end, the kernel is the final
+ arbiter, and can always bounce our requests.
+
+ Strategy
+ ~~~~~~~~
+ The strategy is therefore as follows:
+
+ * Track ownership of mappings. Each one can belong either to
+ Valgrind or to the client.
+
+ * Try to place the client's fixed and hinted mappings at the
+ requested addresses. Fixed mappings are allowed anywhere except
+ in areas reserved by Valgrind; the client can trash its own
+ mappings if it wants. Hinted mappings are allowed providing they
+ fall entirely in free areas; if not, they will be placed by
+ aspacem in a free area.
+
+ * Anonymous mappings are allocated so as to keep Valgrind and
+ client areas widely separated when possible. If address space
+ runs low, then they may become intermingled: aspacem will attempt
+ to use all possible space. But under most circumstances lack of
+ address space is not a problem and so the areas will remain far
+ apart.
+
+ Searches for client space start at aspacem_cStart and will wrap
+ around the end of the available space if needed. Searches for
+ Valgrind space start at aspacem_vStart and will also wrap around.
+ Because aspacem_cStart is approximately at the start of the
+ available space and aspacem_vStart is approximately in the
+ middle, for the most part the client anonymous mappings will be
+ clustered towards the start of available space, and Valgrind ones
+ in the middle.
+
+ The available space is delimited by aspacem_minAddr and
+ aspacem_maxAddr. aspacem is flexible and can operate with these
+ at any (sane) setting. For 32-bit Linux, aspacem_minAddr is set
+ to some low-ish value at startup (64M) and aspacem_maxAddr is
+ derived from the stack pointer at system startup. This seems a
+ reliable way to establish the initial boundaries.
+
+ 64-bit Linux is similar except for the important detail that the
+ upper boundary is set to 32G. The reason is so that all
+ anonymous mappings (basically all client data areas) are kept
+ below 32G, since that is the maximum range that memcheck can
+ track shadow memory using a fast 2-level sparse array. It can go
+ beyond that but runs much more slowly. The 32G limit is
+ arbitrary and is trivially changed. So, with the current
+ settings, programs on 64-bit Linux will appear to run out of
+ address space and presumably fail at the 32G limit. Given the
+ 9/8 space overhead of Memcheck, that means you should be able to
+ memcheckify programs that use up to about 14G natively.
+
+ Note that the aspacem_minAddr/aspacem_maxAddr limits apply only to
+ anonymous mappings. The client can still do fixed and hinted maps
+ at any addresses provided they do not overlap Valgrind's segments.
+ This makes Valgrind able to load prelinked .so's at their requested
+ addresses on 64-bit platforms, even if they are very high (eg,
+ 112TB).
+
+ At startup, aspacem establishes the usable limits, and advises
+ m_main to place the client stack at the top of the range, which on
+ a 32-bit machine will be just below the real initial stack. One
+ effect of this is that self-hosting sort-of works, because an inner
+ valgrind will then place its client's stack just below its own
+ initial stack.
+
+ The segment array and segment kinds
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ The central data structure is the segment array (segments[0
+ .. nsegments_used-1]). This covers the entire address space in
+ order, giving account of every byte of it. Free spaces are
+ represented explicitly as this makes many operations simpler.
+ Mergeable adjacent segments are aggressively merged so as to create
+ a "normalised" representation (preen_nsegments).
+
+ There are 7 (mutually-exclusive) segment kinds, the meaning of
+ which is important:
+
+ SkFree: a free space, which may be allocated either to Valgrind (V)
+ or the client (C).
+
+ SkAnonC: an anonymous mapping belonging to C. For these, aspacem
+ tracks a boolean indicating whether or not is is part of the
+ client's heap area (can't remember why).
+
+ SkFileC: a file mapping belonging to C.
+
+ SkShmC: a shared memory segment belonging to C.
+
+ SkAnonV: an anonymous mapping belonging to V. These cover all V's
+ dynamic memory needs, including non-client malloc/free areas,
+ shadow memory, and the translation cache.
+
+ SkFileV: a file mapping belonging to V. As far as I know these are
+ only created transiently for the purposes of reading debug info.
+
+ SkResvn: a reservation segment.
+
+ These are mostly straightforward. Reservation segments have some
+ subtlety, however.
+
+ A reservation segment is unmapped from the kernel's point of view,
+ but is an area in which aspacem will not create anonymous maps
+ (either Vs or Cs). The idea is that we will try to keep it clear
+ when the choice to do so is ours. Reservation segments are
+ 'invisible' from the client's point of view: it may choose to park
+ a fixed mapping in the middle of one, and that's just tough -- we
+ can't do anything about that. From the client's perspective
+ reservations are semantically equivalent to (although
+ distinguishable from, if it makes enquiries) free areas.
+
+ Reservations are a primitive mechanism provided for whatever
+ purposes the rest of the system wants. Currently they are used to
+ reserve the expansion space into which a growdown stack is
+ expanded, and into which the data segment is extended. Note,
+ though, those uses are entirely external to this module, which only
+ supplies the primitives.
+
+ Reservations may be shrunk in order that an adjoining anonymous
+ mapping may be extended. This makes dataseg/stack expansion work.
+ A reservation may not be shrunk below one page.
+
+ The advise/notify concept
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ All mmap-related calls must be routed via aspacem. Calling
+ sys_mmap directly from the rest of the system is very dangerous
+ because aspacem's data structures will become out of date.
+
+ The fundamental mode of operation of aspacem is to support client
+ mmaps. Here's what happens (in ML_(generic_PRE_sys_mmap)):
+
+ * m_syswrap intercepts the mmap call. It examines the parameters
+ and identifies the requested placement constraints. There are
+ three possibilities: no constraint (MAny), hinted (MHint, "I
+ prefer X but will accept anything"), and fixed (MFixed, "X or
+ nothing").
+
+ * This request is passed to VG_(am_get_advisory). This decides on
+ a placement as described in detail in Strategy above. It may
+ also indicate that the map should fail, because it would trash
+ one of Valgrind's areas, which would probably kill the system.
+
+ * Control returns to the wrapper. If VG_(am_get_advisory) has
+ declared that the map should fail, then it must be made to do so.
+ Usually, though, the request is considered acceptable, in which
+ case an "advised" address is supplied. The advised address
+ replaces the original address supplied by the client, and
+ MAP_FIXED is set.
+
+ Note at this point that although aspacem has been asked for
+ advice on where to place the mapping, no commitment has yet been
+ made by either it or the kernel.
+
+ * The adjusted request is handed off to the kernel.
+
+ * The kernel's result is examined. If the map succeeded, aspacem
+ is told of the outcome (VG_(am_notify_client_mmap)), so it can
+ update its records accordingly.
+
+ This then is the central advise-notify idiom for handling client
+ mmap/munmap/mprotect/shmat:
+
+ * ask aspacem for an advised placement (or a veto)
+
+ * if not vetoed, hand request to kernel, using the advised placement
+
+ * examine result, and if successful, notify aspacem of the result.
+
+ There are also many convenience functions, eg
+ VG_(am_mmap_anon_fixed_client), which do both phases entirely within
+ aspacem.
+
+ To debug all this, a sync-checker is provided. It reads
+ /proc/self/maps, compares what it sees with aspacem's records, and
+ complains if there is a difference. --sanity-level=3 runs it before
+ and after each syscall, which is a powerful, if slow way of finding
+ buggy syscall wrappers.
+
+ Loss of pointercheck
+ ~~~~~~~~~~~~~~~~~~~~
+ Up to and including Valgrind 2.4.1, x86 segmentation was used to
+ enforce seperation of V and C, so that wild writes by C could not
+ trash V. This got called "pointercheck". Unfortunately, the new
+ more flexible memory layout, plus the need to be portable across
+ different architectures, means doing this in hardware is no longer
+ viable, and doing it in software is expensive. So at the moment we
+ don't do it at all.
+*/
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- The Address Space Manager's state. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* ------ start of STATE for the address-space manager ------ */
+
+/* Max number of segments we can track. */
+/* glider: We keep VG_N_SEGMENTS low on Android, because they occupy
+ too much memory. We used to have VG_N_SEGMENTS=10000 on Darwin,
+ but it turned out to be too low for Chromium.
+*/
+#if defined(VGO_darwin)
+#define VG_N_SEGMENTS 50000
+#elif defined(ANDROID)
+#define VG_N_SEGMENTS 10000
+#else
+#define VG_N_SEGMENTS 100000
+#endif
+
+/* Max number of segment file names we can track. */
+#if defined(VGO_darwin) || defined(ANDROID)
+#define VG_N_SEGNAMES 1000
+#else
+#define VG_N_SEGNAMES 100000
+#endif
+
+/* Max length of a segment file name. */
+#define VG_MAX_SEGNAMELEN 1000
+
+
+typedef
+ struct {
+ Bool inUse;
+ Bool mark;
+ HChar fname[VG_MAX_SEGNAMELEN];
+ }
+ SegName;
+
+/* Filename table. _used is the high water mark; an entry is only
+ valid if its index >= 0, < _used, and its .inUse field == True.
+ The .mark field is used to garbage-collect dead entries.
+*/
+static SegName segnames[VG_N_SEGNAMES];
+static Int segnames_used = 0;
+
+
+/* Array [0 .. nsegments_used-1] of all mappings. */
+/* Sorted by .addr field. */
+/* I: len may not be zero. */
+/* I: overlapping segments are not allowed. */
+/* I: the segments cover the entire address space precisely. */
+/* Each segment can optionally hold an index into the filename table. */
+
+static NSegment nsegments[VG_N_SEGMENTS];
+static Int nsegments_used = 0;
+
+#define Addr_MIN ((Addr)0)
+#define Addr_MAX ((Addr)(-1ULL))
+
+/* Limits etc */
+
+// The smallest address that aspacem will try to allocate
+static Addr aspacem_minAddr = 0;
+
+// The largest address that aspacem will try to allocate
+static Addr aspacem_maxAddr = 0;
+
+// Where aspacem will start looking for client space
+static Addr aspacem_cStart = 0;
+
+// Where aspacem will start looking for Valgrind space
+static Addr aspacem_vStart = 0;
+
+
+#define AM_SANITY_CHECK \
+ do { \
+ if (VG_(clo_sanity_level >= 3)) \
+ aspacem_assert(VG_(am_do_sync_check) \
+ (__PRETTY_FUNCTION__,__FILE__,__LINE__)); \
+ } while (0)
+
+/* ------ end of STATE for the address-space manager ------ */
+
+/* ------ Forwards decls ------ */
+inline
+static Int find_nsegment_idx ( Addr a );
+
+static void parse_procselfmaps (
+ void (*record_mapping)( Addr addr, SizeT len, UInt prot,
+ ULong dev, ULong ino, Off64T offset,
+ const UChar* filename ),
+ void (*record_gap)( Addr addr, SizeT len )
+ );
+
+/* ----- Hacks to do with the "commpage" on arm-linux ----- */
+/* Not that I have anything against the commpage per se. It's just
+ that it's not listed in /proc/self/maps, which is a royal PITA --
+ we have to fake it up, in parse_procselfmaps.
+
+ But note also bug 254556 comment #2: this is now fixed in newer
+ kernels -- it is listed as a "[vectors]" entry. Presumably the
+ fake entry made here duplicates the [vectors] entry, and so, if at
+ some point in the future, we can stop supporting buggy kernels,
+ then this kludge can be removed entirely, since the procmap parser
+ below will read that entry in the normal way. */
+#if defined(VGP_arm_linux)
+# define ARM_LINUX_FAKE_COMMPAGE_START 0xFFFF0000
+# define ARM_LINUX_FAKE_COMMPAGE_END1 0xFFFF1000
+#endif
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- SegName array management. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Searches the filename table to find an index for the given name.
+ If none is found, an index is allocated and the name stored. If no
+ space is available we just give up. If the string is too long to
+ store, return -1.
+*/
+static Int allocate_segname ( const HChar* name )
+{
+ Int i, j, len;
+
+ aspacem_assert(name);
+
+ if (0) VG_(debugLog)(0,"aspacem","allocate_segname %s\n", name);
+
+ len = VG_(strlen)(name);
+ if (len >= VG_MAX_SEGNAMELEN-1) {
+ return -1;
+ }
+
+ /* first see if we already have the name. */
+ for (i = 0; i < segnames_used; i++) {
+ if (!segnames[i].inUse)
+ continue;
+ if (0 == VG_(strcmp)(name, &segnames[i].fname[0])) {
+ return i;
+ }
+ }
+
+ /* no we don't. So look for a free slot. */
+ for (i = 0; i < segnames_used; i++)
+ if (!segnames[i].inUse)
+ break;
+
+ if (i == segnames_used) {
+ /* no free slots .. advance the high-water mark. */
+ if (segnames_used+1 < VG_N_SEGNAMES) {
+ i = segnames_used;
+ segnames_used++;
+ } else {
+ ML_(am_barf_toolow)("VG_N_SEGNAMES");
+ }
+ }
+
+ /* copy it in */
+ segnames[i].inUse = True;
+ for (j = 0; j < len; j++)
+ segnames[i].fname[j] = name[j];
+ aspacem_assert(len < VG_MAX_SEGNAMELEN);
+ segnames[i].fname[len] = 0;
+ return i;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Displaying the segment array. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+static HChar* show_SegKind ( SegKind sk )
+{
+ switch (sk) {
+ case SkFree: return " ";
+ case SkAnonC: return "anon";
+ case SkAnonV: return "ANON";
+ case SkFileC: return "file";
+ case SkFileV: return "FILE";
+ case SkShmC: return "shm ";
+ case SkResvn: return "RSVN";
+ default: return "????";
+ }
+}
+
+static HChar* show_ShrinkMode ( ShrinkMode sm )
+{
+ switch (sm) {
+ case SmLower: return "SmLower";
+ case SmUpper: return "SmUpper";
+ case SmFixed: return "SmFixed";
+ default: return "Sm?????";
+ }
+}
+
+static void show_len_concisely ( /*OUT*/HChar* buf, Addr start, Addr end )
+{
+ HChar* fmt;
+ ULong len = ((ULong)end) - ((ULong)start) + 1;
+
+ if (len < 10*1000*1000ULL) {
+ fmt = "%7llu";
+ }
+ else if (len < 999999ULL * (1ULL<<20)) {
+ fmt = "%6llum";
+ len >>= 20;
+ }
+ else if (len < 999999ULL * (1ULL<<30)) {
+ fmt = "%6llug";
+ len >>= 30;
+ }
+ else if (len < 999999ULL * (1ULL<<40)) {
+ fmt = "%6llut";
+ len >>= 40;
+ }
+ else {
+ fmt = "%6llue";
+ len >>= 50;
+ }
+ ML_(am_sprintf)(buf, fmt, len);
+}
+
+
+/* Show full details of an NSegment */
+
+static void __attribute__ ((unused))
+ show_nsegment_full ( Int logLevel, Int segNo, NSegment* seg )
+{
+ HChar len_buf[20];
+ HChar* name = "(none)";
+
+ if (seg->fnIdx >= 0 && seg->fnIdx < segnames_used
+ && segnames[seg->fnIdx].inUse
+ && segnames[seg->fnIdx].fname[0] != 0)
+ name = segnames[seg->fnIdx].fname;
+
+ show_len_concisely(len_buf, seg->start, seg->end);
+
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %010llx-%010llx %s %c%c%c%c%c %s "
+ "d=0x%03llx i=%-7lld o=%-7lld (%d) m=%d %s\n",
+ segNo, show_SegKind(seg->kind),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',
+ seg->isCH ? 'H' : '-',
+ show_ShrinkMode(seg->smode),
+ seg->dev, seg->ino, seg->offset, seg->fnIdx,
+ (Int)seg->mark, name
+ );
+}
+
+
+/* Show an NSegment in a user-friendly-ish way. */
+
+static void show_nsegment ( Int logLevel, Int segNo, NSegment* seg )
+{
+ HChar len_buf[20];
+ show_len_concisely(len_buf, seg->start, seg->end);
+
+ switch (seg->kind) {
+
+ case SkFree:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %010llx-%010llx %s\n",
+ segNo, show_SegKind(seg->kind),
+ (ULong)seg->start, (ULong)seg->end, len_buf
+ );
+ break;
+
+ case SkAnonC: case SkAnonV: case SkShmC:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %010llx-%010llx %s %c%c%c%c%c\n",
+ segNo, show_SegKind(seg->kind),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',
+ seg->isCH ? 'H' : '-'
+ );
+ break;
+
+ case SkFileC: case SkFileV:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %010llx-%010llx %s %c%c%c%c%c d=0x%03llx "
+ "i=%-7lld o=%-7lld (%d)\n",
+ segNo, show_SegKind(seg->kind),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',
+ seg->isCH ? 'H' : '-',
+ seg->dev, seg->ino, seg->offset, seg->fnIdx
+ );
+ break;
+
+ case SkResvn:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %010llx-%010llx %s %c%c%c%c%c %s\n",
+ segNo, show_SegKind(seg->kind),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',
+ seg->isCH ? 'H' : '-',
+ show_ShrinkMode(seg->smode)
+ );
+ break;
+
+ default:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: ???? UNKNOWN SEGMENT KIND\n",
+ segNo
+ );
+ break;
+ }
+}
+
+/* Print out the segment array (debugging only!). */
+void VG_(am_show_nsegments) ( Int logLevel, HChar* who )
+{
+ Int i;
+ VG_(debugLog)(logLevel, "aspacem",
+ "<<< SHOW_SEGMENTS: %s (%d segments, %d segnames)\n",
+ who, nsegments_used, segnames_used);
+ for (i = 0; i < segnames_used; i++) {
+ if (!segnames[i].inUse)
+ continue;
+ VG_(debugLog)(logLevel, "aspacem",
+ "(%2d) %s\n", i, segnames[i].fname);
+ }
+ for (i = 0; i < nsegments_used; i++)
+ show_nsegment( logLevel, i, &nsegments[i] );
+ VG_(debugLog)(logLevel, "aspacem",
+ ">>>\n");
+}
+
+
+/* Get the filename corresponding to this segment, if known and if it
+ has one. The returned name's storage cannot be assumed to be
+ persistent, so the caller should immediately copy the name
+ elsewhere. */
+HChar* VG_(am_get_filename)( NSegment const * seg )
+{
+ Int i;
+ aspacem_assert(seg);
+ i = seg->fnIdx;
+ if (i < 0 || i >= segnames_used || !segnames[i].inUse)
+ return NULL;
+ else
+ return &segnames[i].fname[0];
+}
+
+/* Collect up the start addresses of all non-free, non-resvn segments.
+ The interface is a bit strange in order to avoid potential
+ segment-creation races caused by dynamic allocation of the result
+ buffer *starts.
+
+ The function first computes how many entries in the result
+ buffer *starts will be needed. If this number <= nStarts,
+ they are placed in starts[0..], and the number is returned.
+ If nStarts is not large enough, nothing is written to
+ starts[0..], and the negation of the size is returned.
+
+ Correct use of this function may mean calling it multiple times in
+ order to establish a suitably-sized buffer. */
+
+Int VG_(am_get_segment_starts)( Addr* starts, Int nStarts )
+{
+ Int i, j, nSegs;
+
+ /* don't pass dumbass arguments */
+ aspacem_assert(nStarts >= 0);
+
+ nSegs = 0;
+ for (i = 0; i < nsegments_used; i++) {
+ if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn)
+ continue;
+ nSegs++;
+ }
+
+ if (nSegs > nStarts) {
+ /* The buffer isn't big enough. Tell the caller how big it needs
+ to be. */
+ return -nSegs;
+ }
+
+ /* There's enough space. So write into the result buffer. */
+ aspacem_assert(nSegs <= nStarts);
+
+ j = 0;
+ for (i = 0; i < nsegments_used; i++) {
+ if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn)
+ continue;
+ starts[j] = nsegments[i].start;
+ j++;
+ }
+
+ aspacem_assert(j == nSegs); /* this should not fail */
+ return nSegs;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Sanity checking and preening of the segment array. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Check representational invariants for NSegments. */
+
+static Bool sane_NSegment ( NSegment* s )
+{
+ if (s == NULL) return False;
+
+ /* No zero sized segments and no wraparounds. */
+ if (s->start >= s->end) return False;
+
+ /* .mark is used for admin purposes only. */
+ if (s->mark) return False;
+
+ /* require page alignment */
+ if (!VG_IS_PAGE_ALIGNED(s->start)) return False;
+ if (!VG_IS_PAGE_ALIGNED(s->end+1)) return False;
+
+ switch (s->kind) {
+
+ case SkFree:
+ return
+ s->smode == SmFixed
+ && s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx ==
-1
+ && !s->hasR && !s->hasW && !s->hasX && !s->hasT
+ && !s->isCH;
+
+ case SkAnonC: case SkAnonV: case SkShmC:
+ return
+ s->smode == SmFixed
+ && s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx ==
-1
+ && (s->kind==SkAnonC ? True : !s->isCH);
+
+ case SkFileC: case SkFileV:
+ return
+ s->smode == SmFixed
+ && (s->fnIdx == -1 ||
+ (s->fnIdx >= 0 && s->fnIdx < segnames_used
+ && segnames[s->fnIdx].inUse))
+ && !s->isCH;
+
+ case SkResvn:
+ return
+ s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1
+ && !s->hasR && !s->hasW && !s->hasX && !s->hasT
+ && !s->isCH;
+
+ default:
+ return False;
+ }
+}
+
+
+/* Try merging s2 into s1, if possible. If successful, s1 is
+ modified, and True is returned. Otherwise s1 is unchanged and
+ False is returned. */
+
+static Bool maybe_merge_nsegments ( NSegment* s1, NSegment* s2 )
+{
+ if (s1->kind != s2->kind)
+ return False;
+
+ if (s1->end+1 != s2->start)
+ return False;
+
+ /* reject cases which would cause wraparound */
+ if (s1->start > s2->end)
+ return False;
+
+ switch (s1->kind) {
+
+ case SkFree:
+ s1->end = s2->end;
+ return True;
+
+ case SkAnonC: case SkAnonV:
+ if (s1->hasR == s2->hasR && s1->hasW == s2->hasW
+ && s1->hasX == s2->hasX && s1->isCH == s2->isCH) {
+ s1->end = s2->end;
+ s1->hasT |= s2->hasT;
+ return True;
+ }
+ break;
+
+ case SkFileC: case SkFileV:
+ if (s1->hasR == s2->hasR
+ && s1->hasW == s2->hasW && s1->hasX == s2->hasX
+ && s1->dev == s2->dev && s1->ino == s2->ino
+ && s2->offset == s1->offset
+ + ((ULong)s2->start) - ((ULong)s1->start) ) {
+ s1->end = s2->end;
+ s1->hasT |= s2->hasT;
+ return True;
+ }
+ break;
+
+ case SkShmC:
+ return False;
+
+ case SkResvn:
+ if (s1->smode == SmFixed && s2->smode == SmFixed) {
+ s1->end = s2->end;
+ return True;
+ }
+
+ default:
+ break;
+
+ }
+
+ return False;
+}
+
+
+/* Sanity-check and canonicalise the segment array (merge mergable
+ segments). Returns True if any segments were merged. */
+
+static Bool preen_nsegments ( void )
+{
+ Int i, j, r, w, nsegments_used_old = nsegments_used;
+
+ /* Pass 1: check the segment array covers the entire address space
+ exactly once, and also that each segment is sane. */
+ aspacem_assert(nsegments_used > 0);
+ aspacem_assert(nsegments[0].start == Addr_MIN);
+ aspacem_assert(nsegments[nsegments_used-1].end == Addr_MAX);
+
+ aspacem_assert(sane_NSegment(&nsegments[0]));
+ for (i = 1; i < nsegments_used; i++) {
+ aspacem_assert(sane_NSegment(&nsegments[i]));
+ aspacem_assert(nsegments[i-1].end+1 == nsegments[i].start);
+ }
+
+ /* Pass 2: merge as much as possible, using
+ maybe_merge_segments. */
+ w = 0;
+ for (r = 1; r < nsegments_used; r++) {
+ if (maybe_merge_nsegments(&nsegments[w], &nsegments[r])) {
+ /* nothing */
+ } else {
+ w++;
+ if (w != r)
+ nsegments[w] = nsegments[r];
+ }
+ }
+ w++;
+ aspacem_assert(w > 0 && w <= nsegments_used);
+ nsegments_used = w;
+
+ /* Pass 3: free up unused string table slots */
+ /* clear mark bits */
+ for (i = 0; i < segnames_used; i++)
+ segnames[i].mark = False;
+ /* mark */
+ for (i = 0; i < nsegments_used; i++) {
+ j = nsegments[i].fnIdx;
+ aspacem_assert(j >= -1 && j < segnames_used);
+ if (j >= 0) {
+ aspacem_assert(segnames[j].inUse);
+ segnames[j].mark = True;
+ }
+ }
+ /* release */
+ for (i = 0; i < segnames_used; i++) {
+ if (segnames[i].mark == False) {
+ segnames[i].inUse = False;
+ segnames[i].fname[0] = 0;
+ }
+ }
+
+ return nsegments_used != nsegments_used_old;
+}
+
+
+/* Check the segment array corresponds with the kernel's view of
+ memory layout. sync_check_ok returns True if no anomalies were
+ found, else False. In the latter case the mismatching segments are
+ displayed.
+
+ The general idea is: we get the kernel to show us all its segments
+ and also the gaps in between. For each such interval, try and find
+ a sequence of appropriate intervals in our segment array which
+ cover or more than cover the kernel's interval, and which all have
+ suitable kinds/permissions etc.
+
+ Although any specific kernel interval is not matched exactly to a
+ valgrind interval or sequence thereof, eventually any disagreement
+ on mapping boundaries will be detected. This is because, if for
+ example valgrind's intervals cover a greater range than the current
+ kernel interval, it must be the case that a neighbouring free-space
+ interval belonging to valgrind cannot cover the neighbouring
+ free-space interval belonging to the kernel. So the disagreement
+ is detected.
+
+ In other words, we examine each kernel interval in turn, and check
+ we do not disagree over the range of that interval. Because all of
+ the address space is examined, any disagreements must eventually be
+ detected.
+*/
+
+static Bool sync_check_ok = False;
+
+static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt prot,
+ ULong dev, ULong ino, Off64T
offset,
+ const UChar* filename )
+{
+ Int iLo, iHi, i;
+ Bool sloppyXcheck;
+
+ /* If a problem has already been detected, don't continue comparing
+ segments, so as to avoid flooding the output with error
+ messages. */
+#if !defined(VGO_darwin)
+ /* GrP fixme not */
+ if (!sync_check_ok)
+ return;
+#endif
+ if (len == 0)
+ return;
+
+ /* The kernel should not give us wraparounds. */
+ aspacem_assert(addr <= addr + len - 1);
+
+ iLo = find_nsegment_idx( addr );
+ iHi = find_nsegment_idx( addr + len - 1 );
+
+ /* These 5 should be guaranteed by find_nsegment_idx. */
+ aspacem_assert(0 <= iLo && iLo < nsegments_used);
+ aspacem_assert(0 <= iHi && iHi < nsegments_used);
+ aspacem_assert(iLo <= iHi);
+ aspacem_assert(nsegments[iLo].start <= addr );
+ aspacem_assert(nsegments[iHi].end >= addr + len - 1 );
+
+ /* x86 doesn't differentiate 'x' and 'r' (at least, all except the
+ most recent NX-bit enabled CPUs) and so recent kernels attempt
+ to provide execute protection by placing all executable mappings
+ low down in the address space and then reducing the size of the
+ code segment to prevent code at higher addresses being executed.
+
+ These kernels report which mappings are really executable in
+ the /proc/self/maps output rather than mirroring what was asked
+ for when each mapping was created. In order to cope with this we
+ have a sloppyXcheck mode which we enable on x86 and s390 - in this
+ mode we allow the kernel to report execute permission when we weren't
+ expecting it but not vice versa. */
+# if defined(VGA_x86) || defined (VGA_s390x)
+ sloppyXcheck = True;
+# else
+ sloppyXcheck = False;
+# endif
+
+ /* NSegments iLo .. iHi inclusive should agree with the presented
+ data. */
+ for (i = iLo; i <= iHi; i++) {
+
+ Bool same, cmp_offsets, cmp_devino;
+ UInt seg_prot;
+
+ /* compare the kernel's offering against ours. */
+ same = nsegments[i].kind == SkAnonC
+ || nsegments[i].kind == SkAnonV
+ || nsegments[i].kind == SkFileC
+ || nsegments[i].kind == SkFileV
+ || nsegments[i].kind == SkShmC;
+
+ seg_prot = 0;
+ if (nsegments[i].hasR) seg_prot |= VKI_PROT_READ;
+ if (nsegments[i].hasW) seg_prot |= VKI_PROT_WRITE;
+ if (nsegments[i].hasX) seg_prot |= VKI_PROT_EXEC;
+
+ cmp_offsets
+ = nsegments[i].kind == SkFileC || nsegments[i].kind == SkFileV;
+
+ cmp_devino
+ = nsegments[i].dev != 0 || nsegments[i].ino != 0;
+
+ /* Consider other reasons to not compare dev/inode */
+#if defined(VGO_linux)
+ /* bproc does some godawful hack on /dev/zero at process
+ migration, which changes the name of it, and its dev & ino */
+ if (filename && 0==VG_(strcmp)(filename, "/dev/zero (deleted)"))
+ cmp_devino = False;
+
+ /* hack apparently needed on MontaVista Linux */
+ if (filename && VG_(strstr)(filename, "/.lib-ro/"))
+ cmp_devino = False;
+#endif
+
+#if defined(VGO_darwin)
+ // GrP fixme kernel info doesn't have dev/inode
+ cmp_devino = False;
+
+ // GrP fixme V and kernel don't agree on offsets
+ cmp_offsets = False;
+#endif
+
+ /* If we are doing sloppy execute permission checks then we
+ allow segment to have X permission when we weren't expecting
+ it (but not vice versa) so if the kernel reported execute
+ permission then pretend that this segment has it regardless
+ of what we were expecting. */
+ if (sloppyXcheck && (prot & VKI_PROT_EXEC) != 0) {
+ seg_prot |= VKI_PROT_EXEC;
+ }
+
+ same = same
+ && seg_prot == prot
+ && (cmp_devino
+ ? (nsegments[i].dev == dev && nsegments[i].ino == ino)
+ : True)
+ && (cmp_offsets
+ ? nsegments[i].start-nsegments[i].offset == addr-offset
+ : True);
+ if (!same) {
+ Addr start = addr;
+ Addr end = start + len - 1;
+ HChar len_buf[20];
+ show_len_concisely(len_buf, start, end);
+
+ sync_check_ok = False;
+
+ VG_(debugLog)(
+ 0,"aspacem",
+ "segment mismatch: V's seg 1st, kernel's 2nd:\n");
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_cache.c Thu Nov 22 04:55:39 2012
@@ -0,0 +1,792 @@
+/* -*- mode: C; c-basic-offset: 3; -*- */
+
+/*--------------------------------------------------------------------*/
+/*--- Cache-related stuff. m_cache.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2002-2012 Nicholas Nethercote
+ n...@valgrind.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_mallocfree.h"
+#include "pub_core_machine.h"
+#include "pub_core_debuglog.h"
+#include "libvex.h"
+
+#if defined(VGA_x86) || defined(VGA_amd64)
+
+#include "pub_core_cpuid.h"
+
+// All CPUID info taken from sandpile.org/ia32/cpuid.htm */
+// Probably only works for Intel and AMD chips, and probably only for some
of
+// them.
+
+static void
+add_cache(VexCacheInfo *ci, VexCache cache)
+{
+ static UInt num_allocated = 0;
+
+ if (ci->num_caches == num_allocated) {
+ num_allocated += 6;
+ ci->caches = VG_(realloc)("m_cache", ci->caches,
+ num_allocated * sizeof *ci->caches);
+ }
+
+ if (ci->num_levels < cache.level) ci->num_levels = cache.level;
+ ci->caches[ci->num_caches++] = cache;
+}
+
+/* Convenience macros */
+#define add_icache(level, size, assoc, linesize) \
+ do { \
+ add_cache(ci, \
+ VEX_CACHE_INIT(INSN_CACHE, level, size, linesize, assoc));
\
+ } while (0)
+
+#define add_dcache(level, size, assoc, linesize) \
+ do { \
+ add_cache(ci, \
+ VEX_CACHE_INIT(DATA_CACHE, level, size, linesize, assoc));
\
+ } while (0)
+
+#define add_ucache(level, size, assoc, linesize) \
+ do { \
+ add_cache(ci, \
+ VEX_CACHE_INIT(UNIFIED_CACHE, level, size, linesize,
assoc)); \
+ } while (0)
+
+#define add_itcache(level, size, assoc) \
+ do { \
+ VexCache c = \
+ VEX_CACHE_INIT(INSN_CACHE, level, size, 0, assoc); \
+ c.is_trace_cache = True; \
+ add_cache(ci, c); \
+ } while (0)
+
+#define add_I1(size, assoc, linesize) add_icache(1, size, assoc, linesize)
+#define add_D1(size, assoc, linesize) add_dcache(1, size, assoc, linesize)
+#define add_U1(size, assoc, linesize) add_ucache(1, size, assoc, linesize)
+#define add_I2(size, assoc, linesize) add_icache(2, size, assoc, linesize)
+#define add_D2(size, assoc, linesize) add_dcache(2, size, assoc, linesize)
+#define add_U2(size, assoc, linesize) add_ucache(2, size, assoc, linesize)
+#define add_I3(size, assoc, linesize) add_icache(3, size, assoc, linesize)
+#define add_D3(size, assoc, linesize) add_dcache(3, size, assoc, linesize)
+#define add_U3(size, assoc, linesize) add_ucache(3, size, assoc, linesize)
+
+#define add_I1T(size, assoc) \
+ add_itcache(1, size, assoc)
+
+/* Intel method is truly wretched. We have to do an insane indexing into
an
+ * array of pre-defined configurations for various parts of the memory
+ * hierarchy.
+ * According to Intel Processor Identification, App Note 485.
+ *
+ * If a L3 cache is found, then data for it rather than the L2
+ * is returned via *LLc.
+ */
+static Int
+Intel_cache_info(Int level, VexCacheInfo *ci)
+{
+ UInt cpuid1_eax;
+ UInt cpuid1_ignore;
+ Int family;
+ Int model;
+ UChar info[16];
+ Int i, j, trials;
+
+ if (level < 2) {
+ VG_(debugLog)(1, "cache", "warning: CPUID level < 2 for Intel "
+ "processor (%d)\n", level);
+ return -1;
+ }
+
+ /* family/model needed to distinguish code reuse (currently 0x49) */
+ VG_(cpuid)(1, 0, &cpuid1_eax, &cpuid1_ignore,
+ &cpuid1_ignore, &cpuid1_ignore);
+ family = (((cpuid1_eax >> 20) & 0xff) << 4) + ((cpuid1_eax >> 8) & 0xf);
+ model = (((cpuid1_eax >> 16) & 0xf) << 4) + ((cpuid1_eax >> 4) & 0xf);
+
+ VG_(cpuid)(2, 0, (UInt*)&info[0], (UInt*)&info[4],
+ (UInt*)&info[8], (UInt*)&info[12]);
+ trials = info[0] - 1; /* AL register - bits 0..7 of %eax */
+ info[0] = 0x0; /* reset AL */
+
+ if (0 != trials) {
+ VG_(debugLog)(1, "cache", "warning: non-zero CPUID trials for Intel "
+ "processor (%d)\n", trials);
+ return -1;
+ }
+
+ ci->num_levels = 0;
+ ci->num_caches = 0;
+ ci->icaches_maintain_coherence = True;
+ ci->caches = NULL;
+
+ for (i = 0; i < 16; i++) {
+
+ switch (info[i]) {
+
+ case 0x0: /* ignore zeros */
+ break;
+
+ /* TLB info, ignore */
+ case 0x01: case 0x02: case 0x03: case 0x04: case 0x05:
+ case 0x0b:
+ case 0x4f: case 0x50: case 0x51: case 0x52: case 0x55:
+ case 0x56: case 0x57: case 0x59:
+ case 0x5a: case 0x5b: case 0x5c: case 0x5d:
+ case 0x76:
+ case 0xb0: case 0xb1: case 0xb2:
+ case 0xb3: case 0xb4: case 0xba: case 0xc0:
+ case 0xca:
+ break;
+
+ case 0x06: add_I1( 8, 4, 32); break;
+ case 0x08: add_I1(16, 4, 32); break;
+ case 0x09: add_I1(32, 4, 64); break;
+ case 0x30: add_I1(32, 8, 64); break;
+
+ case 0x0a: add_D1( 8, 2, 32); break;
+ case 0x0c: add_D1(16, 4, 32); break;
+ case 0x0d: add_D1(16, 4, 64); break;
+ case 0x0e: add_D1(24, 6, 64); break;
+ case 0x2c: add_D1(32, 8, 64); break;
+
+ /* IA-64 info -- panic! */
+ case 0x10: case 0x15: case 0x1a:
+ case 0x88: case 0x89: case 0x8a: case 0x8d:
+ case 0x90: case 0x96: case 0x9b:
+ VG_(core_panic)("IA-64 cache detected?!");
+
+ /* L3 cache info. */
+ case 0x22: add_U3(512, 4, 64); break;
+ case 0x23: add_U3(1024, 8, 64); break;
+ case 0x25: add_U3(2048, 8, 64); break;
+ case 0x29: add_U3(4096, 8, 64); break;
+ case 0x46: add_U3(4096, 4, 64); break;
+ case 0x47: add_U3(8192, 8, 64); break;
+ case 0x4a: add_U3(6144, 12, 64); break;
+ case 0x4b: add_U3(8192, 16, 64); break;
+ case 0x4c: add_U3(12288, 12, 64); break;
+ case 0x4d: add_U3(16384, 16, 64); break;
+ case 0xd0: add_U3(512, 4, 64); break;
+ case 0xd1: add_U3(1024, 4, 64); break;
+ case 0xd2: add_U3(2048, 4, 64); break;
+ case 0xd6: add_U3(1024, 8, 64); break;
+ case 0xd7: add_U3(2048, 8, 64); break;
+ case 0xd8: add_U3(4096, 8, 64); break;
+ case 0xdc: add_U3(1536, 12, 64); break;
+ case 0xdd: add_U3(3072, 12, 64); break;
+ case 0xde: add_U3(6144, 12, 64); break;
+ case 0xe2: add_U3(2048, 16, 64); break;
+ case 0xe3: add_U3(4096, 16, 64); break;
+ case 0xe4: add_U3(8192, 16, 64); break;
+ case 0xea: add_U3(12288, 24, 64); break;
+ case 0xeb: add_U3(18432, 24, 64); break;
+ case 0xec: add_U3(24576, 24, 64); break;
+
+ /* Described as "MLC" in Intel documentation */
+ case 0x21: add_U2(256, 8, 64); break;
+
+ /* These are sectored, whatever that means */
+ // FIXME: I did not find these in the Intel docs
+ case 0x39: add_U2(128, 4, 64); break;
+ case 0x3c: add_U2(256, 4, 64); break;
+
+ /* If a P6 core, this means "no L2 cache".
+ If a P4 core, this means "no L3 cache".
+ We don't know what core it is, so don't issue a warning. To
detect
+ a missing L2 cache, we use 'L2_found'. */
+ case 0x40:
+ break;
+
+ case 0x41: add_U2( 128, 4, 32); break;
+ case 0x42: add_U2( 256, 4, 32); break;
+ case 0x43: add_U2( 512, 4, 32); break;
+ case 0x44: add_U2( 1024, 4, 32); break;
+ case 0x45: add_U2( 2048, 4, 32); break;
+ case 0x48: add_U2( 3072, 12, 64); break;
+ case 0x4e: add_U2( 6144, 24, 64); break;
+ case 0x49:
+ if (family == 15 && model == 6) {
+ /* On Xeon MP (family F, model 6), this is for L3 */
+ add_U3(4096, 16, 64);
+ } else {
+ add_U2(4096, 16, 64);
+ }
+ break;
+
+ /* These are sectored, whatever that means */
+ case 0x60: add_D1(16, 8, 64); break; /* sectored */
+ case 0x66: add_D1( 8, 4, 64); break; /* sectored */
+ case 0x67: add_D1(16, 4, 64); break; /* sectored */
+ case 0x68: add_D1(32, 4, 64); break; /* sectored */
+
+ /* HACK ALERT: Instruction trace cache -- capacity is micro-ops
based.
+ * conversion to byte size is a total guess; treat the 12K and 16K
+ * cases the same since the cache byte size must be a power of two
for
+ * everything to work!. Also guessing 32 bytes for the line size...
+ */
+ case 0x70: /* 12K micro-ops, 8-way */
+ add_I1T(12, 8);
+ break;
+ case 0x71: /* 16K micro-ops, 8-way */
+ add_I1T(16, 8);
+ break;
+ case 0x72: /* 32K micro-ops, 8-way */
+ add_I1T(32, 8);
+ break;
+
+ /* not sectored, whatever that might mean */
+ case 0x78: add_U2(1024, 4, 64); break;
+
+ /* These are sectored, whatever that means */
+ case 0x79: add_U2( 128, 8, 64); break;
+ case 0x7a: add_U2( 256, 8, 64); break;
+ case 0x7b: add_U2( 512, 8, 64); break;
+ case 0x7c: add_U2(1024, 8, 64); break;
+ case 0x7d: add_U2(2048, 8, 64); break;
+ case 0x7e: add_U2( 256, 8, 128); break;
+ case 0x7f: add_U2( 512, 2, 64); break;
+ case 0x80: add_U2( 512, 8, 64); break;
+ case 0x81: add_U2( 128, 8, 32); break;
+ case 0x82: add_U2( 256, 8, 32); break;
+ case 0x83: add_U2( 512, 8, 32); break;
+ case 0x84: add_U2(1024, 8, 32); break;
+ case 0x85: add_U2(2048, 8, 32); break;
+ case 0x86: add_U2( 512, 4, 64); break;
+ case 0x87: add_U2(1024, 8, 64); break;
+
+ /* Ignore prefetch information */
+ case 0xf0: case 0xf1:
+ break;
+
+ case 0xff:
+ j = 0;
+ VG_(cpuid)(4, j++, (UInt*)&info[0], (UInt*)&info[4],
+ (UInt*)&info[8], (UInt*)&info[12]);
+
+ while ((info[0] & 0x1f) != 0) {
+ UInt assoc = ((*(UInt *)&info[4] >> 22) & 0x3ff) + 1;
+ UInt parts = ((*(UInt *)&info[4] >> 12) & 0x3ff) + 1;
+ UInt line_size = (*(UInt *)&info[4] & 0x7ff) + 1;
+ UInt sets = *(UInt *)&info[8] + 1;
+
+ UInt size = assoc * parts * line_size * sets / 1024;
+
+ switch ((info[0] & 0xe0) >> 5)
+ {
+ case 1:
+ switch (info[0] & 0x1f)
+ {
+ case 1: add_D1(size, assoc, line_size); break;
+ case 2: add_I1(size, assoc, line_size); break;
+ case 3: add_U1(size, assoc, line_size); break;
+ default:
+ VG_(debugLog)(1, "cache",
+ "warning: L1 cache of unknown type
ignored\n");
+ break;
+ }
+ break;
+ case 2:
+ switch (info[0] & 0x1f)
+ {
+ case 1: add_D2(size, assoc, line_size); break;
+ case 2: add_I2(size, assoc, line_size); break;
+ case 3: add_U2(size, assoc, line_size); break;
+ default:
+ VG_(debugLog)(1, "cache",
+ "warning: L2 cache of unknown type
ignored\n");
+ break;
+ }
+ break;
+ case 3:
+ switch (info[0] & 0x1f)
+ {
+ case 1: add_D3(size, assoc, line_size); break;
+ case 2: add_I3(size, assoc, line_size); break;
+ case 3: add_U3(size, assoc, line_size); break;
+ default:
+ VG_(debugLog)(1, "cache",
+ "warning: L3 cache of unknown type
ignored\n");
+ break;
+ }
+ break;
+ default:
+ VG_(debugLog)(1, "cache", "warning: L%u cache ignored\n",
+ (info[0] & 0xe0) >> 5);
+ break;
+ }
+
+ VG_(cpuid)(4, j++, (UInt*)&info[0], (UInt*)&info[4],
+ (UInt*)&info[8], (UInt*)&info[12]);
+ }
+ break;
+
+ default:
+ VG_(debugLog)(1, "cache",
+ "warning: Unknown Intel cache config value (0x%x), "
+ "ignoring\n", info[i]);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/* AMD method is straightforward, just extract appropriate bits from the
+ * result registers.
+ *
+ * Bits, for D1 and I1:
+ * 31..24 data L1 cache size in KBs
+ * 23..16 data L1 cache associativity (FFh=full)
+ * 15.. 8 data L1 cache lines per tag
+ * 7.. 0 data L1 cache line size in bytes
+ *
+ * Bits, for L2:
+ * 31..16 unified L2 cache size in KBs
+ * 15..12 unified L2 cache associativity (0=off, FFh=full)
+ * 11.. 8 unified L2 cache lines per tag
+ * 7.. 0 unified L2 cache line size in bytes
+ *
+ * #3 The AMD K7 processor's L2 cache must be configured prior to relying
+ * upon this information. (Whatever that means -- njn)
+ *
+ * Also, according to Cyrille Chepelov, Duron stepping A0 processors (model
+ * 0x630) have a bug and misreport their L2 size as 1KB (it's really 64KB),
+ * so we detect that.
+ *
+ * Returns 0 on success, non-zero on failure. As with the Intel code
+ * above, if a L3 cache is found, then data for it rather than the L2
+ * is returned via *LLc.
+ */
+
+/* A small helper */
+static Int
+decode_AMD_cache_L2_L3_assoc ( Int bits_15_12 )
+{
+ /* Decode a L2/L3 associativity indication. It is encoded
+ differently from the I1/D1 associativity. Returns 1
+ (direct-map) as a safe but suboptimal result for unknown
+ encodings. */
+ switch (bits_15_12 & 0xF) {
+ case 1: return 1; case 2: return 2;
+ case 4: return 4; case 6: return 8;
+ case 8: return 16; case 0xA: return 32;
+ case 0xB: return 48; case 0xC: return 64;
+ case 0xD: return 96; case 0xE: return 128;
+ case 0xF: /* fully associative */
+ case 0: /* L2/L3 cache or TLB is disabled */
+ default:
+ return 1;
+ }
+}
+
+static Int
+AMD_cache_info(VexCacheInfo *ci)
+{
+ UInt ext_level;
+ UInt dummy, model;
+ UInt I1i, D1i, L2i, L3i;
+ UInt size, line_size, assoc;
+
+ VG_(cpuid)(0x80000000, 0, &ext_level, &dummy, &dummy, &dummy);
+
+ if (0 == (ext_level & 0x80000000) || ext_level < 0x80000006) {
+ VG_(debugLog)(1, "cache", "warning: ext_level < 0x80000006 for AMD "
+ "processor (0x%x)\n", ext_level);
+ return -1;
+ }
+
+ VG_(cpuid)(0x80000005, 0, &dummy, &dummy, &D1i, &I1i);
+ VG_(cpuid)(0x80000006, 0, &dummy, &dummy, &L2i, &L3i);
+
+ VG_(cpuid)(0x1, 0, &model, &dummy, &dummy, &dummy);
+
+ /* Check for Duron bug */
+ if (model == 0x630) {
+ VG_(debugLog)(1, "cache", "warning: Buggy Duron stepping A0. "
+ "Assuming L2 size=65536 bytes\n");
+ L2i = (64 << 16) | (L2i & 0xffff);
+ }
+
+ ci->num_levels = 2;
+ ci->num_caches = 3;
+ ci->icaches_maintain_coherence = True;
+
+ /* Check for L3 cache */
+ if (((L3i >> 18) & 0x3fff) > 0) {
+ ci->num_levels = 3;
+ ci->num_caches = 4;
+ }
+
+ ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof
*ci->caches);
+
+ // D1
+ size = (D1i >> 24) & 0xff;
+ assoc = (D1i >> 16) & 0xff;
+ line_size = (D1i >> 0) & 0xff;
+ ci->caches[0] = VEX_CACHE_INIT(DATA_CACHE, 1, size, line_size, assoc);
+
+ // I1
+ size = (I1i >> 24) & 0xff;
+ assoc = (I1i >> 16) & 0xff;
+ line_size = (I1i >> 0) & 0xff;
+ ci->caches[1] = VEX_CACHE_INIT(INSN_CACHE, 1, size, line_size, assoc);
+
+ // L2 Nb: different bits used for L2
+ size = (L2i >> 16) & 0xffff;
+ assoc = decode_AMD_cache_L2_L3_assoc((L2i >> 12) & 0xf);
+ line_size = (L2i >> 0) & 0xff;
+ ci->caches[2] = VEX_CACHE_INIT(UNIFIED_CACHE, 2, size, line_size,
assoc);
+
+ // L3, if any
+ if (((L3i >> 18) & 0x3fff) > 0) {
+ /* There's an L3 cache. */
+ /* NB: the test in the if is "if L3 size > 0 ". I don't know if
+ this is the right way to test presence-vs-absence of L3. I
+ can't see any guidance on this in the AMD documentation. */
+ size = ((L3i >> 18) & 0x3fff) * 512;
+ assoc = decode_AMD_cache_L2_L3_assoc((L3i >> 12) & 0xf);
+ line_size = (L3i >> 0) & 0xff;
+ ci->caches[3] = VEX_CACHE_INIT(UNIFIED_CACHE, 3, size, line_size,
assoc);
+ }
+
+ return 0;
+}
+
+static Int
+get_caches_from_CPUID(VexCacheInfo *ci)
+{
+ Int ret, i;
+ UInt level;
+ HChar vendor_id[13];
+
+ vg_assert(VG_(has_cpuid)());
+
+ VG_(cpuid)(0, 0, &level, (UInt*)&vendor_id[0],
+ (UInt*)&vendor_id[8], (UInt*)&vendor_id[4]);
+ vendor_id[12] = '\0';
+
+ if (0 == level) { // CPUID level is 0, early Pentium?
+ return -1;
+ }
+
+ /* Only handling Intel and AMD chips... no Cyrix, Transmeta, etc */
+ if (0 == VG_(strcmp)(vendor_id, "GenuineIntel")) {
+ ret = Intel_cache_info(level, ci);
+
+ } else if (0 == VG_(strcmp)(vendor_id, "AuthenticAMD")) {
+ ret = AMD_cache_info(ci);
+
+ } else if (0 == VG_(strcmp)(vendor_id, "CentaurHauls")) {
+ /* Total kludge. Pretend to be a VIA Nehemiah. */
+ ci->num_levels = 2;
+ ci->num_caches = 3;
+ ci->icaches_maintain_coherence = True;
+ ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof
*ci->caches);
+ ci->caches[0] = VEX_CACHE_INIT(DATA_CACHE, 1, 64, 16, 16);
+ ci->caches[1] = VEX_CACHE_INIT(INSN_CACHE, 1, 64, 16, 4);
+ ci->caches[2] = VEX_CACHE_INIT(UNIFIED_CACHE, 2, 64, 16, 16);
+
+ ret = 0;
+
+ } else {
+ VG_(debugLog)(1, "cache", "CPU vendor ID not recognised (%s)\n",
+ vendor_id);
+ return -1;
+ }
+
+ /* Successful! Convert sizes from KB to bytes */
+ for (i = 0; i < ci->num_caches; ++i) {
+ ci->caches[i].sizeB *= 1024;
+ }
+
+ return ret;
+}
+
+static Bool
+get_cache_info(VexArchInfo *vai)
+{
+ Int ret = get_caches_from_CPUID(&vai->hwcache_info);
+
+ return ret == 0 ? True : False;
+}
+
+#elif defined(VGA_arm) || defined(VGA_ppc32) || defined(VGA_ppc64) || \
+ defined(VGA_mips32)
+
+static Bool
+get_cache_info(VexArchInfo *vai)
+{
+ vai->hwcache_info.icaches_maintain_coherence = False;
+
+ return False; // not yet
+}
+
+#elif defined(VGA_s390x)
+
+static ULong
+ecag(UInt ai, UInt li, UInt ti)
+{
+ register ULong result asm("2") = 0;
+ register ULong input asm("3") = (ai << 4) | (li << 1) | ti;
+
+ asm volatile(".short 0xeb20\n\t"
+ ".long 0x3000004c\n\t"
+ : "=d" (result) : "d" (input));
+
+ return result;
+}
+
+static UInt
+get_cache_info_for_level(ULong topology, UInt level)
+{
+ return (topology >> (56 - level * 8)) & 0xff;
+}
+
+static ULong
+get_line_size(UInt level, Bool is_insn_cache)
+{
+ return ecag(1, level, is_insn_cache);
+}
+
+static ULong
+get_total_size(UInt level, Bool is_insn_cache)
+{
+ return ecag(2, level, is_insn_cache);
+}
+
+static ULong
+get_associativity(UInt level, Bool is_insn_cache)
+{
+ return ecag(3, level, is_insn_cache);
+}
+
+static VexCache
+get_cache(UInt level, VexCacheKind kind)
+{
+ Bool is_insn_cache = kind == INSN_CACHE;
+ UInt size = get_total_size(level, is_insn_cache);
+ UInt line_size = get_line_size(level, is_insn_cache);
+ UInt assoc = get_associativity(level, is_insn_cache);
+
+ return VEX_CACHE_INIT(kind, level + 1, size, line_size, assoc);
+}
+
+static Bool
+get_cache_info(VexArchInfo *vai)
+{
+ VexCacheInfo *ci = &vai->hwcache_info;
+
+ ci->icaches_maintain_coherence = True;
+
+ if (! vai->hwcaps & VEX_HWCAPS_S390X_GIE) {
+ // ECAG is not available
+ return False;
+ }
+
+ UInt level, cache_kind, info, i;
+ ULong topology = ecag(0, 0, 0); // get summary
+
+ /* ECAG supports at most 8 levels of cache. Find out how many levels
+ of cache and how many caches there are. */
+ ci->num_levels = 0;
+ ci->num_caches = 0;
+ for (level = 0; level < 8; level++) {
+ info = get_cache_info_for_level(topology, level);
+
+ if ((info & 0xc) == 0) break; // cache does not exist at this level
+ ++ci->num_levels;
+
+ cache_kind = info & 0x3;
+ switch (cache_kind) {
+ case 0: ci->num_caches += 2; break; /* separate data and insn cache
*/
+ case 1: ci->num_caches += 1; break; /* only insn cache */
+ case 2: ci->num_caches += 1; break; /* only data cache */
+ case 3: ci->num_caches += 1; break; /* unified data and insn cache
*/
+ }
+ }
+
+ ci->caches = VG_(malloc)("m_cache", ci->num_caches * sizeof
*ci->caches);
+
+ i = 0;
+ for (level = 0; level < ci->num_levels; level++) {
+ info = get_cache_info_for_level(topology, level);
+ cache_kind = info & 0x3;
+ switch (cache_kind) {
+ case 0: /* separate data and insn cache */
+ ci->caches[i++] = get_cache(level, INSN_CACHE);
+ ci->caches[i++] = get_cache(level, DATA_CACHE);
+ break;
+
+ case 1: /* only insn cache */
+ ci->caches[i++] = get_cache(level, INSN_CACHE);
+ break;
+
+ case 2: /* only data cache */
+ ci->caches[i++] = get_cache(level, DATA_CACHE);
+ break;
+
+ case 3: /* unified data and insn cache */
+ ci->caches[i++] = get_cache(level, UNIFIED_CACHE);
+ break;
+ }
+ }
+ return True;
+}
+
+#else
+
+#error "Unknown arch"
+
+#endif
+
+/* Debug information */
+static void
+write_cache_info(const VexCacheInfo *ci)
+{
+ UInt i;
+
+ VG_(debugLog)(1, "cache", "Cache info:\n");
+ VG_(debugLog)(1, "cache", " #levels = %u\n", ci->num_levels);
+ VG_(debugLog)(1, "cache", " #caches = %u\n", ci->num_caches);
+ for (i = 0; i < ci->num_caches; ++i) {
+ VexCache *c = ci->caches + i;
+ const HChar *kind;
+ VG_(debugLog)(1, "cache", " cache #%u:\n", i);
+ switch (c->kind) {
+ case INSN_CACHE: kind = "insn"; break;
+ case DATA_CACHE: kind = "data"; break;
+ case UNIFIED_CACHE: kind = "unified"; break;
+ default: kind = "unknown"; break;
+ }
+ VG_(debugLog)(1, "cache", " kind = %s\n", kind);
+ VG_(debugLog)(1, "cache", " level = %u\n", c->level);
+ VG_(debugLog)(1, "cache", " size = %u bytes\n", c->sizeB);
+ VG_(debugLog)(1, "cache", " linesize = %u bytes\n",
c->line_sizeB);
+ VG_(debugLog)(1, "cache", " assoc = %u\n", c->assoc);
+ }
+}
+
+static Bool
+cache_info_is_sensible(const VexCacheInfo *ci)
+{
+ UInt level, i;
+ Bool sensible = True;
+
+ /* There must be at most one cache of a given kind at the same level.
+ If there is a unified cache at a given level, no other cache may
+ exist at that level. */
+ for (level = 1; level <= ci->num_levels; ++level) {
+ UInt num_icache, num_dcache, num_ucache;
+
+ num_icache = num_dcache = num_ucache = 0;
+ for (i = 0; i < ci->num_caches; ++i) {
+ if (ci->caches[i].level == level) {
+ switch (ci->caches[i].kind) {
+ case INSN_CACHE: ++num_icache; break;
+ case DATA_CACHE: ++num_dcache; break;
+ case UNIFIED_CACHE: ++num_ucache; break;
+ }
+ }
+ }
+ if (num_icache == 0 && num_dcache == 0 && num_ucache == 0) {
+ VG_(debugLog)(1, "cache", "warning: No caches at level %u\n",
level);
+ sensible = False;
+ }
+ if (num_icache > 1 || num_dcache > 1 || num_ucache > 1) {
+ VG_(debugLog)(1, "cache", "warning: More than one cache of a
given "
+ "kind at level %u\n", level);
+ sensible = False;
+ }
+ if (num_ucache != 0 && (num_icache > 0 || num_dcache > 0)) {
+ VG_(debugLog)(1, "cache", "warning: Unified cache and I/D cache "
+ "at level %u\n", level);
+ sensible = False;
+ }
+ }
+
+ /* If there is a cache at level N > 1 there must be a cache at level
N-1 */
+ for (level = 2; level <= ci->num_levels; ++level) {
+ Bool found = False;
+ for (i = 0; i < ci->num_caches; ++i) {
+ if (ci->caches[i].level == level - 1) {
+ found = True;
+ break;
+ }
+ }
+ if (! found) {
+ VG_(debugLog)(1, "cache", "warning: Cache at level %u but no
cache "
+ "at level %u\n", level, level - 1);
+ sensible = False;
+ }
+ }
+
+ return sensible;
+}
+
+
+/* Autodetect the cache information for this host and stuff it into
+ VexArchInfo::hwcache_info. Return True if successful. */
+Bool
+VG_(machine_get_cache_info)(VexArchInfo *vai)
+{
+ Bool ok = get_cache_info(vai);
+
+ VexCacheInfo *ci = &vai->hwcache_info;
+
+ if (! ok) {
+ VG_(debugLog)(1, "cache", "Could not autodetect cache info\n");
+ } else {
+ ok = cache_info_is_sensible(ci);
+
+ if (! ok) {
+ VG_(debugLog)(1, "cache",
+ "Autodetected cache info is not sensible\n");
+ } else {
+ VG_(debugLog)(1, "cache",
+ "Autodetected cache info is sensible\n");
+ }
+ write_cache_info(ci); /* write out for debugging */
+ }
+
+ if (! ok ) {
+ /* Reset cache info */
+ ci->num_levels = 0;
+ ci->num_caches = 0;
+ VG_(free)(ci->caches);
+ ci->caches = NULL;
+ }
+
+ return ok;
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_debuginfo/readelf.c.orig Thu Nov 22
04:55:39 2012
@@ -0,0 +1,2613 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Reading of syms & debug info from ELF .so/executable files. ---*/
+/*--- readelf.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2011 Julian Seward
+ jse...@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#if defined(VGO_linux)
+
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_debuginfo.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcfile.h"
+#include "pub_core_aspacemgr.h" /* for mmaping debuginfo files */
+#include "pub_core_machine.h" /* VG_ELF_CLASS */
+#include "pub_core_mallocfree.h"
+#include "pub_core_options.h"
+#include "pub_core_oset.h"
+#include "pub_core_tooliface.h" /* VG_(needs) */
+#include "pub_core_xarray.h"
+#include "priv_misc.h" /* dinfo_zalloc/free/strdup */
+#include "priv_d3basics.h"
+#include "priv_tytypes.h"
+#include "priv_storage.h"
+#include "priv_readelf.h" /* self */
+#include "priv_readdwarf.h" /* 'cos ELF contains DWARF */
+#include "priv_readdwarf3.h"
+#include "priv_readstabs.h" /* and stabs, if we're unlucky */
+
+/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
+#include <elf.h>
+/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
+
+/*------------------------------------------------------------*/
+/*--- 32/64-bit parameterisation ---*/
+/*------------------------------------------------------------*/
+
+/* For all the ELF macros and types which specify '32' or '64',
+ select the correct variant for this platform and give it
+ an 'XX' name. Then use the 'XX' variant consistently in
+ the rest of this file.
+*/
+#if VG_WORDSIZE == 4
+# define ElfXX_Ehdr Elf32_Ehdr
+# define ElfXX_Shdr Elf32_Shdr
+# define ElfXX_Phdr Elf32_Phdr
+# define ElfXX_Nhdr Elf32_Nhdr
+# define ElfXX_Sym Elf32_Sym
+# define ElfXX_Off Elf32_Off
+# define ElfXX_Word Elf32_Word
+# define ElfXX_Addr Elf32_Addr
+# define ElfXX_Dyn Elf32_Dyn
+# define ELFXX_ST_BIND ELF32_ST_BIND
+# define ELFXX_ST_TYPE ELF32_ST_TYPE
+
+#elif VG_WORDSIZE == 8
+# define ElfXX_Ehdr Elf64_Ehdr
+# define ElfXX_Shdr Elf64_Shdr
+# define ElfXX_Phdr Elf64_Phdr
+# define ElfXX_Nhdr Elf64_Nhdr
+# define ElfXX_Sym Elf64_Sym
+# define ElfXX_Off Elf64_Off
+# define ElfXX_Word Elf64_Word
+# define ElfXX_Addr Elf64_Addr
+# define ElfXX_Dyn Elf64_Dyn
+# define ELFXX_ST_BIND ELF64_ST_BIND
+# define ELFXX_ST_TYPE ELF64_ST_TYPE
+
+#else
+# error "VG_WORDSIZE should be 4 or 8"
+#endif
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- Read symbol table and line info from ELF files. ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+/* readelf.c parses ELF files and acquires symbol table info from
+ them. It calls onwards to readdwarf.c to read DWARF2/3 line number
+ and call frame info found. */
+
+
+/* Identify an ELF object file by peering at the first few bytes of
+ it. */
+
+Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
+{
+ ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
+ Int ok = 1;
+
+ if (n_image < sizeof(ElfXX_Ehdr))
+ return False;
+
+ ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
+ && ehdr->e_ident[EI_MAG1] == 'E'
+ && ehdr->e_ident[EI_MAG2] == 'L'
+ && ehdr->e_ident[EI_MAG3] == 'F');
+ ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
+ && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX
+ && ehdr->e_ident[EI_VERSION] == EV_CURRENT);
+ ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
+ ok &= (ehdr->e_machine == VG_ELF_MACHINE);
+ ok &= (ehdr->e_version == EV_CURRENT);
+ ok &= (ehdr->e_shstrndx != SHN_UNDEF);
+ ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0);
+ ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0);
+
+ if (ok)
+ return True;
+ else
+ return False;
+}
+
+
+/* Show a raw ELF symbol, given its in-image address and name. */
+
+static
+void show_raw_elf_symbol ( Int i,
+ ElfXX_Sym* sym, Char* sym_name, Addr sym_svma,
+ Bool ppc64_linux_format )
+{
+ HChar* space = ppc64_linux_format ? " " : "";
+ VG_(printf)("raw symbol [%4d]: ", i);
+ switch (ELFXX_ST_BIND(sym->st_info)) {
+ case STB_LOCAL: VG_(printf)("LOC "); break;
+ case STB_GLOBAL: VG_(printf)("GLO "); break;
+ case STB_WEAK: VG_(printf)("WEA "); break;
+ case STB_LOPROC: VG_(printf)("lop "); break;
+ case STB_HIPROC: VG_(printf)("hip "); break;
+ default: VG_(printf)("??? "); break;
+ }
+ switch (ELFXX_ST_TYPE(sym->st_info)) {
+ case STT_NOTYPE: VG_(printf)("NOT "); break;
+ case STT_OBJECT: VG_(printf)("OBJ "); break;
+ case STT_FUNC: VG_(printf)("FUN "); break;
+ case STT_SECTION: VG_(printf)("SEC "); break;
+ case STT_FILE: VG_(printf)("FIL "); break;
+ case STT_LOPROC: VG_(printf)("lop "); break;
+ case STT_HIPROC: VG_(printf)("hip "); break;
+ default: VG_(printf)("??? "); break;
+ }
+ VG_(printf)(": svma %#010lx, %ssz %4ld %s\n",
+ sym_svma, space, sym->st_size + 0UL,
+ ( sym->st_name ? sym_name : (Char*)"NONAME" ) );
+}
+
+
+/* Decide whether SYM is something we should collect, and if so, copy
+ relevant info to the _OUT arguments. For {x86,amd64,ppc32}-linux
+ this is straightforward - the name, address, size are copied out
+ unchanged.
+
+ There is a bit of a kludge re data symbols (see KLUDGED BSS CHECK
+ below): we assume that the .bss is mapped immediately after .data,
+ and so accept any data symbol which exists in the range [start of
+ .data, size of .data + size of .bss). I don't know if this is
+ really correct/justifiable, or not.
+
+ For ppc64-linux it's more complex. If the symbol is seen to be in
+ the .opd section, it is taken to be a function descriptor, and so
+ a dereference is attempted, in order to get hold of the real entry
+ point address. Also as part of the dereference, there is an attempt
+ to calculate the TOC pointer (R2 value) associated with the symbol.
+
+ To support the ppc64-linux pre-"dotless" ABI (prior to gcc 4.0.0),
+ if the symbol is seen to be outside the .opd section and its name
+ starts with a dot, an .opd deference is not attempted, and no TOC
+ pointer is calculated, but the the leading dot is removed from the
+ name.
+
+ As a result, on ppc64-linux, the caller of this function may have
+ to piece together the real size, address, name of the symbol from
+ multiple calls to this function. Ugly and confusing.
+*/
+static
+Bool get_elf_symbol_info (
+ /* INPUTS */
+ struct _DebugInfo* di, /* containing DebugInfo */
+ ElfXX_Sym* sym, /* ELF symbol */
+ Char* sym_name, /* name */
+ Addr sym_svma, /* address as stated in the object file */
+ Bool symtab_in_debug, /* symbol table is in the debug file */
+ UChar* opd_img, /* oimage of .opd sec (ppc64-linux only) */
+ PtrdiffT opd_bias, /* for biasing AVMAs found in .opd */
+ /* OUTPUTS */
+ Char** sym_name_out, /* name we should record */
+ Addr* sym_avma_out, /* addr we should record */
+ Int* sym_size_out, /* symbol size */
+ Addr* sym_tocptr_out, /* ppc64-linux only: R2 value to be
+ used on entry */
+ Bool* from_opd_out, /* ppc64-linux only: did we deref an
+ .opd entry? */
+ Bool* is_text_out, /* is this a text symbol? */
+ Bool* is_ifunc /* is this a STT_GNU_IFUNC function ?*/
+ )
+{
+ Bool plausible;
+# if defined(VGP_ppc64_linux)
+ Bool is_in_opd;
+# endif
+ Bool in_text, in_data, in_sdata, in_rodata, in_bss, in_sbss;
+ Addr text_svma, data_svma, sdata_svma, rodata_svma, bss_svma, sbss_svma;
+ PtrdiffT text_bias, data_bias, sdata_bias, rodata_bias, bss_bias,
sbss_bias;
+
+ /* Set defaults */
+ *sym_name_out = sym_name;
+ *sym_avma_out = sym_svma; /* we will bias this shortly */
+ *is_text_out = True;
+ *sym_size_out = (Int)sym->st_size;
+ *sym_tocptr_out = 0; /* unknown/inapplicable */
+ *from_opd_out = False;
+ *is_ifunc = False;
+
+ /* Figure out if we're interested in the symbol. Firstly, is it of
+ the right flavour? */
+ plausible
+ = (ELFXX_ST_BIND(sym->st_info) == STB_GLOBAL
+ || ELFXX_ST_BIND(sym->st_info) == STB_LOCAL
+ || ELFXX_ST_BIND(sym->st_info) == STB_WEAK
+ )
+ &&
+ (ELFXX_ST_TYPE(sym->st_info) == STT_FUNC
+ || ELFXX_ST_TYPE(sym->st_info) == STT_OBJECT
+#ifdef STT_GNU_IFUNC
+ || ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC
+#endif
+ );
+
+ /* Work out the svma and bias for each section as it will appear in
+ addresses in the symbol table. */
+ if (symtab_in_debug) {
+ text_svma = di->text_debug_svma;
+ text_bias = di->text_debug_bias;
+ data_svma = di->data_debug_svma;
+ data_bias = di->data_debug_bias;
+ sdata_svma = di->sdata_debug_svma;
+ sdata_bias = di->sdata_debug_bias;
+ rodata_svma = di->rodata_debug_svma;
+ rodata_bias = di->rodata_debug_bias;
+ bss_svma = di->bss_debug_svma;
+ bss_bias = di->bss_debug_bias;
+ sbss_svma = di->sbss_debug_svma;
+ sbss_bias = di->sbss_debug_bias;
+ } else {
+ text_svma = di->text_svma;
+ text_bias = di->text_bias;
+ data_svma = di->data_svma;
+ data_bias = di->data_bias;
+ sdata_svma = di->sdata_svma;
+ sdata_bias = di->sdata_bias;
+ rodata_svma = di->rodata_svma;
+ rodata_bias = di->rodata_bias;
+ bss_svma = di->bss_svma;
+ bss_bias = di->bss_bias;
+ sbss_svma = di->sbss_svma;
+ sbss_bias = di->sbss_bias;
+ }
+
+ /* Now bias sym_avma_out accordingly by figuring out exactly which
+ section the symbol is from and bias accordingly. Screws up if
+ the previously deduced section svma address ranges are wrong. */
+ if (di->text_present
+ && di->text_size > 0
+ && sym_svma >= text_svma
+ && sym_svma < text_svma + di->text_size) {
+ *is_text_out = True;
+ *sym_avma_out += text_bias;
+ } else
+ if (di->data_present
+ && di->data_size > 0
+ && sym_svma >= data_svma
+ && sym_svma < data_svma + di->data_size) {
+ *is_text_out = False;
+ *sym_avma_out += data_bias;
+ } else
+ if (di->sdata_present
+ && di->sdata_size > 0
+ && sym_svma >= sdata_svma
+ && sym_svma < sdata_svma + di->sdata_size) {
+ *is_text_out = False;
+ *sym_avma_out += sdata_bias;
+ } else
+ if (di->rodata_present
+ && di->rodata_size > 0
+ && sym_svma >= rodata_svma
+ && sym_svma < rodata_svma + di->rodata_size) {
+ *is_text_out = False;
+ *sym_avma_out += rodata_bias;
+ } else
+ if (di->bss_present
+ && di->bss_size > 0
+ && sym_svma >= bss_svma
+ && sym_svma < bss_svma + di->bss_size) {
+ *is_text_out = False;
+ *sym_avma_out += bss_bias;
+ } else
+ if (di->sbss_present
+ && di->sbss_size > 0
+ && sym_svma >= sbss_svma
+ && sym_svma < sbss_svma + di->sbss_size) {
+ *is_text_out = False;
+ *sym_avma_out += sbss_bias;
+ } else {
+ /* Assume it's in .text. Is this a good idea? */
+ *is_text_out = True;
+ *sym_avma_out += text_bias;
+ }
+
+# ifdef STT_GNU_IFUNC
+ /* Check for indirect functions. */
+ if (*is_text_out
+ && ELFXX_ST_TYPE(sym->st_info) == STT_GNU_IFUNC) {
+ *is_ifunc = True;
+ }
+# endif
+
+# if defined(VGP_ppc64_linux)
+ /* Allow STT_NOTYPE in the very special case where we're running on
+ ppc64-linux and the symbol is one which the .opd-chasing hack
+ below will chase. */
+ if (!plausible
+ && *is_text_out
+ && ELFXX_ST_TYPE(sym->st_info) == STT_NOTYPE
+ && sym->st_size > 0
+ && di->opd_present
+ && di->opd_size > 0
+ && *sym_avma_out >= di->opd_avma
+ && *sym_avma_out < di->opd_avma + di->opd_size)
+ plausible = True;
+# endif
+
+ if (!plausible)
+ return False;
+
+ /* Ignore if nameless. */
+ if (sym_name == (ElfXX_Word)0
+ || /* VG_(strlen)(sym_name) == 0 */
+ /* equivalent but cheaper ... */
+ sym_name[0] == 0) {
+ TRACE_SYMTAB(" ignore -- nameless: %s\n", sym_name);
+ return False;
+ }
+
+ /* Ignore if zero-sized. Except on Android:
+
+ On Android 2.3.5, some of the symbols that Memcheck needs to
+ intercept (for noise reduction purposes) have zero size, due to
+ lack of .size directives in handwritten assembly sources. So we
+ can't reject them out of hand -- instead give them a bogusly
+ large size and let canonicaliseSymtab trim them so they don't
+ overlap any following symbols. At least the following symbols
+ are known to be affected:
+
+ in /system/lib/libc.so: strlen strcmp strcpy memcmp memcpy
+ in /system/bin/linker: __dl_strcmp __dl_strlen
+ */
+ if (sym->st_size == 0) {
+# if defined(VGPV_arm_linux_android)
+ *sym_size_out = 2048;
+# else
+ TRACE_SYMTAB(" ignore -- size=0: %s\n", sym_name);
+ return False;
+# endif
+ }
+
+ /* This seems to significantly reduce the number of junk
+ symbols, and particularly reduces the number of
+ overlapping address ranges. Don't ask me why ... */
+ if ((Int)sym->st_value == 0) {
+ TRACE_SYMTAB( " ignore -- valu=0: %s\n", sym_name);
+ return False;
+ }
+
+ /* If it's apparently in a GOT or PLT, it's really a reference to a
+ symbol defined elsewhere, so ignore it. */
+ if (di->got_present
+ && di->got_size > 0
+ && *sym_avma_out >= di->got_avma
+ && *sym_avma_out < di->got_avma + di->got_size) {
+ TRACE_SYMTAB(" ignore -- in GOT: %s\n", sym_name);
+ return False;
+ }
+ if (di->plt_present
+ && di->plt_size > 0
+ && *sym_avma_out >= di->plt_avma
+ && *sym_avma_out < di->plt_avma + di->plt_size) {
+ TRACE_SYMTAB(" ignore -- in PLT: %s\n", sym_name);
+ return False;
+ }
+
+ /* ppc64-linux nasty hack: if the symbol is in an .opd section,
+ then really what we have is the address of a function
+ descriptor. So use the first word of that as the function's
+ text.
+
+ See thread starting at
+ http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00557.html
+ */
+# if defined(VGP_ppc64_linux)
+ is_in_opd = False;
+# endif
+
+ if (di->opd_present
+ && di->opd_size > 0
+ && *sym_avma_out >= di->opd_avma
+ && *sym_avma_out < di->opd_avma + di->opd_size) {
+# if !defined(VGP_ppc64_linux)
+ TRACE_SYMTAB(" ignore -- in OPD: %s\n", sym_name);
+ return False;
+# else
+ Int offset_in_opd;
+ ULong* fn_descr;
+ Bool details = 1||False;
+
+ if (details)
+ TRACE_SYMTAB("opdXXX: opd_bias %p, sym_svma_out %p\n",
+ (void*)(opd_bias), (void*)*sym_avma_out);
+
+ if (!VG_IS_8_ALIGNED(*sym_avma_out)) {
+ TRACE_SYMTAB(" ignore -- not 8-aligned: %s\n", sym_name);
+ return False;
+ }
+
+ /* *sym_avma_out is a vma pointing into the .opd section. We
+ know the vma of the opd section start, so we can figure out
+ how far into the opd section this is. */
+
+ offset_in_opd = (Addr)(*sym_avma_out) - (Addr)(di->opd_avma);
+ if (offset_in_opd < 0 || offset_in_opd >= di->opd_size) {
+ TRACE_SYMTAB(" ignore -- invalid OPD offset: %s\n", sym_name);
+ return False;
+ }
+
+ /* Now we want to know what's at that offset in the .opd
+ section. We can't look in the running image since it won't
+ necessarily have been mapped. But we can consult the oimage.
+ opd_img is the start address of the .opd in the oimage.
+ Hence: */
+
+ fn_descr = (ULong*)(opd_img + offset_in_opd);
+
+ if (details)
+ TRACE_SYMTAB("opdXXY: offset %d, fn_descr %p\n",
+ offset_in_opd, fn_descr);
+ if (details)
+ TRACE_SYMTAB("opdXXZ: *fn_descr %p\n", (void*)(fn_descr[0]));
+
+ /* opd_bias is the what we have to add to SVMAs found in .opd to
+ get plausible .text AVMAs for the entry point, and .data
+ AVMAs (presumably) for the TOC locations. We use the caller
+ supplied value (which is di->text_bias) for both of these.
+ Not sure why that is correct - it seems to work, and sounds
+ OK for fn_descr[0], but surely we need to use the data bias
+ and not the text bias for fn_descr[1] ? Oh Well.
+ */
+ *sym_avma_out = fn_descr[0] + opd_bias;
+ *sym_tocptr_out = fn_descr[1] + opd_bias;
+ *from_opd_out = True;
+ is_in_opd = True;
+
+ /* Do a final sanity check: if the symbol falls outside the
+ DebugInfo's mapped range, ignore it. Since *sym_avma_out has
+ been updated, that can be achieved simply by falling through
+ to the test below. */
+
+# endif /* ppc64-linux nasty hack */
+ }
+
+ /* Here's yet another ppc64-linux hack. Get rid of leading dot if
+ the symbol is outside .opd. */
+# if defined(VGP_ppc64_linux)
+ if (di->opd_size > 0
+ && !is_in_opd
+ && sym_name[0] == '.') {
+ vg_assert(!(*from_opd_out));
+ *sym_name_out = &sym_name[1];
+ }
+# endif
+
+ /* If no part of the symbol falls within the mapped range,
+ ignore it. */
+
+ in_text
+ = di->text_present
+ && di->text_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->text_avma
+ || *sym_avma_out >= di->text_avma + di->text_size);
+
+ in_data
+ = di->data_present
+ && di->data_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->data_avma
+ || *sym_avma_out >= di->data_avma + di->data_size);
+
+ in_sdata
+ = di->sdata_present
+ && di->sdata_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->sdata_avma
+ || *sym_avma_out >= di->sdata_avma + di->sdata_size);
+
+ in_rodata
+ = di->rodata_present
+ && di->rodata_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->rodata_avma
+ || *sym_avma_out >= di->rodata_avma + di->rodata_size);
+
+ in_bss
+ = di->bss_present
+ && di->bss_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->bss_avma
+ || *sym_avma_out >= di->bss_avma + di->bss_size);
+
+ in_sbss
+ = di->sbss_present
+ && di->sbss_size > 0
+ && !(*sym_avma_out + *sym_size_out <= di->sbss_avma
+ || *sym_avma_out >= di->sbss_avma + di->sbss_size);
+
+
+ if (*is_text_out) {
+ /* This used to reject any symbol falling outside the text
+ segment ("if (!in_text) ..."). Now it is relaxed slightly,
+ to reject only symbols which fall outside the area mapped
+ r-x. This is in accordance with r7427. See
+ "Comment_Regarding_Text_Range_Checks" in storage.c for
+ background. */
+ Bool in_rx;
+ vg_assert(di->fsm.have_rx_map);
+ in_rx = (!(*sym_avma_out + *sym_size_out <= di->fsm.rx_map_avma
+ || *sym_avma_out >= di->fsm.rx_map_avma
+ + di->fsm.rx_map_size));
+ if (in_text)
+ vg_assert(in_rx);
+ if (!in_rx) {
+ TRACE_SYMTAB(
+ "ignore -- %#lx .. %#lx outside .text svma
range %#lx .. %#lx\n",
+ *sym_avma_out, *sym_avma_out + *sym_size_out,
+ di->text_avma,
+ di->text_avma + di->text_size);
+ return False;
+ }
+ } else {
+ if (!(in_data || in_sdata || in_rodata || in_bss || in_sbss)) {
+ TRACE_SYMTAB(
+ "ignore -- %#lx .. %#lx outside .data / .sdata / .rodata "
+ "/ .bss / .sbss svma ranges\n",
+ *sym_avma_out, *sym_avma_out + *sym_size_out);
+ return False;
+ }
+ }
+
+# if defined(VGP_ppc64_linux)
+ /* It's crucial that we never add symbol addresses in the .opd
+ section. This would completely mess up function redirection and
+ intercepting. This assert ensures that anysymbols that make it
+ into the symbol table on ppc64-linux don't point into .opd. */
+ if (di->opd_present && di->opd_size > 0) {
+ vg_assert(*sym_avma_out + *sym_size_out <= di->opd_avma
+ || *sym_avma_out >= di->opd_avma + di->opd_size);
+ }
+# endif
+
+ /* Acquire! */
+ return True;
+}
+
+
+/* Read an ELF symbol table (normal or dynamic). This one is for the
+ "normal" case ({x86,amd64,ppc32}-linux). */
+static
+__attribute__((unused)) /* not referred to on all targets */
+void read_elf_symtab__normal(
+ struct _DebugInfo* di, UChar* tab_name,
+ ElfXX_Sym* symtab_img, SizeT symtab_szB,
+ UChar* strtab_img, SizeT strtab_szB,
+ Bool symtab_in_debug,
+ UChar* opd_img /* ppc64-linux only */
+ )
+{
+ Word i;
+ Addr sym_svma, sym_avma_really;
+ Char *sym_name, *sym_name_really;
+ Int sym_size;
+ Addr sym_tocptr;
+ Bool from_opd, is_text, is_ifunc;
+ DiSym disym;
+ ElfXX_Sym *sym;
+
+ if (strtab_img == NULL || symtab_img == NULL) {
+ Char buf[80];
+ vg_assert(VG_(strlen)(tab_name) < 40);
+ VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
+ ML_(symerr)(di, False, buf);
+ return;
+ }
+
+ TRACE_SYMTAB("\n--- Reading (ELF, standard) %s (%ld entries) ---\n",
+ tab_name, symtab_szB/sizeof(ElfXX_Sym) );
+
+ /* Perhaps should start at i = 1; ELF docs suggest that entry
+ 0 always denotes 'unknown symbol'. */
+ for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
+ sym = & symtab_img[i];
+ sym_name = (UChar*)(strtab_img + sym->st_name);
+ sym_svma = sym->st_value;
+
+ if (di->trace_symtab)
+ show_raw_elf_symbol(i, sym, sym_name, sym_svma, False);
+
+ if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
+ symtab_in_debug,
+ opd_img, di->text_bias,
+ &sym_name_really,
+ &sym_avma_really,
+ &sym_size,
+ &sym_tocptr,
+ &from_opd, &is_text, &is_ifunc)) {
+
+ disym.addr = sym_avma_really;
+ disym.tocptr = sym_tocptr;
+ disym.pri_name = ML_(addStr) ( di, sym_name_really, -1 );
+ disym.sec_names = NULL;
+ disym.size = sym_size;
+ disym.isText = is_text;
+ disym.isIFunc = is_ifunc;
+ vg_assert(disym.pri_name);
+ vg_assert(disym.tocptr == 0); /* has no role except on
ppc64-linux */
+ ML_(addSym) ( di, &disym );
+
+ if (di->trace_symtab) {
+ VG_(printf)(" rec(%c) [%4ld]: "
+ " val %#010lx, sz %4d %s\n",
+ is_text ? 't' : 'd',
+ i,
+ disym.addr,
+ (Int)disym.size,
+ (HChar*)disym.pri_name
+ );
+ }
+
+ }
+ }
+}
+
+
+/* Read an ELF symbol table (normal or dynamic). This one is for
+ ppc64-linux, which requires special treatment. */
+
+typedef
+ struct {
+ Addr addr;
+ UChar* name;
+ }
+ TempSymKey;
+
+typedef
+ struct {
+ TempSymKey key;
+ Addr tocptr;
+ Int size;
+ Bool from_opd;
+ Bool is_text;
+ Bool is_ifunc;
+ }
+ TempSym;
+
+static Word cmp_TempSymKey ( TempSymKey* key1, TempSym* elem2 ) {
+ if (key1->addr < elem2->key.addr) return -1;
+ if (key1->addr > elem2->key.addr) return 1;
+ return (Word)VG_(strcmp)(key1->name, elem2->key.name);
+}
+
+static
+__attribute__((unused)) /* not referred to on all targets */
+void read_elf_symtab__ppc64_linux(
+ struct _DebugInfo* di, UChar* tab_name,
+ ElfXX_Sym* symtab_img, SizeT symtab_szB,
+ UChar* strtab_img, SizeT strtab_szB,
+ Bool symtab_in_debug,
+ UChar* opd_img /* ppc64-linux only */
+ )
+{
+ Word i;
+ Int old_size;
+ Addr sym_svma, sym_avma_really;
+ Char *sym_name, *sym_name_really;
+ Int sym_size;
+ Addr sym_tocptr;
+ Bool from_opd, modify_size, modify_tocptr, is_text, is_ifunc;
+ DiSym disym;
+ ElfXX_Sym *sym;
+ OSet *oset;
+ TempSymKey key;
+ TempSym *elem;
+ TempSym *prev;
+
+ if (strtab_img == NULL || symtab_img == NULL) {
+ Char buf[80];
+ vg_assert(VG_(strlen)(tab_name) < 40);
+ VG_(sprintf)(buf, " object doesn't have a %s", tab_name);
+ ML_(symerr)(di, False, buf);
+ return;
+ }
+
+ TRACE_SYMTAB("\n--- Reading (ELF, ppc64-linux) %s (%ld entries) ---\n",
+ tab_name, symtab_szB/sizeof(ElfXX_Sym) );
+
+ oset = VG_(OSetGen_Create)( offsetof(TempSym,key),
+ (OSetCmp_t)cmp_TempSymKey,
+ ML_(dinfo_zalloc), "di.respl.1",
+ ML_(dinfo_free) );
+ vg_assert(oset);
+
+ /* Perhaps should start at i = 1; ELF docs suggest that entry
+ 0 always denotes 'unknown symbol'. */
+ for (i = 1; i < (Word)(symtab_szB/sizeof(ElfXX_Sym)); i++) {
+ sym = & symtab_img[i];
+ sym_name = (Char*)(strtab_img + sym->st_name);
+ sym_svma = sym->st_value;
+
+ if (di->trace_symtab)
+ show_raw_elf_symbol(i, sym, sym_name, sym_svma, True);
+
+ if (get_elf_symbol_info(di, sym, sym_name, sym_svma,
+ symtab_in_debug,
+ opd_img, di->text_bias,
+ &sym_name_really,
+ &sym_avma_really,
+ &sym_size,
+ &sym_tocptr,
+ &from_opd, &is_text, &is_ifunc)) {
+
+ /* Check if we've seen this (name,addr) key before. */
+ key.addr = sym_avma_really;
+ key.name = sym_name_really;
+ prev = VG_(OSetGen_Lookup)( oset, &key );
+
+ if (prev) {
+
+ /* Seen it before. Fold in whatever new info we can. */
+ modify_size = False;
+ modify_tocptr = False;
+ old_size = 0;
+
+ if (prev->from_opd && !from_opd
+ && (prev->size == 24 || prev->size == 16)
+ && sym_size != prev->size) {
+ /* Existing one is an opd-redirect, with a bogus size,
+ so the only useful new fact we have is the real size
+ of the symbol. */
+ modify_size = True;
+ old_size = prev->size;
+ prev->size = sym_size;
+ }
+ else
+ if (!prev->from_opd && from_opd
+ && (sym_size == 24 || sym_size == 16)) {
+ /* Existing one is non-opd, new one is opd. What we
+ can acquire from the new one is the TOC ptr to be
+ used. Since the existing sym is non-toc, it
+ shouldn't currently have an known TOC ptr. */
+ vg_assert(prev->tocptr == 0);
+ modify_tocptr = True;
+ prev->tocptr = sym_tocptr;
+ }
+ else {
+ /* ignore. can we do better here? */
+ }
+
+ /* Only one or the other is possible (I think) */
+ vg_assert(!(modify_size && modify_tocptr));
+
+ if (modify_size && di->trace_symtab) {
+ VG_(printf)(" modify (old sz %4d) "
+ " val %#010lx, toc %#010lx, sz %4d %s\n",
+ old_size,
+ prev->key.addr,
+ prev->tocptr,
+ (Int) prev->size,
+ (HChar*)prev->key.name
+ );
+ }
+ if (modify_tocptr && di->trace_symtab) {
+ VG_(printf)(" modify (upd tocptr) "
+ " val %#010lx, toc %#010lx, sz %4d %s\n",
+ prev->key.addr,
+ prev->tocptr,
+ (Int) prev->size,
+ (HChar*)prev->key.name
+ );
+ }
+
+ } else {
+
+ /* A new (name,addr) key. Add and continue. */
+ elem = VG_(OSetGen_AllocNode)(oset, sizeof(TempSym));
+ vg_assert(elem);
+ elem->key = key;
+ elem->tocptr = sym_tocptr;
+ elem->size = sym_size;
+ elem->from_opd = from_opd;
+ elem->is_text = is_text;
+ elem->is_ifunc = is_ifunc;
+ VG_(OSetGen_Insert)(oset, elem);
+ if (di->trace_symtab) {
+ VG_(printf)(" to-oset [%4ld]: "
+ " val %#010lx, toc %#010lx, sz %4d %s\n",
+ i,
+ elem->key.addr,
+ elem->tocptr,
+ (Int) elem->size,
+ (HChar*)elem->key.name
+ );
+ }
+
+ }
+ }
+ }
+
+ /* All the syms that matter are in the oset. Now pull them out,
+ build a "standard" symbol table, and nuke the oset. */
+
+ i = 0;
+ VG_(OSetGen_ResetIter)( oset );
+
+ while ( (elem = VG_(OSetGen_Next)(oset)) ) {
+ disym.addr = elem->key.addr;
+ disym.tocptr = elem->tocptr;
+ disym.pri_name = ML_(addStr) ( di, elem->key.name, -1 );
+ disym.sec_names = NULL;
+ disym.size = elem->size;
+ disym.isText = elem->is_text;
+ disym.isIFunc = elem->is_ifunc;
+ vg_assert(disym.pri_name != NULL);
+
+ ML_(addSym) ( di, &disym );
+ if (di->trace_symtab) {
+ VG_(printf)(" rec(%c) [%4ld]: "
+ " val %#010lx, toc %#010lx, sz %4d %s\n",
+ disym.isText ? 't' : 'd',
+ i,
+ disym.addr,
+ disym.tocptr,
+ (Int) disym.size,
+ (HChar*)disym.pri_name
+ );
+ }
+ i++;
+ }
+
+ VG_(OSetGen_Destroy)( oset );
+}
+
+
+/*
+ * Look for a build-id in an ELF image. The build-id specification
+ * can be found here:
+ *
+ * http://fedoraproject.org/wiki/RolandMcGrath/BuildID
+ */
+static
+Char *find_buildid(Addr image, UWord n_image)
+{
+ Char* buildid = NULL;
+ __attribute__((unused)) /* on Android, at least */
+ ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
+
+#ifdef NT_GNU_BUILD_ID
+ if (n_image >= sizeof(ElfXX_Ehdr) &&
+ ML_(is_elf_object_file)(ehdr, n_image)) {
+ Word i;
+
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ ElfXX_Phdr* phdr
+ = (ElfXX_Phdr*)(image + ehdr->e_phoff + i * ehdr->e_phentsize);
+
+ if (phdr->p_type == PT_NOTE) {
+ ElfXX_Off offset = phdr->p_offset;
+
+ while (offset < phdr->p_offset + phdr->p_filesz) {
+ ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset);
+ Char* name = (Char *)note + sizeof(ElfXX_Nhdr);
+ UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3);
+ Word j;
+
+ if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 &&
+ note->n_type == NT_GNU_BUILD_ID) {
+ buildid = ML_(dinfo_zalloc)("di.fbi.1",
+ note->n_descsz * 2 + 1);
+
+ for (j = 0; j < note->n_descsz; j++) {
+ VG_(sprintf)(buildid + VG_(strlen)(buildid),
+ "%02x", desc[j]);
+ }
+ }
+
+ offset = offset + sizeof(ElfXX_Nhdr)
+ + ((note->n_namesz + 3) & ~3)
+ + ((note->n_descsz + 3) & ~3);
+ }
+ }
+ }
+ }
+#endif
+
+ return buildid;
+}
+
+/*
+ * This routine for calculating the CRC for a separate debug file
+ * is GPLed code borrowed from GNU binutils.
+ */
+static UInt
+calc_gnu_debuglink_crc32(UInt crc, const UChar *buf, Int len)
+{
+ static const UInt crc32_table[256] =
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+ 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+ 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+ 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+ 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+ 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+ 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+ 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+ 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+ 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+ 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+ 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+ 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+ 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+ 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+ 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+ 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+ 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+ 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+ 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+ 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+ 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+ 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+ 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+ 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+ 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+ 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+ 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+ 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+ 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+ 0x2d02ef8d
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_debuginfo/readelf.c.rej Thu Nov 22 04:55:39
2012
@@ -0,0 +1,77 @@
+--- coregrind/m_debuginfo/readelf.c (revision 12307)
++++ coregrind/m_debuginfo/readelf.c (revision 13132)
+@@ -1671,46 +1737,49 @@
+ find a soname, add a fake one. */
+ if (di->soname == NULL) {
+ TRACE_SYMTAB("No soname found; using (fake) \"NONE\"\n");
+- di->soname = "NONE";
++ di->soname = ML_(dinfo_strdup)("di.redi.2", "NONE");
+ }
+
+- vg_assert(n_rx >= 0 && n_rx <= N_RX_RW_AREAS);
+- vg_assert(n_rw >= 0 && n_rw <= N_RX_RW_AREAS);
+- for (i = 0; i < n_rx; i++) {
+- vg_assert(rx[i].svma_limit != 0);
+- }
+- for (i = 0; i < n_rw; i++) {
+- vg_assert(rw[i].svma_limit != 0);
+- }
++ vg_assert(VG_(sizeXA)(svma_ranges) != 0);
+
+ /* Now read the section table. */
+ TRACE_SYMTAB("\n");
+ TRACE_SYMTAB("------ Examining the section headers ------\n");
+- TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
+- di->fsm.rx_map_avma,
+- di->fsm.rx_map_foff,
+- di->fsm.rx_map_foff + di->fsm.rx_map_size - 1 );
+- for (i = 0; i < n_rx; i++) {
+- TRACE_SYMTAB("rx[%ld]: contains svmas %#lx .. %#lx with
bias %#lx\n",
+- i, rx[i].svma_base, rx[i].svma_limit - 1, rx[i].bias );
++ for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
++ struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
++ if (map->rx)
++ TRACE_SYMTAB("rx: at %#lx are mapped foffsets %ld .. %ld\n",
++ map->avma, map->foff, map->foff + map->size - 1 );
+ }
+- TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
+- di->fsm.rw_map_avma,
+- di->fsm.rw_map_foff,
+- di->fsm.rw_map_foff + di->fsm.rw_map_size - 1 );
+- for (i = 0; i < n_rw; i++) {
+- TRACE_SYMTAB("rw[%ld]: contains svmas %#lx .. %#lx with
bias %#lx\n",
+- i, rw[i].svma_base, rw[i].svma_limit - 1, rw[i].bias );
++ TRACE_SYMTAB("rx: contains these svma regions:\n");
++ for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
++ RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
++ if (reg->exec)
++ TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
++ reg->svma_base, reg->svma_limit - 1, reg->bias );
+ }
++ for (i = 0; i < VG_(sizeXA)(di->fsm.maps); i++) {
++ struct _DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, i);
++ if (map->rw)
++ TRACE_SYMTAB("rw: at %#lx are mapped foffsets %ld .. %ld\n",
++ map->avma, map->foff, map->foff + map->size - 1 );
++ }
++ TRACE_SYMTAB("rw: contains these svma regions:\n");
++ for (i = 0; i < VG_(sizeXA)(svma_ranges); i++) {
++ RangeAndBias* reg = VG_(indexXA)(svma_ranges, i);
++ if (!reg->exec)
++ TRACE_SYMTAB(" svmas %#lx .. %#lx with bias %#lx\n",
++ reg->svma_base, reg->svma_limit - 1, reg->bias );
++ }
+
+ /* TOPLEVEL */
+ /* Iterate over section headers */
+ for (i = 0; i < shdr_nent; i++) {
+ ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
+- UChar* name = shdr_strtab_img + shdr->sh_name;
++ HChar* name = shdr_strtab_img + shdr->sh_name;
+ Addr svma = shdr->sh_addr;
+ OffT foff = shdr->sh_offset;
+- UWord size = shdr->sh_size;
++ UWord size = shdr->sh_size; /* Do not change this to be signed. */
+ UInt alyn = shdr->sh_addralign;
+ Bool bits = !(shdr->sh_type == SHT_NOBITS);
+ /* Look through our collection of info obtained from the PT_LOAD
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_debuginfo/readpdb.c.orig Thu Nov 22
04:55:39 2012
@@ -0,0 +1,2565 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Reading of syms & debug info from PDB-format files. ---*/
+/*--- readpdb.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+ Spring 2008:
+ derived from readelf.c and valgrind-20031012-wine/vg_symtab2.c
+ derived from wine-1.0/tools/winedump/pdb.c and msc.c
+
+ Copyright (C) 2000-2011 Julian Seward
+ jse...@acm.org
+ Copyright 2006 Eric Pouech (winedump/pdb.c and msc.c)
+ GNU Lesser General Public License version 2.1 or later applies.
+ Copyright (C) 2008 BitWagon Software LLC
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#if defined(VGO_linux) || defined(VGO_darwin)
+
+#include "pub_core_basics.h"
+#include "pub_core_debuginfo.h"
+#include "pub_core_vki.h" // VKI_PAGE_SIZE
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcfile.h" // VG_(open), read, lseek, close
+#include "pub_core_libcprint.h"
+#include "pub_core_libcproc.h" // VG_(getpid), system
+#include "pub_core_options.h" // VG_(clo_verbosity)
+#include "pub_core_xarray.h" // keeps priv_storage.h happy
+#include "pub_core_redir.h"
+
+#include "priv_misc.h" /* dinfo_zalloc/free/strdup */
+#include "priv_d3basics.h"
+#include "priv_storage.h"
+#include "priv_readpdb.h" // self
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- Biasing ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+/* JRS 2009-Apr-13: Mostly this PDB reader is straightforward. But
+ the biasing is incomprehensible, and I don't claim to understand it
+ at all. There are four places where biasing is required:
+
+ - when reading symbol addresses (DEBUG_SnarfCodeView)
+ - when reading old-style line number tables (DEBUG_SnarfLinetab)
+ - when reading new-style line number tables (codeview_dump_linetab2)
+ - when reading FPO (stack-unwind) tables (pdb_dump)
+
+ To complicate matters further, Wine supplies us, via the
+ VG_USERREQ__LOAD_PDB_DEBUGINFO client request that initiates PDB
+ reading, a value 'unknown_purpose__reloc' which, if you read
+ 'virtual.c' in the Wine sources, looks a lot like a text bias
+ value. Yet the code below ignores it.
+
+ To make future experimentation with biasing easier, here are four
+ macros which give the bias to use in each of the four cases. Be
+ warned, they can and do refer to local vars in the relevant
+ functions. */
+
+/* The BIAS_FOR_{SYMBOLS,LINETAB,LINETAB2} are as in JohnR's original
+ patch. BIAS_FOR_FPO was originally hardwired to zero, but that
+ doesn't make much sense. Here, we use text_bias as empirically
+ producing the most ranges that fall inside the text segments for a
+ multi-dll program. Of course, it could still be nonsense :-) */
+#define BIAS_FOR_SYMBOLS (di->fsm.rx_map_avma)
+#define BIAS_FOR_LINETAB (di->fsm.rx_map_avma)
+#define BIAS_FOR_LINETAB2 (di->text_bias)
+#define BIAS_FOR_FPO (di->text_bias)
+/* Using di->text_bias for the FPOs causes 981 in range and 1 out of
+ range. Using rx_map_avma gives 953 in range and 29 out of range,
+ so di->text_bias looks like a better bet.:
+ $ grep FPO spew-B-text_bias | grep keep | wc
+ 981 4905 57429
+ $ grep FPO spew-B-text_bias | grep SKIP | wc
+ 1 5 53
+ $ grep FPO spew-B-rx_map_avma | grep keep | wc
+ 953 4765 55945
+ $ grep FPO spew-B-rx_map_avma | grep SKIP | wc
+ 29 145 1537
+*/
+
+/* This module leaks space; enable m_main's calling of
+ VG_(di_discard_ALL_debuginfo)() at shutdown and run with
+ --profile-heap=yes to see. The main culprit appears to be
+ di.readpe.pdr.1. I haven't bothered to chase it further. */
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- PE/PDB definitions ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+typedef UInt DWORD;
+typedef UShort WORD;
+typedef UChar BYTE;
+
+
+/* the following DOS and WINDOWS structures, defines and PE/PDB
+ * parsing code are copied or derived from the WINE
+ * project - http://www.winehq.com/
+ */
+
+/*
+ * File formats definitions
+ */
+#define OFFSET_OF(__c,__f)
((int)(((char*)&(((__c*)0)->__f))-((char*)0)))
+#define WIN32_PATH_MAX 256
+
+#pragma pack(2)
+typedef struct _IMAGE_DOS_HEADER {
+ unsigned short e_magic; /* 00: MZ Header signature */
+ unsigned short e_cblp; /* 02: Bytes on last page of file */
+ unsigned short e_cp; /* 04: Pages in file */
+ unsigned short e_crlc; /* 06: Relocations */
+ unsigned short e_cparhdr; /* 08: Size of header in paragraphs */
+ unsigned short e_minalloc; /* 0a: Minimum extra paragraphs needed */
+ unsigned short e_maxalloc; /* 0c: Maximum extra paragraphs needed */
+ unsigned short e_ss; /* 0e: Initial (relative) SS value */
+ unsigned short e_sp; /* 10: Initial SP value */
+ unsigned short e_csum; /* 12: Checksum */
+ unsigned short e_ip; /* 14: Initial IP value */
+ unsigned short e_cs; /* 16: Initial (relative) CS value */
+ unsigned short e_lfarlc; /* 18: File address of relocation table
*/
+ unsigned short e_ovno; /* 1a: Overlay number */
+ unsigned short e_res[4]; /* 1c: Reserved words */
+ unsigned short e_oemid; /* 24: OEM identifier (for e_oeminfo) */
+ unsigned short e_oeminfo; /* 26: OEM information; e_oemid specific
*/
+ unsigned short e_res2[10]; /* 28: Reserved words */
+ unsigned long e_lfanew; /* 3c: Offset to extended header */
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
+#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
+#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
+#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
+#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
+#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
+
+/* Subsystem Values */
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem*/
+#define IMAGE_SUBSYSTEM_OS2_CUI 5
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7
+
+typedef struct _IMAGE_FILE_HEADER {
+ unsigned short Machine;
+ unsigned short NumberOfSections;
+ unsigned long TimeDateStamp;
+ unsigned long PointerToSymbolTable;
+ unsigned long NumberOfSymbols;
+ unsigned short SizeOfOptionalHeader;
+ unsigned short Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ unsigned long VirtualAddress;
+ unsigned long Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+
+ /* Standard fields */
+
+ unsigned short Magic; /* 0x10b or 0x107 */ /* 0x00 */
+ unsigned char MajorLinkerVersion;
+ unsigned char MinorLinkerVersion;
+ unsigned long SizeOfCode;
+ unsigned long SizeOfInitializedData;
+ unsigned long SizeOfUninitializedData;
+ unsigned long AddressOfEntryPoint; /* 0x10 */
+ unsigned long BaseOfCode;
+ unsigned long BaseOfData;
+
+ /* NT additional fields */
+
+ unsigned long ImageBase;
+ unsigned long SectionAlignment; /* 0x20 */
+ unsigned long FileAlignment;
+ unsigned short MajorOperatingSystemVersion;
+ unsigned short MinorOperatingSystemVersion;
+ unsigned short MajorImageVersion;
+ unsigned short MinorImageVersion;
+ unsigned short MajorSubsystemVersion; /* 0x30 */
+ unsigned short MinorSubsystemVersion;
+ unsigned long Win32VersionValue;
+ unsigned long SizeOfImage;
+ unsigned long SizeOfHeaders;
+ unsigned long CheckSum; /* 0x40 */
+ unsigned short Subsystem;
+ unsigned short DllCharacteristics;
+ unsigned long SizeOfStackReserve;
+ unsigned long SizeOfStackCommit;
+ unsigned long SizeOfHeapReserve; /* 0x50 */
+ unsigned long SizeOfHeapCommit;
+ unsigned long LoaderFlags;
+ unsigned long NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; /*
0x60 */
+ /* 0xE0 */
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_NT_HEADERS {
+ unsigned long Signature; /* "PE"\0\0 */ /* 0x00 */
+ IMAGE_FILE_HEADER FileHeader; /* 0x04 */
+ IMAGE_OPTIONAL_HEADER OptionalHeader; /* 0x18 */
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ unsigned char Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ unsigned long PhysicalAddress;
+ unsigned long VirtualSize;
+ } Misc;
+ unsigned long VirtualAddress;
+ unsigned long SizeOfRawData;
+ unsigned long PointerToRawData;
+ unsigned long PointerToRelocations;
+ unsigned long PointerToLinenumbers;
+ unsigned short NumberOfRelocations;
+ unsigned short NumberOfLinenumbers;
+ unsigned long Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_FIRST_SECTION(ntheader) \
+ ((PIMAGE_SECTION_HEADER)((LPunsigned
char)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
+
((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
+
+/* These defines are for the Characteristics bitfield. */
+/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */
+/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */
+/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */
+/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */
+/* #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 - Reserved */
+/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100
+#define IMAGE_SCN_LNK_INFO 0x00000200
+/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_LNK_COMDAT 0x00001000
+
+/* 0x00002000 - Reserved */
+/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+
+/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+/* 0x00800000 - Unused */
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+
+
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+#pragma pack()
+
+typedef struct _GUID /* 16 bytes */
+{
+ unsigned int Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+} GUID;
+
+/*========================================================================
+ * Process PDB file.
+ */
+
+#pragma pack(1)
+typedef struct _PDB_FILE
+{
+ unsigned long size;
+ unsigned long unknown;
+
+} PDB_FILE, *PPDB_FILE;
+
+// A .pdb file begins with a variable-length one-line text string
+// that ends in "\r\n\032". This is followed by a 4-byte "signature"
+// ("DS\0\0" for newer files, "JG\0\0" for older files), then
+// aligned up to a 4-byte boundary, then the struct below:
+struct PDB_JG_HEADER
+{
+ //char ident[40]; // "Microsoft C/C++ program database 2.00\r\n\032"
+ //unsigned long signature; // "JG\0\0"
+ unsigned int blocksize; // 0x400 typical; also 0x800, 0x1000
+ unsigned short freelist;
+ unsigned short total_alloc;
+ PDB_FILE toc;
+ unsigned short toc_block[ 1 ];
+};
+
+struct PDB_DS_HEADER
+{
+ //char signature[32]; // "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0"
+ unsigned int block_size;
+ unsigned int unknown1;
+ unsigned int num_pages;
+ unsigned int toc_size;
+ unsigned int unknown2;
+ unsigned int toc_page;
+};
+
+struct PDB_JG_TOC
+{
+ unsigned int nFiles;
+ PDB_FILE file[ 1 ];
+
+};
+
+struct PDB_DS_TOC
+{
+ unsigned int num_files;
+ unsigned int file_size[1];
+};
+
+struct PDB_JG_ROOT
+{
+ unsigned int version;
+ unsigned int TimeDateStamp;
+ unsigned int age;
+ unsigned int cbNames;
+ char names[ 1 ];
+};
+
+struct PDB_DS_ROOT
+{
+ unsigned int version;
+ unsigned int TimeDateStamp;
+ unsigned int age;
+ GUID guid;
+ unsigned int cbNames;
+ char names[1];
+};
+
+typedef struct _PDB_TYPES_OLD
+{
+ unsigned long version;
+ unsigned short first_index;
+ unsigned short last_index;
+ unsigned long type_size;
+ unsigned short file;
+ unsigned short pad;
+
+} PDB_TYPES_OLD, *PPDB_TYPES_OLD;
+
+typedef struct _PDB_TYPES
+{
+ unsigned long version;
+ unsigned long type_offset;
+ unsigned long first_index;
+ unsigned long last_index;
+ unsigned long type_size;
+ unsigned short file;
+ unsigned short pad;
+ unsigned long hash_size;
+ unsigned long hash_base;
+ unsigned long hash_offset;
+ unsigned long hash_len;
+ unsigned long search_offset;
+ unsigned long search_len;
+ unsigned long unknown_offset;
+ unsigned long unknown_len;
+
+} PDB_TYPES, *PPDB_TYPES;
+
+typedef struct _PDB_SYMBOL_RANGE
+{
+ unsigned short segment;
+ unsigned short pad1;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long characteristics;
+ unsigned short index;
+ unsigned short pad2;
+
+} PDB_SYMBOL_RANGE, *PPDB_SYMBOL_RANGE;
+
+typedef struct _PDB_SYMBOL_RANGE_EX
+{
+ unsigned short segment;
+ unsigned short pad1;
+ unsigned long offset;
+ unsigned long size;
+ unsigned long characteristics;
+ unsigned short index;
+ unsigned short pad2;
+ unsigned long timestamp;
+ unsigned long unknown;
+
+} PDB_SYMBOL_RANGE_EX, *PPDB_SYMBOL_RANGE_EX;
+
+typedef struct _PDB_SYMBOL_FILE
+{
+ unsigned long unknown1;
+ PDB_SYMBOL_RANGE range;
+ unsigned short flag;
+ unsigned short file;
+ unsigned long symbol_size;
+ unsigned long lineno_size;
+ unsigned long unknown2;
+ unsigned long nSrcFiles;
+ unsigned long attribute;
+ char filename[ 1 ];
+
+} PDB_SYMBOL_FILE, *PPDB_SYMBOL_FILE;
+
+typedef struct _PDB_SYMBOL_FILE_EX
+{
+ unsigned long unknown1;
+ PDB_SYMBOL_RANGE_EX range;
+ unsigned short flag;
+ unsigned short file;
+ unsigned long symbol_size;
+ unsigned long lineno_size;
+ unsigned long unknown2;
+ unsigned long nSrcFiles;
+ unsigned long attribute;
+ unsigned long reserved[ 2 ];
+ char filename[ 1 ];
+
+} PDB_SYMBOL_FILE_EX, *PPDB_SYMBOL_FILE_EX;
+
+typedef struct _PDB_SYMBOL_SOURCE
+{
+ unsigned short nModules;
+ unsigned short nSrcFiles;
+ unsigned short table[ 1 ];
+
+} PDB_SYMBOL_SOURCE, *PPDB_SYMBOL_SOURCE;
+
+typedef struct _PDB_SYMBOL_IMPORT
+{
+ unsigned long unknown1;
+ unsigned long unknown2;
+ unsigned long TimeDateStamp;
+ unsigned long nRequests;
+ char filename[ 1 ];
+
+} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
+
+typedef struct _PDB_SYMBOLS_OLD
+{
+ unsigned short hash1_file;
+ unsigned short hash2_file;
+ unsigned short gsym_file;
+ unsigned short pad;
+ unsigned long module_size;
+ unsigned long offset_size;
+ unsigned long hash_size;
+ unsigned long srcmodule_size;
+
+} PDB_SYMBOLS_OLD, *PPDB_SYMBOLS_OLD;
+
+typedef struct _PDB_SYMBOLS
+{
+ unsigned long signature;
+ unsigned long version;
+ unsigned long unknown;
+ unsigned long hash1_file;
+ unsigned long hash2_file;
+ unsigned long gsym_file;
+ unsigned long module_size;
+ unsigned long offset_size;
+ unsigned long hash_size;
+ unsigned long srcmodule_size;
+ unsigned long pdbimport_size;
+ unsigned long resvd[ 5 ];
+
+} PDB_SYMBOLS, *PPDB_SYMBOLS;
+#pragma pack()
+
+/*========================================================================
+ * Process CodeView symbol information.
+ */
+
+/* from wine-1.0/include/wine/mscvpdb.h */
+
+struct p_string /* "Pascal string": prefixed by byte containing length */
+{
+ unsigned char namelen;
+ char name[1];
+};
+/* The other kind of "char name[1]" is a "C++ string" terminated by '\0'.
+ * "Name mangling" to encode type information often exceeds 255 bytes.
+ * Instead of using a 2-byte explicit length, they save one byte of space
+ * but incur a strlen(). This is justified by other code that wants
+ * a "C string" [terminated by '\0'] anyway.
+ */
+
+union codeview_symbol
+{
+ struct
+ {
+ short int len;
+ short int id;
+ } generic;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned short symtype;
+ struct p_string p_name;
+ } data_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int symtype;
+ unsigned int offset;
+ unsigned short segment;
+ struct p_string p_name;
+ } data_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int symtype;
+ unsigned int offset;
+ unsigned short segment;
+ char name[1]; /* terminated by '\0' */
+ } data_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int pparent;
+ unsigned int pend;
+ unsigned int next;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned short thunk_len;
+ unsigned char thtype;
+ struct p_string p_name;
+ } thunk_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int pparent;
+ unsigned int pend;
+ unsigned int next;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned short thunk_len;
+ unsigned char thtype;
+ char name[1]; /* terminated by '\0' */
+ } thunk_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int pparent;
+ unsigned int pend;
+ unsigned int next;
+ unsigned int proc_len;
+ unsigned int debug_start;
+ unsigned int debug_end;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned short proctype;
+ unsigned char flags;
+ struct p_string p_name;
+ } proc_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int pparent;
+ unsigned int pend;
+ unsigned int next;
+ unsigned int proc_len;
+ unsigned int debug_start;
+ unsigned int debug_end;
+ unsigned int proctype;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned char flags;
+ struct p_string p_name;
+ } proc_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int pparent;
+ unsigned int pend;
+ unsigned int next;
+ unsigned int proc_len;
+ unsigned int debug_start;
+ unsigned int debug_end;
+ unsigned int proctype;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned char flags;
+ char name[1]; /* terminated by '\0' */
+ } proc_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int symtype;
+ unsigned int offset;
+ unsigned short segment;
+ struct p_string p_name;
+ } public_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int symtype;
+ unsigned int offset;
+ unsigned short segment;
+ char name[1]; /* terminated by '\0' */
+ } public_v3;
+
+ struct
+ {
+ short int len; /* Total length of this entry */
+ short int id; /* Always S_BPREL_V1 */
+ unsigned int offset; /* Stack offset relative to BP */
+ unsigned short symtype;
+ struct p_string p_name;
+ } stack_v1;
+
+ struct
+ {
+ short int len; /* Total length of this entry */
+ short int id; /* Always S_BPREL_V2 */
+ unsigned int offset; /* Stack offset relative to EBP */
+ unsigned int symtype;
+ struct p_string p_name;
+ } stack_v2;
+
+ struct
+ {
+ short int len; /* Total length of this
entry */
+ short int id; /* Always S_BPREL_V3 */
+ int offset; /* Stack offset relative
to BP */
+ unsigned int symtype;
+ char name[1]; /* terminated by '\0' */
+ } stack_v3;
+
+ struct
+ {
+ short int len; /* Total length of this
entry */
+ short int id; /* Always S_BPREL_V3 */
+ int offset; /* Stack offset relative
to BP */
+ unsigned int symtype;
+ unsigned short unknown;
+ char name[1]; /* terminated by '\0' */
+ } stack_xxxx_v3;
+
+ struct
+ {
+ short int len; /* Total length of this entry */
+ short int id; /* Always S_REGISTER */
+ unsigned short type;
+ unsigned short reg;
+ struct p_string p_name;
+ /* don't handle register tracking */
+ } register_v1;
+
+ struct
+ {
+ short int len; /* Total length of this entry */
+ short int id; /* Always S_REGISTER_V2 */
+ unsigned int type; /* check whether type &
reg are correct */
+ unsigned short reg;
+ struct p_string p_name;
+ /* don't handle register tracking */
+ } register_v2;
+
+ struct
+ {
+ short int len; /* Total length of this entry */
+ short int id; /* Always S_REGISTER_V3 */
+ unsigned int type; /* check whether type &
reg are correct */
+ unsigned short reg;
+ char name[1]; /* terminated by '\0' */
+ /* don't handle register tracking */
+ } register_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int parent;
+ unsigned int end;
+ unsigned int length;
+ unsigned int offset;
+ unsigned short segment;
+ struct p_string p_name;
+ } block_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int parent;
+ unsigned int end;
+ unsigned int length;
+ unsigned int offset;
+ unsigned short segment;
+ char name[1]; /* terminated by '\0' */
+ } block_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned char flags;
+ struct p_string p_name;
+ } label_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int offset;
+ unsigned short segment;
+ unsigned char flags;
+ char name[1]; /* terminated by '\0' */
+ } label_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned short type;
+ unsigned short cvalue; /* numeric leaf */
+#if 0
+ struct p_string p_name;
+#endif
+ } constant_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned type;
+ unsigned short cvalue; /* numeric leaf */
+#if 0
+ struct p_string p_name;
+#endif
+ } constant_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned type;
+ unsigned short cvalue;
+#if 0
+ char name[1]; /* terminated by '\0' */
+#endif
+ } constant_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned short type;
+ struct p_string p_name;
+ } udt_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned type;
+ struct p_string p_name;
+ } udt_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int type;
+ char name[1]; /* terminated by '\0' */
+ } udt_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ char signature[4];
+ struct p_string p_name;
+ } objname_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int unknown;
+ struct p_string p_name;
+ } compiland_v1;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned unknown1[4];
+ unsigned short unknown2;
+ struct p_string p_name;
+ } compiland_v2;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int unknown;
+ char name[1]; /* terminated by '\0' */
+ } compiland_v3;
+
+ struct
+ {
+ short int len;
+ short int id;
+ unsigned int offset;
+ unsigned short segment;
+ } ssearch_v1;
+};
+
+#define S_COMPILAND_V1 0x0001
+#define S_REGISTER_V1 0x0002
+#define S_CONSTANT_V1 0x0003
+#define S_UDT_V1 0x0004
+#define S_SSEARCH_V1 0x0005
+#define S_END_V1 0x0006
+#define S_SKIP_V1 0x0007
+#define S_CVRESERVE_V1 0x0008
+#define S_OBJNAME_V1 0x0009
+#define S_ENDARG_V1 0x000a
+#define S_COBOLUDT_V1 0x000b
+#define S_MANYREG_V1 0x000c
+#define S_RETURN_V1 0x000d
+#define S_ENTRYTHIS_V1 0x000e
+
+#define S_BPREL_V1 0x0200
+#define S_LDATA_V1 0x0201
+#define S_GDATA_V1 0x0202
+#define S_PUB_V1 0x0203
+#define S_LPROC_V1 0x0204
+#define S_GPROC_V1 0x0205
+#define S_THUNK_V1 0x0206
+#define S_BLOCK_V1 0x0207
+#define S_WITH_V1 0x0208
+#define S_LABEL_V1 0x0209
+#define S_CEXMODEL_V1 0x020a
+#define S_VFTPATH_V1 0x020b
+#define S_REGREL_V1 0x020c
+#define S_LTHREAD_V1 0x020d
+#define S_GTHREAD_V1 0x020e
+
+#define S_PROCREF_V1 0x0400
+#define S_DATAREF_V1 0x0401
+#define S_ALIGN_V1 0x0402
+#define S_LPROCREF_V1 0x0403
+
+#define S_REGISTER_V2 0x1001 /* Variants with new 32-bit type indices */
+#define S_CONSTANT_V2 0x1002
+#define S_UDT_V2 0x1003
+#define S_COBOLUDT_V2 0x1004
+#define S_MANYREG_V2 0x1005
+#define S_BPREL_V2 0x1006
+#define S_LDATA_V2 0x1007
+#define S_GDATA_V2 0x1008
+#define S_PUB_V2 0x1009
+#define S_LPROC_V2 0x100a
+#define S_GPROC_V2 0x100b
+#define S_VFTTABLE_V2 0x100c
+#define S_REGREL_V2 0x100d
+#define S_LTHREAD_V2 0x100e
+#define S_GTHREAD_V2 0x100f
+#if 0
+#define S_XXXXXXXXX_32 0x1012 /* seems linked to a function, content
unknown */
+#endif
+#define S_COMPILAND_V2 0x1013
+
+#define S_COMPILAND_V3 0x1101
+#define S_THUNK_V3 0x1102
+#define S_BLOCK_V3 0x1103
+#define S_LABEL_V3 0x1105
+#define S_REGISTER_V3 0x1106
+#define S_CONSTANT_V3 0x1107
+#define S_UDT_V3 0x1108
+#define S_BPREL_V3 0x110B
+#define S_LDATA_V3 0x110C
+#define S_GDATA_V3 0x110D
+#define S_PUB_V3 0x110E
+#define S_LPROC_V3 0x110F
+#define S_GPROC_V3 0x1110
+#define S_BPREL_XXXX_V3 0x1111 /* not really understood, but looks like
bprel... */
+#define S_MSTOOL_V3 0x1116 /* compiler command line options and build
information */
+#define S_PUB_FUNC1_V3 0x1125 /* didn't get the difference between the
two */
+#define S_PUB_FUNC2_V3 0x1127
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- pdb-reading: bits and pieces ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+struct pdb_reader
+{
+ void* (*read_file)(struct pdb_reader*, unsigned, unsigned *);
+ // JRS 2009-Apr-8: .uu_n_pdbimage is never used.
+ UChar* pdbimage; // image address
+ SizeT uu_n_pdbimage; // size
+ union {
+ struct {
+ struct PDB_JG_HEADER* header;
+ struct PDB_JG_TOC* toc;
+ } jg;
+ struct {
+ struct PDB_DS_HEADER* header;
+ struct PDB_DS_TOC* toc;
+ } ds;
+ } u;
+};
+
+
+static void* pdb_ds_read( struct pdb_reader* pdb,
+ unsigned* block_list,
+ unsigned size )
+{
+ unsigned blocksize, nBlocks;
+ UChar* buffer;
+ UInt i;
+
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_dispatch/dispatch-mips32-linux.S Thu Nov 22
04:55:39 2012
@@ -0,0 +1,245 @@
+
+/*--------------------------------------------------------------------*/
+/*--- The core dispatch loop, for jumping to a code address. ---*/
+/*--- dispatch-mips-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2012 RT-RK
+ mips-v...@rt-rk.com
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+
+#if defined(VGP_mips32_linux)
+
+#include "pub_core_basics_asm.h"
+#include "pub_core_dispatch_asm.h"
+#include "pub_core_transtab_asm.h"
+#include "libvex_guest_offsets.h" /* for OFFSET_mips_PC */
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- The dispatch loop. VG_(disp_run_translations) is ---*/
+/*--- used to run all translations, ---*/
+/*--- including no-redir ones. ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+/*----------------------------------------------------*/
+/*--- Entry and preamble (set everything up) ---*/
+/*----------------------------------------------------*/
+
+/* signature:
+void VG_(disp_run_translations)( UWord* two_words,
+ void* guest_state,
+ Addr host_addr );
+*/
+
+.text
+.globl VG_(disp_run_translations)
+VG_(disp_run_translations):
+ /* a0 ($4) holds two_words */
+ /* a1 ($5) holds guest_state */
+ /* a2 ($6) holds host_addr */
+
+ /* New stack frame. Stack must remain 8 aligned (at least) */
+ addiu $29, -64
+
+ /* Save ra */
+ sw $31, 16($29)
+
+ /* ... and s0 - s7 */
+ sw $16, 20($29)
+ sw $17, 24($29)
+ sw $18, 28($29)
+ sw $19, 32($29)
+ sw $20, 36($29)
+ sw $21, 40($29)
+ sw $22, 44($29)
+ sw $23, 48($29)
+
+ /* ... and gp, fp/s8 */
+ sw $28, 52($29)
+ sw $30, 56($29)
+
+ /* Save a0 ($4) on stack. In postamble it will be restored such that
the
+ return values can be written */
+ sw $4, 60($29)
+
+ /* Load address of guest state into guest state register (r10) */
+ move $10, $5
+
+ /* and jump into the code cache. Chained translations in
+ the code cache run, until for whatever reason, they can't
+ continue. When that happens, the translation in question
+ will jump (or call) to one of the continuation points
+ VG_(cp_...) below. */
+ jr $6
+ /*NOTREACHED*/
+
+/*----------------------------------------------------*/
+/*--- Postamble and exit. ---*/
+/*----------------------------------------------------*/
+
+postamble:
+ /* At this point, r2 and r3 contain two
+ words to be returned to the caller. r2
+ holds a TRC value, and r3 optionally may
+ hold another word (for CHAIN_ME exits, the
+ address of the place to patch.) */
+
+ /* Restore $4 from stack; holds address of two_words */
+ lw $4, 60($29)
+ sw $2, 0($4) /* Store $2 to two_words[0] */
+ sw $3, 4($4) /* Store $3 to two_words[1] */
+
+ /* Restore callee-saved registers... */
+
+ /* Restore ra */
+ lw $31, 16($29)
+
+ /* ... and s0 - s7 */
+ lw $16, 20($29)
+ lw $17, 24($29)
+ lw $18, 28($29)
+ lw $19, 32($29)
+ lw $20, 36($29)
+ lw $21, 40($29)
+ lw $22, 44($29)
+ lw $23, 48($29)
+
+ /* ... and gp, fp/s8 */
+ lw $28, 52($29)
+ lw $30, 56($29)
+
+ addiu $29, 64 /* stack_size */
+ jr $31
+ nop
+
+/*----------------------------------------------------*/
+/*--- Continuation points ---*/
+/*----------------------------------------------------*/
+
+/* ------ Chain me to slow entry point ------ */
+.global VG_(disp_cp_chain_me_to_slowEP)
+VG_(disp_cp_chain_me_to_slowEP):
+ /* We got called. The return address indicates
+ where the patching needs to happen. Collect
+ the return address and, exit back to C land,
+ handing the caller the pair (Chain_me_S, RA) */
+ li $2, VG_TRC_CHAIN_ME_TO_SLOW_EP
+ move $3, $31
+ /* 8 = mkLoadImm_EXACTLY2or5
+ 4 = jalr $9
+ 4 = nop */
+ addiu $3, $3, -16
+ b postamble
+
+/* ------ Chain me to slow entry point ------ */
+.global VG_(disp_cp_chain_me_to_fastEP)
+VG_(disp_cp_chain_me_to_fastEP):
+ /* We got called. The return address indicates
+ where the patching needs to happen. Collect
+ the return address and, exit back to C land,
+ handing the caller the pair (Chain_me_S, RA) */
+ li $2, VG_TRC_CHAIN_ME_TO_FAST_EP
+ move $3, $31
+ /* 8 = mkLoadImm_EXACTLY2or5
+ 4 = jalr $9
+ 4 = nop */
+ addiu $3, $3, -16
+ b postamble
+
+/* ------ Indirect but boring jump ------ */
+.global VG_(disp_cp_xindir)
+VG_(disp_cp_xindir):
+ /* Where are we going? */
+ lw $11, OFFSET_mips32_PC($10)
+
+ lw $13, vgPlain_stats__n_xindirs_32
+ addiu $13, $13, 0x1
+ sw $13, vgPlain_stats__n_xindirs_32
+
+ /* try a fast lookup in the translation cache */
+ /* t1 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
+ = (t8 >> 2 & VG_TT_FAST_MASK) << 3 */
+
+ move $14, $11
+ li $12, VG_TT_FAST_MASK
+ srl $14, $14, 2
+ and $14, $14, $12
+ sll $14, $14, 3
+
+ /* t2 = (addr of VG_(tt_fast)) + t1 */
+ la $13, VG_(tt_fast)
+ addu $13, $13, $14
+
+ lw $12, 0($13) /* t3 = VG_(tt_fast)[hash] :: ULong* */
+ addi $13, $13, 4
+ lw $25, 0($13) /* little-endian, so comparing 1st 32bit word */
+ nop
+
+check:
+ bne $12, $11, fast_lookup_failed
+ /* run the translation */
+ jr $25
+ .long 0x0 /* persuade insn decoders not to speculate past here
*/
+
+fast_lookup_failed:
+ /* %PC is up to date */
+ /* back out decrement of the dispatch counter */
+ /* hold dispatch_ctr in t0 (r8) */
+ lw $13, vgPlain_stats__n_xindirs_32
+ addiu $13, $13, 0x1
+ sw $13, vgPlain_stats__n_xindirs_32
+ li $2, VG_TRC_INNER_FASTMISS
+ li $3, 0
+ b postamble
+
+/* ------ Assisted jump ------ */
+ .global VG_(disp_cp_xassisted)
+VG_(disp_cp_xassisted):
+ /* guest-state-pointer contains the TRC. Put the value into the
+ return register */
+ move $2, $10
+ move $3, $0
+ b postamble
+
+/* ------ Event check failed ------ */
+ .global VG_(disp_cp_evcheck_fail)
+VG_(disp_cp_evcheck_fail):
+ li $2, VG_TRC_INNER_COUNTERZERO
+ move $3, $0
+ b postamble
+
+.size VG_(disp_run_translations), .-VG_(disp_run_translations)
+
+
+/* Let the linker know we do not need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+#endif // defined(VGP_mips32_linux)
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_errormgr.c.orig Thu Nov 22 04:55:39 2012
@@ -0,0 +1,1552 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Management of error messages. m_errormgr.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2011 Julian Seward
+ jse...@acm.org
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_libcsetjmp.h"
+#include "pub_core_threadstate.h" // For VG_N_THREADS
+#include "pub_core_debugger.h"
+#include "pub_core_debuginfo.h"
+#include "pub_core_errormgr.h"
+#include "pub_core_execontext.h"
+#include "pub_core_gdbserver.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcfile.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_libcproc.h" // For VG_(getpid)()
+#include "pub_core_seqmatch.h"
+#include "pub_core_mallocfree.h"
+#include "pub_core_options.h"
+#include "pub_core_stacktrace.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_translate.h" // for VG_(translate)()
+#include "pub_core_xarray.h" // VG_(xaprintf) et al
+
+/*------------------------------------------------------------*/
+/*--- Globals ---*/
+/*------------------------------------------------------------*/
+
+/* After this many different unsuppressed errors have been observed,
+ be more conservative about collecting new ones. */
+#define M_COLLECT_ERRORS_SLOWLY_AFTER 100
+
+/* After this many different unsuppressed errors have been observed,
+ stop collecting errors at all, and tell the user their program is
+ evidently a steaming pile of camel dung. */
+#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000
+
+/* After this many total errors have been observed, stop collecting
+ errors at all. Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
+#define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000
+
+/* The list of error contexts found, both suppressed and unsuppressed.
+ Initially empty, and grows as errors are detected. */
+static Error* errors = NULL;
+
+/* The list of suppression directives, as read from the specified
+ suppressions file. Note that the list gets rearranged as a result
+ of the searches done by is_suppressible_error(). */
+static Supp* suppressions = NULL;
+
+/* Running count of unsuppressed errors detected. */
+static UInt n_errs_found = 0;
+
+/* Running count of suppressed errors detected. */
+static UInt n_errs_suppressed = 0;
+
+/* Running count of unsuppressed error contexts. */
+static UInt n_err_contexts = 0;
+
+/* Running count of suppressed error contexts. */
+static UInt n_supp_contexts = 0;
+
+
+/* forwards ... */
+static Supp* is_suppressible_error ( Error* err );
+
+static ThreadId last_tid_printed = 1;
+
+/* Stats: number of searches of the error list initiated. */
+static UWord em_errlist_searches = 0;
+
+/* Stats: number of comparisons done during error list
+ searching. */
+static UWord em_errlist_cmps = 0;
+
+/* Stats: number of searches of the suppression list initiated. */
+static UWord em_supplist_searches = 0;
+
+/* Stats: number of comparisons done during suppression list
+ searching. */
+static UWord em_supplist_cmps = 0;
+
+/*------------------------------------------------------------*/
+/*--- Error type ---*/
+/*------------------------------------------------------------*/
+
+/* Errors. Extensible (via the 'extra' field). Tools can use a normal
+ enum (with element values in the normal range (0..)) for 'ekind'.
+ Functions for getting/setting the tool-relevant fields are in
+ include/pub_tool_errormgr.h.
+
+ When errors are found and recorded with VG_(maybe_record_error)(), all
+ the tool must do is pass in the four parameters; core will
+ allocate/initialise the error record.
+*/
+struct _Error {
+ struct _Error* next;
+ // Unique tag. This gives the error a unique identity (handle) by
+ // which it can be referred to afterwords. Currently only used for
+ // XML printing.
+ UInt unique;
+ // NULL if unsuppressed; or ptr to suppression record.
+ Supp* supp;
+ Int count;
+
+ // The tool-specific part
+ ThreadId tid; // Initialised by core
+ ExeContext* where; // Initialised by core
+ ErrorKind ekind; // Used by ALL. Must be in the range (0..)
+ Addr addr; // Used frequently
+ Char* string; // Used frequently
+ void* extra; // For any tool-specific extras
+};
+
+
+ExeContext* VG_(get_error_where) ( Error* err )
+{
+ return err->where;
+}
+
+ErrorKind VG_(get_error_kind) ( Error* err )
+{
+ return err->ekind;
+}
+
+Addr VG_(get_error_address) ( Error* err )
+{
+ return err->addr;
+}
+
+Char* VG_(get_error_string) ( Error* err )
+{
+ return err->string;
+}
+
+void* VG_(get_error_extra) ( Error* err )
+{
+ return err->extra;
+}
+
+UInt VG_(get_n_errs_found)( void )
+{
+ return n_errs_found;
+}
+
+/*------------------------------------------------------------*/
+/*--- Suppression type ---*/
+/*------------------------------------------------------------*/
+
+/* Note: it is imperative this doesn't overlap with (0..) at all, as tools
+ * effectively extend it by defining their own enums in the (0..) range. */
+typedef
+ enum {
+ // Nb: thread errors are a relic of the time when Valgrind's core
+ // could detect them. This example is left commented-out as an
+ // example should new core errors ever be added.
+ ThreadSupp = -1, /* Matches ThreadErr */
+ }
+ CoreSuppKind;
+
+/* Max number of callers for context in a suppression. */
+#define VG_MAX_SUPP_CALLERS 24
+
+/* For each caller specified for a suppression, record the nature of
+ the caller name. Not of interest to tools. */
+typedef
+ enum {
+ NoName, /* Error case */
+ ObjName, /* Name is of an shared object file. */
+ FunName, /* Name is of a function. */
+ DotDotDot /* Frame-level wildcard */
+ }
+ SuppLocTy;
+
+typedef
+ struct {
+ SuppLocTy ty;
+ Char* name; /* NULL for NoName and DotDotDot */
+ }
+ SuppLoc;
+
+/* Suppressions. Tools can get/set tool-relevant parts with functions
+ declared in include/pub_tool_errormgr.h. Extensible via the 'extra'
field.
+ Tools can use a normal enum (with element values in the normal range
+ (0..)) for 'skind'. */
+struct _Supp {
+ struct _Supp* next;
+ Int count; // The number of times this error has been suppressed.
+ Char* sname; // The name by which the suppression is referred to.
+
+ // Length of 'callers'
+ Int n_callers;
+ // Array of callers, for matching stack traces. First one (name of fn
+ // where err occurs) is mandatory; rest are optional.
+ SuppLoc* callers;
+
+ /* The tool-specific part */
+ SuppKind skind; // What kind of suppression. Must use the range
(0..).
+ Char* string; // String -- use is optional. NULL by default.
+ void* extra; // Anything else -- use is optional. NULL by default.
+};
+
+SuppKind VG_(get_supp_kind) ( Supp* su )
+{
+ return su->skind;
+}
+
+Char* VG_(get_supp_string) ( Supp* su )
+{
+ return su->string;
+}
+
+void* VG_(get_supp_extra) ( Supp* su )
+{
+ return su->extra;
+}
+
+
+void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
+{
+ su->skind = skind;
+}
+
+void VG_(set_supp_string) ( Supp* su, Char* string )
+{
+ su->string = string;
+}
+
+void VG_(set_supp_extra) ( Supp* su, void* extra )
+{
+ su->extra = extra;
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Helper fns ---*/
+/*------------------------------------------------------------*/
+
+// Only show core errors if the tool wants to, we're not running with -q,
+// and were not outputting XML.
+Bool VG_(showing_core_errors)(void)
+{
+ return VG_(needs).core_errors && VG_(clo_verbosity) >= 1
&& !VG_(clo_xml);
+}
+
+/* Compare errors, to detect duplicates.
+*/
+static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
+{
+ if (e1->ekind != e2->ekind)
+ return False;
+ if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
+ return False;
+
+ switch (e1->ekind) {
+ //(example code, see comment on CoreSuppKind above)
+ //case ThreadErr:
+ // vg_assert(VG_(needs).core_errors);
+ // return <something>
+ default:
+ if (VG_(needs).tool_errors) {
+ return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
+ } else {
+ VG_(printf)("\nUnhandled error type: %u.
VG_(needs).tool_errors\n"
+ "probably needs to be set.\n",
+ e1->ekind);
+ VG_(tool_panic)("unhandled error type");
+ }
+ }
+}
+
+
+/* Helper functions for suppression generation: print a single line of
+ a suppression pseudo-stack-trace, either in XML or text mode. It's
+ important that the behaviour of these two functions exactly
+ corresponds.
+*/
+#define ERRTXT_LEN 4096
+
+static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
+{
+ static UChar buf[ERRTXT_LEN];
+ if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
+ VG_(printf_xml)(" <sframe> <fun>%pS</fun> </sframe>\n", buf);
+ } else
+ if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
+ VG_(printf_xml)(" <sframe> <obj>%pS</obj> </sframe>\n", buf);
+ } else {
+ VG_(printf_xml)(" <sframe> <obj>*</obj> </sframe>\n");
+ }
+}
+
+static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
+{
+ static UChar buf[ERRTXT_LEN];
+ XArray* /* of HChar */ text = (XArray*)textV;
+ if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
+ VG_(xaprintf)(text, " fun:%s\n", buf);
+ } else
+ if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
+ VG_(xaprintf)(text, " obj:%s\n", buf);
+ } else {
+ VG_(xaprintf)(text, " obj:*\n");
+ }
+}
+
+/* Generate a suppression for an error, either in text or XML mode.
+*/
+static void gen_suppression(Error* err)
+{
+ Char xtra[256]; /* assumed big enough (is overrun-safe) */
+ Bool anyXtra;
+ Char* name;
+ ExeContext* ec;
+ XArray* /* HChar */ text;
+
+ const HChar* dummy_name = "insert_a_suppression_name_here";
+
+ vg_assert(err);
+
+ ec = VG_(get_error_where)(err);
+ vg_assert(ec);
+
+ name = VG_TDICT_CALL(tool_get_error_name, err);
+ if (NULL == name) {
+ VG_(umsg)("(%s does not allow error to be suppressed)\n",
+ VG_(details).name);
+ return;
+ }
+
+ /* In XML mode, we also need to print the plain text version of the
+ suppresion in a CDATA section. What that really means is, we
+ need to generate the plaintext version both in XML and text
+ mode. So generate it into TEXT. */
+ text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
+ VG_(free), sizeof(HChar) );
+ vg_assert(text);
+
+ /* Ok. Generate the plain text version into TEXT. */
+ VG_(xaprintf)(text, "{\n");
+ VG_(xaprintf)(text, " <%s>\n", dummy_name);
+ VG_(xaprintf)(text, " %s:%s\n", VG_(details).name, name);
+
+ VG_(memset)(xtra, 0, sizeof(xtra));
+ anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
+ err, xtra, sizeof(xtra));
+ vg_assert(xtra[sizeof(xtra)-1] == 0);
+
+ if (anyXtra)
+ VG_(xaprintf)(text, " %s\n", xtra);
+
+ // Print stack trace elements
+ UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
+ tl_assert(n_ips > 0);
+ if (n_ips > VG_MAX_SUPP_CALLERS)
+ n_ips = VG_MAX_SUPP_CALLERS;
+ VG_(apply_StackTrace)(printSuppForIp_nonXML,
+ text,
+ VG_(get_ExeContext_StackTrace)(ec),
+ n_ips);
+
+ VG_(xaprintf)(text, "}\n");
+ // zero terminate
+ VG_(xaprintf)(text, "%c", (HChar)0 );
+ // VG_(printf) of text
+
+ /* And now display it. */
+ if (! VG_(clo_xml) ) {
+
+ // the simple case
+ VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
+
+ } else {
+
+ /* Now we have to print the XML directly. No need to go to the
+ effort of stuffing it in an XArray, since we won't need it
+ again. */
+ VG_(printf_xml)(" <suppression>\n");
+ VG_(printf_xml)(" <sname>%s</sname>\n", dummy_name);
+ VG_(printf_xml)(
+ " <skind>%pS:%pS</skind>\n", VG_(details).name,
name);
+ if (anyXtra)
+ VG_(printf_xml)(" <skaux>%pS</skaux>\n", xtra);
+
+ // Print stack trace elements
+ VG_(apply_StackTrace)(printSuppForIp_XML,
+ NULL,
+ VG_(get_ExeContext_StackTrace)(ec),
+ VG_(get_ExeContext_n_ips)(ec));
+
+ // And now the cdata bit
+ // XXX FIXME! properly handle the case where the raw text
+ // itself contains "]]>", as specified in Protocol 4.
+ VG_(printf_xml)(" <rawtext>\n");
+ VG_(printf_xml)("<![CDATA[\n");
+ VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
+ VG_(printf_xml)("]]>\n");
+ VG_(printf_xml)(" </rawtext>\n");
+ VG_(printf_xml)(" </suppression>\n");
+
+ }
+
+ VG_(deleteXA)(text);
+}
+
+
+/* Figure out if we want to perform a given action for this error,
+ possibly by asking the user.
+*/
+Bool VG_(is_action_requested) ( Char* action, Bool* clo )
+{
+ Char ch, ch2;
+ Int res;
+
+ /* First off, we shouldn't be asking the user anything if
+ we're in XML mode. */
+ if (VG_(clo_xml))
+ return False; /* That's a Nein, oder Nay as they say down here in
B-W */
+
+ if (*clo == False)
+ return False;
+
+ VG_(umsg)("\n");
+
+ again:
+ VG_(printf)(
+ "==%d== "
+ "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",
+ VG_(getpid)(), action
+ );
+
+ res = VG_(read)(VG_(clo_input_fd), &ch, 1);
+ if (res != 1) goto ioerror;
+ /* res == 1 */
+ if (ch == '\n') return False;
+ if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y'
+ && ch != 'C' && ch != 'c') goto again;
+
+ res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
+ if (res != 1) goto ioerror;
+ if (ch2 != '\n') goto again;
+
+ /* No, don't want to do action. */
+ if (ch == 'n' || ch == 'N') return False;
+ /* Yes, want to do action. */
+ if (ch == 'y' || ch == 'Y') return True;
+ /* No, don't want to do action, and don't ask again either. */
+ vg_assert(ch == 'c' || ch == 'C');
+
+ ioerror:
+ *clo = False;
+ return False;
+}
+
+
+/* Do text-mode actions on error, that is, immediately after an error
+ is printed. These are:
+ * possibly, attach to a debugger
+ * possibly, generate a suppression.
+ Note this should not be called in XML mode!
+*/
+static
+void do_actions_on_error(Error* err, Bool allow_db_attach)
+{
+ Bool still_noisy = True;
+
+ /* Should be assured by caller */
+ vg_assert( ! VG_(clo_xml) );
+
+ /* if user wants to debug from a certain error nr, then wait for
gdb/vgdb */
+ if (VG_(clo_vgdb) != Vg_VgdbNo
+ && allow_db_attach
+ && VG_(dyn_vgdb_error) <= n_errs_found) {
+ VG_(umsg)("(action on error) vgdb me ... \n");
+ VG_(gdbserver)( err->tid );
+ VG_(umsg)("Continuing ...\n");
+ }
+
+ /* Perhaps we want a debugger attach at this point? */
+ /* GDBTD ??? maybe we should/could remove the below assuming the
+ gdbserver interface is better ??? */
+ if (allow_db_attach &&
+ VG_(is_action_requested)( "Attach to debugger", &
VG_(clo_db_attach) ))
+ {
+ if (0) VG_(printf)("starting debugger\n");
+ VG_(start_debugger)( err->tid );
+ }
+ /* Or maybe we want to generate the error's suppression? */
+ if (VG_(clo_gen_suppressions) == 2
+ || (VG_(clo_gen_suppressions) == 1
+ && VG_(is_action_requested)( "Print suppression", &still_noisy
))
+ ) {
+ gen_suppression(err);
+ }
+ if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
+ VG_(clo_gen_suppressions) = 0;
+}
+
+// See https://bugs.kde.org/show_bug.cgi?id=265803 and b/3423996
+static Bool seen_pc_with_no_function_name_nor_object_file_name = False;
+
+static Bool ErrHasNoFunctionNamesNorObjectFileNames(Error *err) {
+ // boil out if the stack trace has no function/object names.
+ StackTrace ips = VG_(get_ExeContext_StackTrace)(err->where);
+ UWord n_ips = VG_(get_ExeContext_n_ips)(err->where);
+ UWord i;
+ for (i = 0; i < n_ips; i++) {
+ Addr ip = ips[i];
+ Char buffer[1024];
+ if (VG_(get_fnname)(ip, buffer, sizeof(buffer))) {
+ return False;
+ }
+ if (VG_(get_objname)(ip, buffer, sizeof(buffer))) {
+ return False;
+ }
+ }
+ if (!seen_pc_with_no_function_name_nor_object_file_name)
+ VG_(umsg)("\n\n\nWARNING: Valgrind encountered a stack trace which
has\n"
+ "no function names nor object file names.\n"
+ "Unless your program has a dynamically generated code (e.g.
it is a JIT)\n"
+ "something is very much wrong with your binary's debug
info.\n"
+ "See https://bugs.kde.org/show_bug.cgi?id=265803 and
b/3423996\n\n\n"
+ );
+ seen_pc_with_no_function_name_nor_object_file_name = True;
+ return True;
+}
+
+/* Prints an error. Not entirely simple because of the differences
+ between XML and text mode output.
+
+ In XML mode:
+
+ * calls the tool's pre-show method, so the tool can create any
+ preamble ahead of the message, if it wants.
+
+ * prints the opening tag, and the <unique> and <tid> fields
+
+ * prints the tool-specific parts of the message
+
+ * if suppression generation is required, a suppression
+
+ * the closing tag
+
+ In text mode:
+
+ * calls the tool's pre-show method, so the tool can create any
+ preamble ahead of the message, if it wants.
+
+ * prints the tool-specific parts of the message
+
+ * calls do_actions_on_error. This optionally does a debugger
+ attach (and detach), and optionally prints a suppression; both
+ of these may require user input.
+*/
+static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
+{
+ /* If this fails, you probably specified your tool's method
+ dictionary incorrectly. */
+ vg_assert(VG_(needs).tool_errors);
+
+ if (xml) {
+
+ /* Note, allow_db_attach is ignored in here. */
+
+ /* Ensure that suppression generation is either completely
+ enabled or completely disabled; either way, we won't require
+ any user input. m_main.process_cmd_line_options should
+ ensure the asserted condition holds. */
+ vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
+ || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
+
+ /* Pre-show it to the tool */
+ VG_TDICT_CALL( tool_before_pp_Error, err );
+
+ /* standard preamble */
+ VG_(printf_xml)("<error>\n");
+ VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
+ VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
+
+ /* actually print it */
+ VG_TDICT_CALL( tool_pp_Error, err );
+
+ if (VG_(clo_gen_suppressions) > 0)
+ gen_suppression(err);
+
+ /* postamble */
+ VG_(printf_xml)("</error>\n");
+ VG_(printf_xml)("\n");
+
+ } else {
+
+ VG_TDICT_CALL( tool_before_pp_Error, err );
+
+ if (VG_(tdict).tool_show_ThreadIDs_for_errors
+ && err->tid > 0 && err->tid != last_tid_printed) {
+ VG_(umsg)("Thread %d:\n", err->tid );
+ last_tid_printed = err->tid;
+ }
+
+ VG_TDICT_CALL( tool_pp_Error, err );
+ VG_(umsg)("\n");
+
+ do_actions_on_error(err, allow_db_attach);
+ }
+}
+
+
+/* Construct an error */
+static
+void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
+ Char* s, void* extra, ExeContext* where )
+{
+ /* DO NOT MAKE unique_counter NON-STATIC */
+ static UInt unique_counter = 0;
+
+ tl_assert(tid < VG_N_THREADS);
+
+ /* Core-only parts */
+ err->unique = unique_counter++;
+ err->next = NULL;
+ err->supp = NULL;
+ err->count = 1;
+ err->tid = tid;
+ if (NULL == where)
+ err->where = VG_(record_ExeContext)( tid, 0 );
+ else
+ err->where = where;
+
+ /* Tool-relevant parts */
+ err->ekind = ekind;
+ err->addr = a;
+ err->extra = extra;
+ err->string = s;
+
+ /* sanity... */
+ vg_assert( tid < VG_N_THREADS );
+}
+
+
+
+static Int n_errs_shown = 0;
+
+/* Top-level entry point to the error management subsystem.
+ All detected errors are notified here; this routine decides if/when the
+ user should see the error. */
+void VG_(maybe_record_error) ( ThreadId tid,
+ ErrorKind ekind, Addr a, Char* s, void*
extra )
+{
+ Error err;
+ Error* p;
+ Error* p_prev;
+ UInt extra_size;
+ VgRes exe_res = Vg_MedRes;
+ static Bool stopping_message = False;
+ static Bool slowdown_message = False;
+
+ /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
+ been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
+ have been found, just refuse to collect any more. This stops
+ the burden of the error-management system becoming excessive in
+ extremely buggy programs, although it does make it pretty
+ pointless to continue the Valgrind run after this point. */
+ if (VG_(clo_error_limit)
+ && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
+ || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
+ && !VG_(clo_xml)) {
+ if (!stopping_message) {
+ VG_(umsg)("\n");
+
+ if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
+ VG_(umsg)(
+ "More than %d different errors detected. "
+ "I'm not reporting any more.\n",
+ M_COLLECT_NO_ERRORS_AFTER_SHOWN );
+ } else {
+ VG_(umsg)(
+ "More than %d total errors detected. "
+ "I'm not reporting any more.\n",
+ M_COLLECT_NO_ERRORS_AFTER_FOUND );
+ }
+
+ VG_(umsg)("Final error counts will be inaccurate. "
+ "Go fix your program!\n");
+ VG_(umsg)("Rerun with --error-limit=no to disable "
+ "this cutoff. Note\n");
+ VG_(umsg)("that errors may occur in your program without "
+ "prior warning from\n");
+ VG_(umsg)("Valgrind, because errors are no longer "
+ "being displayed.\n");
+ VG_(umsg)("\n");
+ stopping_message = True;
+ }
+ return;
+ }
+
+ /* Ignore it if error acquisition is disabled for this thread. */
+ { ThreadState* tst = VG_(get_ThreadState)(tid);
+ if (tst->err_disablement_level > 0)
+ return;
+ }
+
+ /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
+ been found, be much more conservative about collecting new
+ ones. */
+ if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
+ && !VG_(clo_xml)) {
+ exe_res = Vg_LowRes;
+ if (!slowdown_message) {
+ VG_(umsg)("\n");
+ VG_(umsg)("More than %d errors detected. Subsequent errors\n",
+ M_COLLECT_ERRORS_SLOWLY_AFTER);
+ VG_(umsg)("will still be recorded, but in less "
+ "detail than before.\n");
+ slowdown_message = True;
+ }
+ } else if (seen_pc_with_no_function_name_nor_object_file_name) {
+ // we are probably inside some unknown code -- don't spend too much
time
+ // matching the error reports.
+ exe_res = Vg_LowRes;
+ }
+
+ /* Build ourselves the error */
+ construct_error ( &err, tid, ekind, a, s, extra, NULL );
+
+ /* First, see if we've got an error record matching this one. */
+ em_errlist_searches++;
+ p = errors;
+ p_prev = NULL;
+ while (p != NULL) {
+ em_errlist_cmps++;
+ if (eq_Error(exe_res, p, &err)) {
+ /* Found it. */
+ p->count++;
+ if (p->supp != NULL) {
+ /* Deal correctly with suppressed errors. */
+ p->supp->count++;
+ n_errs_suppressed++;
+ } else {
+ if (!seen_pc_with_no_function_name_nor_object_file_name)
+ n_errs_found++;
+ }
+
+ /* Move p to the front of the list so that future searches
+ for it are faster. It also allows to print the last
+ error (see VG_(show_last_error). */
+ if (p_prev != NULL) {
+ vg_assert(p_prev->next == p);
+ p_prev->next = p->next;
+ p->next = errors;
+ errors = p;
+ }
+
+ return;
+ }
+ p_prev = p;
+ p = p->next;
+ }
+
+ /* Didn't see it. Copy and add. */
+
+ /* OK, we're really going to collect it. The context is on the stack
and
+ will disappear shortly, so we must copy it. First do the main
+ (non-'extra') part.
+
+ Then VG_(tdict).tool_update_extra can update the 'extra' part. This
+ is for when there are more details to fill in which take time to work
+ out but don't affect our earlier decision to include the error -- by
+ postponing those details until now, we avoid the extra work in the
+ case where we ignore the error. Ugly.
+
+ Then, if there is an 'extra' part, copy it too, using the size that
+ VG_(tdict).tool_update_extra returned. Also allow for people using
+ the void* extra field for a scalar value like an integer.
+ */
+
+ /* copy main part */
+ p = VG_(arena_malloc)(VG_AR_ERRORS, "errormgr.mre.1", sizeof(Error));
+ *p = err;
+
+ /* update 'extra' */
+ switch (ekind) {
+ //(example code, see comment on CoreSuppKind above)
+ //case ThreadErr:
+ // vg_assert(VG_(needs).core_errors);
+ // extra_size = <something>
+ // break;
+ default:
+ vg_assert(VG_(needs).tool_errors);
+ extra_size = VG_TDICT_CALL(tool_update_extra, p);
+ break;
+ }
+
+ /* copy block pointed to by 'extra', if there is one */
+ if (NULL != p->extra && 0 != extra_size) {
+ void* new_extra = VG_(malloc)("errormgr.mre.2", extra_size);
+ VG_(memcpy)(new_extra, p->extra, extra_size);
+ p->extra = new_extra;
+ }
+
+ p->next = errors;
+ p->supp = is_suppressible_error(&err);
+ errors = p;
+
+ if (ErrHasNoFunctionNamesNorObjectFileNames(p))
+ return;
+
+ if (p->supp == NULL) {
+ n_err_contexts++;
+ n_errs_found++;
+ /* Actually show the error; more complex than you might think. */
+ pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
+ /* update stats */
+ n_errs_shown++;
+ } else {
+ n_supp_contexts++;
+ n_errs_suppressed++;
+ p->supp->count++;
+ }
+}
+
+/* Second top-level entry point to the error management subsystem, for
+ errors that the tool wants to report immediately, eg. because they're
+ guaranteed to only happen once. This avoids all the recording and
+ comparing stuff. But they can be suppressed; returns True if it is
+ suppressed. Bool 'print_error' dictates whether to print the error.
+ Bool 'count_error' dictates whether to count the error in n_errs_found.
+*/
+Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
+ void* extra, ExeContext* where, Bool print_error,
+ Bool allow_db_attach, Bool count_error )
+{
+ Error err;
+ Supp *su;
+
+ /* Ignore it if error acquisition is disabled for this thread. */
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+ if (tst->err_disablement_level > 0)
+ return False; /* ignored, not suppressed */
+
+ /* Build ourselves the error */
+ construct_error ( &err, tid, ekind, a, s, extra, where );
+
+ /* Unless it's suppressed, we're going to show it. Don't need to make
+ a copy, because it's only temporary anyway.
+
+ Then update the 'extra' part with VG_(tdict).tool_update_extra),
+ because that can have an affect on whether it's suppressed. Ignore
+ the size return value of VG_(tdict).tool_update_extra, because we're
+ not copying 'extra'. */
+ (void)VG_TDICT_CALL(tool_update_extra, &err);
+
+ su = is_suppressible_error(&err);
+ if (NULL == su) {
+ if (count_error) {
+ n_errs_found++;
+ n_err_contexts++;
+ }
+
+ if (print_error) {
+ /* Actually show the error; more complex than you might think. */
+ pp_Error(&err, allow_db_attach, VG_(clo_xml));
+ /* update stats */
+ n_errs_shown++;
+ }
+ return False;
+
+ } else {
+ if (count_error) {
+ n_errs_suppressed++;
+ n_supp_contexts++;
+ }
+ su->count++;
+ return True;
+ }
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Exported fns ---*/
+/*------------------------------------------------------------*/
+
+/* Show the used suppressions. Returns False if no suppression
+ got used. */
+static Bool show_used_suppressions ( void )
+{
+ Supp *su;
+ Bool any_supp;
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("<suppcounts>\n");
+
+ any_supp = False;
+ for (su = suppressions; su != NULL; su = su->next) {
+ if (su->count <= 0)
+ continue;
+ if (VG_(clo_xml)) {
+ VG_(printf_xml)( " <pair>\n"
+ " <count>%d</count>\n"
+ " <name>%pS</name>\n"
+ " </pair>\n",
+ su->count, su->sname );
+ } else {
+ // blank line before the first shown suppression, if any
+ if (!any_supp)
+ VG_(dmsg)("\n");
+ VG_(dmsg)("used_suppression: %6d %s\n", su->count, su->sname);
+ }
+ any_supp = True;
+ }
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("</suppcounts>\n");
+
+ return any_supp;
+}
+
+/* Show all the errors that occurred, and possibly also the
+ suppressions used. */
+void VG_(show_all_errors) ( Int verbosity, Bool xml )
+{
+ Int i, n_min;
+ Error *p, *p_min;
+ Bool any_supp;
+
+ if (verbosity == 0)
+ return;
+
+ /* If we're printing XML, just show the suppressions and stop. */
+ if (xml) {
+ (void)show_used_suppressions();
+ return;
+ }
+
+ /* We only get here if not printing XML. */
+ VG_(umsg)("ERROR SUMMARY: "
+ "%d errors from %d contexts (suppressed: %d from %d)\n",
+ n_errs_found, n_err_contexts,
+ n_errs_suppressed, n_supp_contexts );
+
+ if (verbosity <= 1)
+ return;
+
+ // We do the following only at -v or above, and only in non-XML
+ // mode
+
+ /* Print the contexts in order of increasing error count.
+ Once an error is shown, we add a huge value to its count to filter it
+ out. After having shown all errors, we reset count to the original
value. */
+ for (i = 0; i < n_err_contexts; i++) {
+ n_min = (1 << 30) - 1;
+ p_min = NULL;
+ for (p = errors; p != NULL; p = p->next) {
+ if (p->supp != NULL) continue;
+ if (p->count < n_min) {
+ n_min = p->count;
+ p_min = p;
+ }
+ }
+ // XXX: this isn't right. See bug 203651.
+ if (p_min == NULL) continue; //VG_(tool_panic)("show_all_errors()");
+
+ VG_(umsg)("\n");
+ VG_(umsg)("%d errors in context %d of %d:\n",
+ p_min->count, i+1, n_err_contexts);
+ pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );
+
+ // We're not printing XML -- we'd have exited above if so.
+ vg_assert(! xml);
+
+ if ((i+1 == VG_(clo_dump_error))) {
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/64bit-avx-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.i386.avx.valgrind.s1">
+ <reg name="ymm0hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm1hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm2hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm3hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm4hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm5hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm6hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm7hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm8hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm9hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm10hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm11hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm12hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm13hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm14hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm15hs1" bitsize="128" type="uint128"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/64bit-avx-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.i386.avx.valgrind.s2">
+ <reg name="ymm0hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm1hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm2hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm3hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm4hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm5hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm6hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm7hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm8hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm9hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm10hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm11hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm12hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm13hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm14hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm15hs2" bitsize="128" type="uint128"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/64bit-avx.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.i386.avx">
+ <reg name="ymm0h" bitsize="128" type="uint128"/>
+ <reg name="ymm1h" bitsize="128" type="uint128"/>
+ <reg name="ymm2h" bitsize="128" type="uint128"/>
+ <reg name="ymm3h" bitsize="128" type="uint128"/>
+ <reg name="ymm4h" bitsize="128" type="uint128"/>
+ <reg name="ymm5h" bitsize="128" type="uint128"/>
+ <reg name="ymm6h" bitsize="128" type="uint128"/>
+ <reg name="ymm7h" bitsize="128" type="uint128"/>
+ <reg name="ymm8h" bitsize="128" type="uint128"/>
+ <reg name="ymm9h" bitsize="128" type="uint128"/>
+ <reg name="ymm10h" bitsize="128" type="uint128"/>
+ <reg name="ymm11h" bitsize="128" type="uint128"/>
+ <reg name="ymm12h" bitsize="128" type="uint128"/>
+ <reg name="ymm13h" bitsize="128" type="uint128"/>
+ <reg name="ymm14h" bitsize="128" type="uint128"/>
+ <reg name="ymm15h" bitsize="128" type="uint128"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/amd64-avx-coresse-valgrind.xml
Thu Nov 22 04:55:39 2012
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- AMD64 - core and sse. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+ <xi:include href="64bit-core-valgrind-s1.xml"/>
+ <xi:include href="64bit-sse-valgrind-s1.xml"/>
+ <xi:include href="64bit-avx-valgrind-s1.xml"/>
+ <xi:include href="64bit-core-valgrind-s2.xml"/>
+ <xi:include href="64bit-sse-valgrind-s2.xml"/>
+ <xi:include href="64bit-avx-valgrind-s2.xml"/>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/amd64-avx-coresse.xml Thu Nov 22
04:55:39 2012
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- AMD64 - core and sse and avx. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/amd64-avx-linux-valgrind.xml Thu
Nov 22 04:55:39 2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- AMD64 with avx - Includes Linux-only special "register". -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-linux.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+ <xi:include href="64bit-core-valgrind-s1.xml"/>
+ <xi:include href="64bit-sse-valgrind-s1.xml"/>
+ <xi:include href="64bit-linux-valgrind-s1.xml"/>
+ <xi:include href="64bit-avx-valgrind-s1.xml"/>
+ <xi:include href="64bit-core-valgrind-s2.xml"/>
+ <xi:include href="64bit-sse-valgrind-s2.xml"/>
+ <xi:include href="64bit-linux-valgrind-s2.xml"/>
+ <xi:include href="64bit-avx-valgrind-s2.xml"/>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/amd64-avx-linux.xml Thu Nov 22
04:55:39 2012
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- AMD64 with avx - Includes Linux-only special "register". -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-linux.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cp0-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0.valgrind.s1">
+ <reg name="statuss1" bitsize="32" regnum="32"/>
+ <reg name="badvaddrs1" bitsize="32" regnum="35"/>
+ <reg name="causes1" bitsize="32" regnum="36"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cp0-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0.valgrind.s2">
+ <reg name="statuss2" bitsize="32" regnum="32"/>
+ <reg name="badvaddrs2" bitsize="32" regnum="35"/>
+ <reg name="causes2" bitsize="32" regnum="36"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cp0.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0">
+ <reg name="status" bitsize="32" regnum="32"/>
+ <reg name="badvaddr" bitsize="32" regnum="35"/>
+ <reg name="cause" bitsize="32" regnum="36"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cpu-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu.valgrind.s1">
+ <reg name="r0s1" bitsize="32" regnum="0"/>
+ <reg name="r1s1" bitsize="32"/>
+ <reg name="r2s1" bitsize="32"/>
+ <reg name="r3s1" bitsize="32"/>
+ <reg name="r4s1" bitsize="32"/>
+ <reg name="r5s1" bitsize="32"/>
+ <reg name="r6s1" bitsize="32"/>
+ <reg name="r7s1" bitsize="32"/>
+ <reg name="r8s1" bitsize="32"/>
+ <reg name="r9s1" bitsize="32"/>
+ <reg name="r10s1" bitsize="32"/>
+ <reg name="r11s1" bitsize="32"/>
+ <reg name="r12s1" bitsize="32"/>
+ <reg name="r13s1" bitsize="32"/>
+ <reg name="r14s1" bitsize="32"/>
+ <reg name="r15s1" bitsize="32"/>
+ <reg name="r16s1" bitsize="32"/>
+ <reg name="r17s1" bitsize="32"/>
+ <reg name="r18s1" bitsize="32"/>
+ <reg name="r19s1" bitsize="32"/>
+ <reg name="r20s1" bitsize="32"/>
+ <reg name="r21s1" bitsize="32"/>
+ <reg name="r22s1" bitsize="32"/>
+ <reg name="r23s1" bitsize="32"/>
+ <reg name="r24s1" bitsize="32"/>
+ <reg name="r25s1" bitsize="32"/>
+ <reg name="r26s1" bitsize="32"/>
+ <reg name="r27s1" bitsize="32"/>
+ <reg name="r28s1" bitsize="32"/>
+ <reg name="r29s1" bitsize="32"/>
+ <reg name="r30s1" bitsize="32"/>
+ <reg name="r31s1" bitsize="32"/>
+
+ <reg name="los1" bitsize="32" regnum="33"/>
+ <reg name="his1" bitsize="32" regnum="34"/>
+ <reg name="pcs1" bitsize="32" regnum="37"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cpu-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu.valgrind.s2">
+ <reg name="r0s2" bitsize="32" regnum="0"/>
+ <reg name="r1s2" bitsize="32"/>
+ <reg name="r2s2" bitsize="32"/>
+ <reg name="r3s2" bitsize="32"/>
+ <reg name="r4s2" bitsize="32"/>
+ <reg name="r5s2" bitsize="32"/>
+ <reg name="r6s2" bitsize="32"/>
+ <reg name="r7s2" bitsize="32"/>
+ <reg name="r8s2" bitsize="32"/>
+ <reg name="r9s2" bitsize="32"/>
+ <reg name="r10s2" bitsize="32"/>
+ <reg name="r11s2" bitsize="32"/>
+ <reg name="r12s2" bitsize="32"/>
+ <reg name="r13s2" bitsize="32"/>
+ <reg name="r14s2" bitsize="32"/>
+ <reg name="r15s2" bitsize="32"/>
+ <reg name="r16s2" bitsize="32"/>
+ <reg name="r17s2" bitsize="32"/>
+ <reg name="r18s2" bitsize="32"/>
+ <reg name="r19s2" bitsize="32"/>
+ <reg name="r20s2" bitsize="32"/>
+ <reg name="r21s2" bitsize="32"/>
+ <reg name="r22s2" bitsize="32"/>
+ <reg name="r23s2" bitsize="32"/>
+ <reg name="r24s2" bitsize="32"/>
+ <reg name="r25s2" bitsize="32"/>
+ <reg name="r26s2" bitsize="32"/>
+ <reg name="r27s2" bitsize="32"/>
+ <reg name="r28s2" bitsize="32"/>
+ <reg name="r29s2" bitsize="32"/>
+ <reg name="r30s2" bitsize="32"/>
+ <reg name="r31s2" bitsize="32"/>
+
+ <reg name="los2" bitsize="32" regnum="33"/>
+ <reg name="his2" bitsize="32" regnum="34"/>
+ <reg name="pcs2" bitsize="32" regnum="37"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-cpu.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu">
+ <reg name="r0" bitsize="32" regnum="0"/>
+ <reg name="r1" bitsize="32"/>
+ <reg name="r2" bitsize="32"/>
+ <reg name="r3" bitsize="32"/>
+ <reg name="r4" bitsize="32"/>
+ <reg name="r5" bitsize="32"/>
+ <reg name="r6" bitsize="32"/>
+ <reg name="r7" bitsize="32"/>
+ <reg name="r8" bitsize="32"/>
+ <reg name="r9" bitsize="32"/>
+ <reg name="r10" bitsize="32"/>
+ <reg name="r11" bitsize="32"/>
+ <reg name="r12" bitsize="32"/>
+ <reg name="r13" bitsize="32"/>
+ <reg name="r14" bitsize="32"/>
+ <reg name="r15" bitsize="32"/>
+ <reg name="r16" bitsize="32"/>
+ <reg name="r17" bitsize="32"/>
+ <reg name="r18" bitsize="32"/>
+ <reg name="r19" bitsize="32"/>
+ <reg name="r20" bitsize="32"/>
+ <reg name="r21" bitsize="32"/>
+ <reg name="r22" bitsize="32"/>
+ <reg name="r23" bitsize="32"/>
+ <reg name="r24" bitsize="32"/>
+ <reg name="r25" bitsize="32"/>
+ <reg name="r26" bitsize="32"/>
+ <reg name="r27" bitsize="32"/>
+ <reg name="r28" bitsize="32"/>
+ <reg name="r29" bitsize="32"/>
+ <reg name="r30" bitsize="32"/>
+ <reg name="r31" bitsize="32"/>
+
+ <reg name="lo" bitsize="32" regnum="33"/>
+ <reg name="hi" bitsize="32" regnum="34"/>
+ <reg name="pc" bitsize="32" regnum="37"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-fpu-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu.valgrind.s1">
+ <reg name="f0s1" bitsize="32" type="ieee_single" regnum="38"/>
+ <reg name="f1s1" bitsize="32" type="ieee_single"/>
+ <reg name="f2s1" bitsize="32" type="ieee_single"/>
+ <reg name="f3s1" bitsize="32" type="ieee_single"/>
+ <reg name="f4s1" bitsize="32" type="ieee_single"/>
+ <reg name="f5s1" bitsize="32" type="ieee_single"/>
+ <reg name="f6s1" bitsize="32" type="ieee_single"/>
+ <reg name="f7s1" bitsize="32" type="ieee_single"/>
+ <reg name="f8s1" bitsize="32" type="ieee_single"/>
+ <reg name="f9s1" bitsize="32" type="ieee_single"/>
+ <reg name="f10s1" bitsize="32" type="ieee_single"/>
+ <reg name="f11s1" bitsize="32" type="ieee_single"/>
+ <reg name="f12s1" bitsize="32" type="ieee_single"/>
+ <reg name="f13s1" bitsize="32" type="ieee_single"/>
+ <reg name="f14s1" bitsize="32" type="ieee_single"/>
+ <reg name="f15s1" bitsize="32" type="ieee_single"/>
+ <reg name="f16s1" bitsize="32" type="ieee_single"/>
+ <reg name="f17s1" bitsize="32" type="ieee_single"/>
+ <reg name="f18s1" bitsize="32" type="ieee_single"/>
+ <reg name="f19s1" bitsize="32" type="ieee_single"/>
+ <reg name="f20s1" bitsize="32" type="ieee_single"/>
+ <reg name="f21s1" bitsize="32" type="ieee_single"/>
+ <reg name="f22s1" bitsize="32" type="ieee_single"/>
+ <reg name="f23s1" bitsize="32" type="ieee_single"/>
+ <reg name="f24s1" bitsize="32" type="ieee_single"/>
+ <reg name="f25s1" bitsize="32" type="ieee_single"/>
+ <reg name="f26s1" bitsize="32" type="ieee_single"/>
+ <reg name="f27s1" bitsize="32" type="ieee_single"/>
+ <reg name="f28s1" bitsize="32" type="ieee_single"/>
+ <reg name="f29s1" bitsize="32" type="ieee_single"/>
+ <reg name="f30s1" bitsize="32" type="ieee_single"/>
+ <reg name="f31s1" bitsize="32" type="ieee_single"/>
+
+ <reg name="fcsrs1" bitsize="32" group="float"/>
+ <reg name="firs1" bitsize="32" group="float"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-fpu-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu.valgrind.s2">
+ <reg name="f0s2" bitsize="32" type="ieee_single" regnum="38"/>
+ <reg name="f1s2" bitsize="32" type="ieee_single"/>
+ <reg name="f2s2" bitsize="32" type="ieee_single"/>
+ <reg name="f3s2" bitsize="32" type="ieee_single"/>
+ <reg name="f4s2" bitsize="32" type="ieee_single"/>
+ <reg name="f5s2" bitsize="32" type="ieee_single"/>
+ <reg name="f6s2" bitsize="32" type="ieee_single"/>
+ <reg name="f7s2" bitsize="32" type="ieee_single"/>
+ <reg name="f8s2" bitsize="32" type="ieee_single"/>
+ <reg name="f9s2" bitsize="32" type="ieee_single"/>
+ <reg name="f10s2" bitsize="32" type="ieee_single"/>
+ <reg name="f11s2" bitsize="32" type="ieee_single"/>
+ <reg name="f12s2" bitsize="32" type="ieee_single"/>
+ <reg name="f13s2" bitsize="32" type="ieee_single"/>
+ <reg name="f14s2" bitsize="32" type="ieee_single"/>
+ <reg name="f15s2" bitsize="32" type="ieee_single"/>
+ <reg name="f16s2" bitsize="32" type="ieee_single"/>
+ <reg name="f17s2" bitsize="32" type="ieee_single"/>
+ <reg name="f18s2" bitsize="32" type="ieee_single"/>
+ <reg name="f19s2" bitsize="32" type="ieee_single"/>
+ <reg name="f20s2" bitsize="32" type="ieee_single"/>
+ <reg name="f21s2" bitsize="32" type="ieee_single"/>
+ <reg name="f22s2" bitsize="32" type="ieee_single"/>
+ <reg name="f23s2" bitsize="32" type="ieee_single"/>
+ <reg name="f24s2" bitsize="32" type="ieee_single"/>
+ <reg name="f25s2" bitsize="32" type="ieee_single"/>
+ <reg name="f26s2" bitsize="32" type="ieee_single"/>
+ <reg name="f27s2" bitsize="32" type="ieee_single"/>
+ <reg name="f28s2" bitsize="32" type="ieee_single"/>
+ <reg name="f29s2" bitsize="32" type="ieee_single"/>
+ <reg name="f30s2" bitsize="32" type="ieee_single"/>
+ <reg name="f31s2" bitsize="32" type="ieee_single"/>
+
+ <reg name="fcsrs2" bitsize="32" group="float"/>
+ <reg name="firs2" bitsize="32" group="float"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-fpu.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu">
+ <reg name="f0" bitsize="32" type="ieee_single" regnum="38"/>
+ <reg name="f1" bitsize="32" type="ieee_single"/>
+ <reg name="f2" bitsize="32" type="ieee_single"/>
+ <reg name="f3" bitsize="32" type="ieee_single"/>
+ <reg name="f4" bitsize="32" type="ieee_single"/>
+ <reg name="f5" bitsize="32" type="ieee_single"/>
+ <reg name="f6" bitsize="32" type="ieee_single"/>
+ <reg name="f7" bitsize="32" type="ieee_single"/>
+ <reg name="f8" bitsize="32" type="ieee_single"/>
+ <reg name="f9" bitsize="32" type="ieee_single"/>
+ <reg name="f10" bitsize="32" type="ieee_single"/>
+ <reg name="f11" bitsize="32" type="ieee_single"/>
+ <reg name="f12" bitsize="32" type="ieee_single"/>
+ <reg name="f13" bitsize="32" type="ieee_single"/>
+ <reg name="f14" bitsize="32" type="ieee_single"/>
+ <reg name="f15" bitsize="32" type="ieee_single"/>
+ <reg name="f16" bitsize="32" type="ieee_single"/>
+ <reg name="f17" bitsize="32" type="ieee_single"/>
+ <reg name="f18" bitsize="32" type="ieee_single"/>
+ <reg name="f19" bitsize="32" type="ieee_single"/>
+ <reg name="f20" bitsize="32" type="ieee_single"/>
+ <reg name="f21" bitsize="32" type="ieee_single"/>
+ <reg name="f22" bitsize="32" type="ieee_single"/>
+ <reg name="f23" bitsize="32" type="ieee_single"/>
+ <reg name="f24" bitsize="32" type="ieee_single"/>
+ <reg name="f25" bitsize="32" type="ieee_single"/>
+ <reg name="f26" bitsize="32" type="ieee_single"/>
+ <reg name="f27" bitsize="32" type="ieee_single"/>
+ <reg name="f28" bitsize="32" type="ieee_single"/>
+ <reg name="f29" bitsize="32" type="ieee_single"/>
+ <reg name="f30" bitsize="32" type="ieee_single"/>
+ <reg name="f31" bitsize="32" type="ieee_single"/>
+
+ <reg name="fcsr" bitsize="32" group="float"/>
+ <reg name="fir" bitsize="32" group="float"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-linux-valgrind.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>mips</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="mips-cpu.xml"/>
+ <xi:include href="mips-cp0.xml"/>
+ <xi:include href="mips-fpu.xml"/>
+ <xi:include href="mips-cpu-valgrind-s1.xml"/>
+ <xi:include href="mips-cp0-valgrind-s1.xml"/>
+ <xi:include href="mips-fpu-valgrind-s1.xml"/>
+ <xi:include href="mips-cpu-valgrind-s2.xml"/>
+ <xi:include href="mips-cp0-valgrind-s2.xml"/>
+ <xi:include href="mips-fpu-valgrind-s2.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="32" group="system"/>
+ </feature>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/mips-linux.xml Thu Nov 22
04:55:39 2012
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>mips</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="mips-cpu.xml"/>
+ <xi:include href="mips-cp0.xml"/>
+ <xi:include href="mips-fpu.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="32" group="system"/>
+ </feature>
+</target>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/power-core-valgrind-s1.xml Thu
Nov 22 04:55:39 2012
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.core-valgrind-s1">
+ <reg name="r0s1" bitsize="32" type="uint32"/>
+ <reg name="r1s1" bitsize="32" type="uint32"/>
+ <reg name="r2s1" bitsize="32" type="uint32"/>
+ <reg name="r3s1" bitsize="32" type="uint32"/>
+ <reg name="r4s1" bitsize="32" type="uint32"/>
+ <reg name="r5s1" bitsize="32" type="uint32"/>
+ <reg name="r6s1" bitsize="32" type="uint32"/>
+ <reg name="r7s1" bitsize="32" type="uint32"/>
+ <reg name="r8s1" bitsize="32" type="uint32"/>
+ <reg name="r9s1" bitsize="32" type="uint32"/>
+ <reg name="r10s1" bitsize="32" type="uint32"/>
+ <reg name="r11s1" bitsize="32" type="uint32"/>
+ <reg name="r12s1" bitsize="32" type="uint32"/>
+ <reg name="r13s1" bitsize="32" type="uint32"/>
+ <reg name="r14s1" bitsize="32" type="uint32"/>
+ <reg name="r15s1" bitsize="32" type="uint32"/>
+ <reg name="r16s1" bitsize="32" type="uint32"/>
+ <reg name="r17s1" bitsize="32" type="uint32"/>
+ <reg name="r18s1" bitsize="32" type="uint32"/>
+ <reg name="r19s1" bitsize="32" type="uint32"/>
+ <reg name="r20s1" bitsize="32" type="uint32"/>
+ <reg name="r21s1" bitsize="32" type="uint32"/>
+ <reg name="r22s1" bitsize="32" type="uint32"/>
+ <reg name="r23s1" bitsize="32" type="uint32"/>
+ <reg name="r24s1" bitsize="32" type="uint32"/>
+ <reg name="r25s1" bitsize="32" type="uint32"/>
+ <reg name="r26s1" bitsize="32" type="uint32"/>
+ <reg name="r27s1" bitsize="32" type="uint32"/>
+ <reg name="r28s1" bitsize="32" type="uint32"/>
+ <reg name="r29s1" bitsize="32" type="uint32"/>
+ <reg name="r30s1" bitsize="32" type="uint32"/>
+ <reg name="r31s1" bitsize="32" type="uint32"/>
+
+ <reg name="pcs1" bitsize="32" type="code_ptr" regnum="64"/>
+ <reg name="msrs1" bitsize="32" type="uint32"/>
+ <reg name="crs1" bitsize="32" type="uint32"/>
+ <reg name="lrs1" bitsize="32" type="code_ptr"/>
+ <reg name="ctrs1" bitsize="32" type="uint32"/>
+ <reg name="xers1" bitsize="32" type="uint32"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/power-core-valgrind-s2.xml Thu
Nov 22 04:55:39 2012
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.core-valgrind-s2">
+ <reg name="r0s2" bitsize="32" type="uint32"/>
+ <reg name="r1s2" bitsize="32" type="uint32"/>
+ <reg name="r2s2" bitsize="32" type="uint32"/>
+ <reg name="r3s2" bitsize="32" type="uint32"/>
+ <reg name="r4s2" bitsize="32" type="uint32"/>
+ <reg name="r5s2" bitsize="32" type="uint32"/>
+ <reg name="r6s2" bitsize="32" type="uint32"/>
+ <reg name="r7s2" bitsize="32" type="uint32"/>
+ <reg name="r8s2" bitsize="32" type="uint32"/>
+ <reg name="r9s2" bitsize="32" type="uint32"/>
+ <reg name="r10s2" bitsize="32" type="uint32"/>
+ <reg name="r11s2" bitsize="32" type="uint32"/>
+ <reg name="r12s2" bitsize="32" type="uint32"/>
+ <reg name="r13s2" bitsize="32" type="uint32"/>
+ <reg name="r14s2" bitsize="32" type="uint32"/>
+ <reg name="r15s2" bitsize="32" type="uint32"/>
+ <reg name="r16s2" bitsize="32" type="uint32"/>
+ <reg name="r17s2" bitsize="32" type="uint32"/>
+ <reg name="r18s2" bitsize="32" type="uint32"/>
+ <reg name="r19s2" bitsize="32" type="uint32"/>
+ <reg name="r20s2" bitsize="32" type="uint32"/>
+ <reg name="r21s2" bitsize="32" type="uint32"/>
+ <reg name="r22s2" bitsize="32" type="uint32"/>
+ <reg name="r23s2" bitsize="32" type="uint32"/>
+ <reg name="r24s2" bitsize="32" type="uint32"/>
+ <reg name="r25s2" bitsize="32" type="uint32"/>
+ <reg name="r26s2" bitsize="32" type="uint32"/>
+ <reg name="r27s2" bitsize="32" type="uint32"/>
+ <reg name="r28s2" bitsize="32" type="uint32"/>
+ <reg name="r29s2" bitsize="32" type="uint32"/>
+ <reg name="r30s2" bitsize="32" type="uint32"/>
+ <reg name="r31s2" bitsize="32" type="uint32"/>
+
+ <reg name="pcs2" bitsize="32" type="code_ptr" regnum="64"/>
+ <reg name="msrs2" bitsize="32" type="uint32"/>
+ <reg name="crs2" bitsize="32" type="uint32"/>
+ <reg name="lrs2" bitsize="32" type="code_ptr"/>
+ <reg name="ctrs2" bitsize="32" type="uint32"/>
+ <reg name="xers2" bitsize="32" type="uint32"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-acr-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.acr-valgrind-s1">
+ <reg name="acr0s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr1s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr2s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr3s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr4s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr5s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr6s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr7s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr8s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr9s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr10s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr11s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr12s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr13s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr14s1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr15s1" bitsize="32" type="uint32" group="access"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-acr-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.acr-valgrind-s2">
+ <reg name="acr0s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr1s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr2s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr3s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr4s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr5s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr6s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr7s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr8s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr9s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr10s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr11s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr12s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr13s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr14s2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr15s2" bitsize="32" type="uint32" group="access"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-acr.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.acr">
+ <reg name="acr0" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr1" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr2" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr3" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr4" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr5" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr6" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr7" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr8" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr9" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr10" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr11" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr12" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr13" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr14" bitsize="32" type="uint32" group="access"/>
+ <reg name="acr15" bitsize="32" type="uint32" group="access"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-fpr-valgrind-s1.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.fpr-valgrind-s1">
+ <reg name="fpcs1" bitsize="32" type="uint32" group="float"/>
+ <reg name="f0s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f1s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f2s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f3s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f4s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f5s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f6s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f7s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f8s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f9s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f10s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f11s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f12s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f13s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f14s1" bitsize="64" type="uint64" group="float"/>
+ <reg name="f15s1" bitsize="64" type="uint64" group="float"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-fpr-valgrind-s2.xml Thu Nov
22 04:55:39 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.fpr-valgrind-s2">
+ <reg name="fpcs2" bitsize="32" type="uint32" group="float"/>
+ <reg name="f0s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f1s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f2s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f3s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f4s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f5s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f6s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f7s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f8s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f9s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f10s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f11s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f12s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f13s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f14s2" bitsize="64" type="uint64" group="float"/>
+ <reg name="f15s2" bitsize="64" type="uint64" group="float"/>
+</feature>
=======================================
--- /dev/null
+++ /trunk/valgrind/coregrind/m_gdbserver/s390-fpr.xml Thu Nov 22 04:55:39
2012
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.s390.fpr">
+ <reg name="fpc" bitsize="32" type="uint32" group="float"/>
+ <reg name="f0" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f1" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f2" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f3" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f4" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f5" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f6" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f7" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f8" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f9" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f10" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f11" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f12" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f13" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f14" bitsize="64" type="ieee_double" group="float"/>
+ <reg name="f15" bitsize="64" type="ieee_double" group="float"/>
+</feature>
=======================================
***Additional files exist in this changeset.***
Reply all
Reply to author
Forward
0 new messages