--- cell-gdb-6.6.50cvs20070623.orig/debian/rules +++ cell-gdb-6.6.50cvs20070623/debian/rules @@ -0,0 +1,285 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +export SHELL = /bin/bash + +with_check := yes +ifneq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS))) + with_check := disabled through DEB_BUILD_OPTIONS +endif +with_check := disabled + +NJOBS = -j $(shell getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1) +# Support parallel= in DEB_BUILD_OPTIONS (see #209008) +ifneq (,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) + COMMA = , + NJOBS := -j $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) +endif + +d_ppu = debian/ppu-gdb +d_spu = debian/spu-gdb + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +CC = gcc + +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) + +ifeq (,$(filter $(DEB_BUILD_ARCH), powerpc ppc64)) + sysroot = usr/lib/cell/sysroot + prefix = usr/lib/cell/toolchain +else + prefix = usr + CC = gcc -m64 + on_powerpc = yes +endif +mandir=$(prefix)/share/man +infodir=$(prefix)/share/info + +PPU_PREFIX = ppu- +PPU32_PREFIX = ppu32- +PPU_TARGET = ppu + +SET_PPU_FLAGS = \ + CC=$(if $(on_powerpc),ppu-gcc,gcc) \ + CFLAGS="$(value $(CFLAGS)) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" + +PPU_CONFARGS = \ + --prefix=/$(prefix) \ + --mandir=/$(mandir) \ + --infodir=/$(infodir) +ifneq (,$(sysroot)) + PPU_CONFARGS += --with-sysroot=/$(sysroot) +endif +PPU_CONFARGS += \ + --disable-nls \ + --disable-sim \ + --disable-install-libbfd \ + --program-prefix=$(PPU_PREFIX) \ + $(if $(on_powerpc), --without-libexpat-prefix) \ + $(if $(sysroot), --with-sysroot=/$(sysroot)) \ + $(if $(on_powerpc), --host=powerpc64-linux-gnu) \ + --target=powerpc64-linux-gnu \ + --enable-targets=spu + +# Do a second build of gdbserver only, using --target=powerpc-linux. +# This is so we get a gdbserver suited for 32-bit programs. +ifneq (,$(on_powerpc)) + PPU32_CONFARGS = \ + --prefix=/$(prefix) \ + --mandir=/$(mandir) \ + --infodir=/$(infodir) \ + $(if $(sysroot), --with-sysroot=/$(sysroot)) \ + --program-prefix=$(PPU32_PREFIX) \ + --disable-nls \ + --host=powerpc-linux-gnu \ + --target=powerpc-linux-gnu \ + --enable-targets=spu +endif + +SET_SPU_FLAGS = \ + CFLAGS="$(value $(CFLAGS)) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" + +SPU_PREFIX = spu- +SPU_TARGET = spu + +SPU_CONFARGS = \ + --prefix=/$(prefix) \ + --mandir=/$(mandir) \ + --infodir=/$(infodir) \ + $(if $(sysroot), --with-sysroot=/$(sysroot)) \ + --disable-shared \ + --disable-nls \ + --program-prefix=$(SPU_PREFIX) \ + --target=$(SPU_TARGET) + +unpack: ppu-unpack-stamp spu-unpack-stamp +ppu-unpack-stamp: + rm -rf ppu + mkdir ppu + cd ppu && tar xf ../gdb*.tar.bz2 + touch ppu-unpack-stamp + +spu-unpack-stamp: + rm -rf spu + mkdir spu + cd spu && tar xf ../gdb*.tar.bz2 + touch spu-unpack-stamp + +patch: ppu-patch-stamp spu-patch-stamp +ppu-patch-stamp: ppu-unpack-stamp + cd ppu && \ + QUILT_PATCHES=$(CURDIR)/debian/patches/ppu quilt push -a || test $$? = 2 + touch ppu-patch-stamp + +spu-patch-stamp: spu-unpack-stamp + cd spu && \ + QUILT_PATCHES=$(CURDIR)/debian/patches/spu quilt push -a || test $$? = 2 + touch spu-patch-stamp + + +unpatch: + QUILT_PATCHES=debian/patches quilt pop -a + rm -f patch-stamp + +configure: ppu-configure-stamp spu-configure-stamp +ppu-configure-stamp: ppu-patch-stamp + dh_testdir + rm -rf ppu/build + mkdir -p ppu/build +ifneq (,$(on_powerpc)) + mkdir -p ppu/bin + for i in ar as ld ranlib; do \ + ln -s /usr/bin/ppu-$$i ppu/bin/powerpc64-linux-gnu-$$i; \ + done +endif + cd ppu/build && \ + $(SET_PPU_FLAGS) \ + PATH=$(CURDIR)/ppu/bin:$$PATH \ + ../src/configure $(PPU_CONFARGS) + touch ppu-configure-stamp + +ppu32-configure-stamp: ppu-patch-stamp + dh_testdir + rm -rf ppu/build32 + mkdir -p ppu/build32 + cd ppu/build32 && \ + $(SET_PPU_FLAGS) ../src/configure $(PPU32_CONFARGS) + touch ppu32-configure-stamp + +spu-configure-stamp: spu-patch-stamp + dh_testdir + rm -rf spu/build + mkdir -p spu/build + cd spu/build && \ + $(SET_SPU_FLAGS) ../src/configure $(SPU_CONFARGS) + touch spu-configure-stamp + +build: ppu-build spu-build $(if $(on_powerpc),ppu32-build) + +ppu-build: ppu-build-stamp +ppu-build-stamp: ppu-configure-stamp + PATH=$(CURDIR)/ppu/bin:$$PATH \ + $(MAKE) -C ppu/build $(NJOBS) + touch $@ + +ppu32-build: ppu32-build-stamp +ppu32-build-stamp: ppu32-configure-stamp + $(MAKE) -C ppu/build32 configure-gdb + $(MAKE) -C ppu/build32/gdb/gdbserver $(NJOBS) + + touch $@ + +spu-build: spu-build-stamp +spu-build-stamp: spu-configure-stamp + $(MAKE) -C spu/build $(NJOBS) + touch $@ + +clean: + dh_testdir + dh_testroot + rm -rf ppu spu .pc + rm -f debian/*.links + rm -f *-stamp + dh_clean + +install: pre-install ppu-install $(if $(on_powerpc),ppu32-install) spu-install + +pre-install: + dh_testdir + dh_testroot + dh_clean -k + +ppu-install: + dh_testdir + dh_testroot + dh_installdirs -pppu-gdb + + PATH=$(CURDIR)/ppu/bin:$$PATH \ + $(MAKE) -C ppu/build DESTDIR=$(CURDIR)/$(d_ppu) install + rm -rf $(d_ppu)/$(prefix)/include + rm -rf $(d_ppu)/$(infodir) + rm -rf $(d_ppu)/$(prefix)/lib* + +ifneq ($(prefix),usr) + mkdir -p $(d_ppu)/usr/bin $(d_ppu)/usr/share/man/man1 + cd $(d_ppu); \ + for i in $(prefix)/bin/$(PPU_PREFIX)* $(mandir)/man1/$(PPU_PREFIX)*; do \ + echo /$$i /usr$${i#$(prefix)*}; \ + done > $(CURDIR)/debian/ppu-gdb.links +endif + -find debian/ppu-gdb -type d -empty -delete + find $(d_ppu) ! -type d + +ppu32-install: + dh_testdir + dh_testroot + dh_installdirs -pppu-gdb + + $(MAKE) -C ppu/build32/gdb/gdbserver DESTDIR=$(CURDIR)/$(d_ppu) install + rm -rf $(d_ppu)/$(prefix)/include + rm -rf $(d_ppu)/$(infodir) + rm -rf $(d_ppu)/$(prefix)/lib* + for i in $(d_ppu)/$(mandir)/man1/$(PPU32_PREFIX)*; do \ + case "$$i" in *$(PPU32_PREFIX)gdbserver*) continue; esac; \ + rm -f $$i; \ + done + -find debian/ppu-gdb -type d -empty -delete + find $(d_ppu) ! -type d + +spu-install: + dh_testdir + dh_testroot + dh_installdirs -pspu-gdb + + $(MAKE) -C spu/build DESTDIR=$(CURDIR)/$(d_spu) install + + rm -rf $(d_spu)/$(prefix)/include + rm -rf $(d_spu)/$(infodir) + rm -rf $(d_spu)/$(prefix)/lib* + +ifneq ($(prefix),usr) + mkdir -p $(d_spu)/usr/bin $(d_spu)/usr/share/man/man1 + cd $(d_spu); \ + for i in $(prefix)/bin/$(SPU_PREFIX)* $(mandir)/man1/$(SPU_PREFIX)*; do \ + echo /$$i /usr$${i#$(prefix)*}; \ + done > $(CURDIR)/debian/spu-gdb.links +endif + -find debian/spu-gdb -type d -empty -delete + find $(d_spu) ! -type d + +binary-indep: build install +# nothing to do + +# Build architecture dependant packages using the common target. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs -s + dh_installdocs -s +# dh_installinfo +# dh_installman + dh_link -s + dh_strip -s + dh_compress -s + dh_fixperms -s + dh_makeshlibs -s + dh_installdeb -s + dh_shlibdeps -s + dh_gencontrol -s + dh_md5sums -s + dh_builddeb -s + +binary: binary-arch binary-indep +.PHONY: build clean binary-indep binary-arch binary install configure --- cell-gdb-6.6.50cvs20070623.orig/debian/changelog +++ cell-gdb-6.6.50cvs20070623/debian/changelog @@ -0,0 +1,40 @@ +cell-gdb (6.6.50cvs20070623-1ubuntu3) gutsy; urgency=low + + * debian/rules(clean): Remove the generated debian/*.links files, + brings back the missing binaries on powerpc. + + -- Matthias Klose Thu, 27 Sep 2007 16:10:06 +0200 + +cell-gdb (6.6.50cvs20070623-1ubuntu2) gutsy; urgency=low + + * Do not install man pages without a prefix. + * Configure spu build with --disable-nls. + + -- Matthias Klose Thu, 27 Sep 2007 09:03:48 +0000 + +cell-gdb (6.6.50cvs20070623-1ubuntu1) gutsy; urgency=low + + * Fix build dependencies for powerpc. + + -- Matthias Klose Mon, 24 Sep 2007 09:56:11 +0000 + +cell-gdb (6.6.50cvs20070623-1) gutsy; urgency=low + + * Update to SDK 3.0 earlyRel. + * Change cross-prefix to /usr/lib/cell/toolchain. Do not change sysroot. + * debian/rules: Support parallel= in DEB_BUILD_OPTIONS. + + -- Matthias Klose Wed, 19 Sep 2007 11:14:05 +0200 + +cell-gdb (6.6-1ubuntu1) gutsy; urgency=low + + * Upload to gutsy. + + -- Matthias Klose Wed, 13 Jun 2007 19:50:12 +0200 + +cell-gdb (6.6-0ubuntu1) feisty-proposed; urgency=low + + * Initial release, based on the SDK 2.1 rpm packages. + + -- Matthias Klose Mon, 14 May 2007 17:51:30 +0200 + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-testsuite +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-testsuite @@ -0,0 +1,2615 @@ +diff -urN src-orig/gdb/testsuite/configure src/gdb/testsuite/configure +--- src-orig/gdb/testsuite/configure 2007-01-23 18:11:54.000000000 +0100 ++++ src/gdb/testsuite/configure 2007-07-30 06:53:18.000000000 +0200 +@@ -1439,6 +1439,20 @@ + ;; + esac + ++# Add testsuite for combined debugger. ++case $target in ++ powerpc*) ++ if test -n "$enable_targets" ; then ++ for targ in `echo $enable_targets | sed 's/,/ /g'` ++ do ++ case "$targ" in ++ all | spu*) subdirs="$subdirs gdb.combined" ++ esac ++ done ++ fi ++ ;; ++esac ++ + # With stabs. + + # Check whether --with-stabs or --without-stabs was given. +diff -urN src-orig/gdb/testsuite/gdb.combined/arch.exp src/gdb/testsuite/gdb.combined/arch.exp +--- src-orig/gdb/testsuite/gdb.combined/arch.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/arch.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,121 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcase checks if the "show architecture" command works properly. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++# No programm running, default architecture should be powerpc:common. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently powerpc:common.*" \ ++ "startup architecture is powerpc:common" ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# In PPU thread, architecture should be powerpc:common. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently powerpc:common.*" \ ++ "ppu architecture is powerpc:common" ++ ++# Switch to SPU thread. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*"\ ++ "continuing to spu thread" ++ ++# In SPU Thread, architecture should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K" ++ ++# Stress Test: Switching from PPU- to SPU-Thread and back 'rep' times. ++set rep 100 ++for {set i 0} {$i < $rep} {incr i} { ++ # Switch to PPU Thread. ++ gdb_test "t 1" \ ++ "Switching to thread 1.*" \ ++ "switch back to thread 1 (PPU) #$i" ++ # In PPU Thread, architecture should again be powerpc:common. ++ gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently powerpc:common.*" \ ++ "ppu architecture is powerpc:common again #$i" ++ # Thread switching to SPU. ++ gdb_test "t 2" \ ++ "Switching to thread 2.*at.*$spu_file.c.*" \ ++ "switch back to thread 2 (spu) #$i" ++ # Standing in SPU thread again, architecture should be spu:256K again. ++ gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K again #$i" ++} ++# End of Stress Test loop ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/break.c src/gdb/testsuite/gdb.combined/break.c +--- src-orig/gdb/testsuite/gdb.combined/break.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/break.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,68 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t break_spu_bin; ++#define nr_t 5 ++ ++void * ++spe_thread(void * arg) ++{ ++ int flags = 0; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &break_spu_bin); ++ spe_context_run ++ (*ctx, &entry, flags, NULL, NULL, NULL); ++ ++ pthread_exit(NULL); ++} ++ ++int main() ++{ ++ int thread_id[nr_t]; ++ pthread_t pts[nr_t]; ++ spe_context_ptr_t ctx[nr_t]; ++ int value = 1; ++ int cnt; ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ { ++ ctx[cnt] = spe_context_create(0, NULL); ++ thread_id[cnt] = pthread_create ++ (&pts[cnt], NULL, &spe_thread, &ctx[cnt]); ++ } ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ pthread_join (pts[cnt], NULL); ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ spe_context_destroy (ctx[cnt]); ++ ++ return 0; ++} ++ ++void ++foo () ++{ ++ printf ("foo in break\n"); ++ return; ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/break.exp src/gdb/testsuite/gdb.combined/break.exp +--- src-orig/gdb/testsuite/gdb.combined/break.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/break.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,110 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcases tests setting and deleting breakpoints on PPU and SPU. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++# Delete breakpoints before starting the application. The debugger ++# shouldn't prompt for anything. ++gdb_test "delete breakpoints" \ ++ "" \ ++ "No prompt when deleting non-existing breakpoints" ++ ++gdb_test "break main" \ ++ "Breakpoint.*at.* file .*$testfile.c, line.*" \ ++ "breakpoint main in ppu" ++ ++if ![is_remote target] { ++ gdb_test "run" \ ++ "Starting program.*$combined_binary.*" \ ++ "run to main" ++} ++ ++delete_breakpoints ++ ++# Re-set breakpoint at main in PPU binary. ++gdb_test "break main" \ ++ "Breakpoint.*at.* file .*$testfile.c, line.*" \ ++ "breakpoint function" ++ ++# Set breakpoint in SPU binary. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++ ++# Check breakpoints. ++gdb_test "info break" \ ++ "Num Type\[ \]+Disp Enb Address\[ \]+What.* ++\[0-9\]+\[\t \]+breakpoint keep y.*in main at.*$testfile.c.* ++\[0-9\]+\[\t \]+breakpoint keep y.*PENDING.*$spu_file.c:10.*" \ ++ "breakpoint info" ++ ++gdb_test "continue" \ ++ "Continuing.*Breakpoint.*at.*file.*$spu_file.c.*Pending breakpoint.*resolved.*Switching to Thread.*" \ ++ "continuing to spu thread" ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/break-spu.c src/gdb/testsuite/gdb.combined/break-spu.c +--- src-orig/gdb/testsuite/gdb.combined/break-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/break-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,39 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++ ++void foo(); ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ int i; ++ ++ printf("Hello World! from spu\n"); ++ ++ i = 5; ++ foo (); ++ printf ("i = %d\n", i); ++ ++ return 0; ++} ++ ++void ++foo() ++{ ++ printf ("in foo\n"); ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/bt.exp src/gdb/testsuite/gdb.combined/bt.exp +--- src-orig/gdb/testsuite/gdb.combined/bt.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/bt.exp 2007-07-30 07:30:55.000000000 +0200 +@@ -0,0 +1,117 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcase tests backtraces in both PPU- and SPU-Threads including ++# cross-architecture backtraces. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++ ++if ![is_remote target] { ++ # No programm running, no backtrace available. Beside ++ # remote testing: Gdbserver already started the inferior. ++ gdb_test "bt" \ ++ "No stack.*" \ ++ "No programm running, no backtrace available" ++} else { ++ gdb_test "bt" \ ++ "#0.*" \ ++ "backtrace" ++} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Backtrace after hiting the breakpoint at main. ++gdb_test "bt" \ ++ "#0.*main.*().*at.*$testfile.c.*" \ ++ "backtrace in main" ++ ++# Continue to SPU thread. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*"\ ++ "continuing to spu thread" ++ ++# Stress Test Loop. ++set rep 25 ++for {set i 0} {$i < $rep} {incr i} { ++ gdb_test "bt" \ ++ "#0.*main.*speid.*argp.*envp.*at.*$spu_file.c.*" \ ++ "backtrace in SPU Thread" ++} ++# End Backtrace Stress Loop ++ ++# Test cross-architecture bt ++gdb_test "break $spu_file.c:30" "" "" ++gdb_test "bt" \ ++ "#0.*main.*speid.*argp.*envp.*at.*$spu_file.c.*#1.*start.*from $spu_bin.*#2.*.*#3.*syscall.*#4.*_base_spe_context_run.*#5.*spe_context_run.*#6.*spe_thread.*" \ ++ "cross-architecture backtrace from SPU Thread" ++ ++gdb_exit ++ ++return 0 +Binary files src-orig/gdb/testsuite/gdb.combined/.bt.exp.swp and src/gdb/testsuite/gdb.combined/.bt.exp.swp differ +diff -urN src-orig/gdb/testsuite/gdb.combined/data.c src/gdb/testsuite/gdb.combined/data.c +--- src-orig/gdb/testsuite/gdb.combined/data.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/data.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,69 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t data_spu_bin; ++#define nr_t 1 ++ ++void * spe_thread(void * arg) ++{ ++ int flags = 0; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &data_spu_bin); ++ spe_context_run ++ (*ctx, &entry, flags, NULL, NULL, NULL); ++ ++ pthread_exit(NULL); ++} ++ ++int main (void) ++{ ++ int thread_id[nr_t]; ++ pthread_t pts[nr_t]; ++ spe_context_ptr_t ctx[nr_t]; ++ ++ int cnt; ++ ++ char var_char = 'c'; ++ short var_short = 7; ++ int var_int = 1337; ++ long var_long = 123456; ++ long long var_longlong = 123456789; ++ float var_float = 1.23; ++ double var_double = 2.3456; ++ long double var_longdouble = 3.45678; ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ { ++ ctx[cnt] = spe_context_create(0, NULL); ++ thread_id[cnt] = pthread_create ++ (&pts[cnt], NULL, &spe_thread, &ctx[cnt]); ++ } ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ pthread_join (pts[cnt], NULL); ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ spe_context_destroy (ctx[cnt]); ++ ++ return 0; ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/data.exp src/gdb/testsuite/gdb.combined/data.exp +--- src-orig/gdb/testsuite/gdb.combined/data.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/data.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,145 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcases tries to read variables of each kind both on PPU and SPU. ++ ++load_lib combined.exp ++ ++set testfile "data" ++set ppu_file "data" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "data-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "data_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++proc check_var { name value } { ++ gdb_test "print $name" \ ++ ".*=.*$value" \ ++ "check_var $name = $value" ++} ++ ++proc set_var { name value } { ++ gdb_test "set var $name = $value" \ ++ "" \ ++ "set var $name = $value" ++} ++ ++proc dotest { name value } { ++ set_var $name $value ++ check_var $name $value ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Set values. ++dotest var_char 'z' ++dotest var_short 8 ++dotest var_int 321 ++dotest var_long 523442 ++dotest var_longlong 235354533 ++xfail "dotest var_float 33.2113" ++xfail "dotest var_double 2.3456" ++xfail "dotest var_longdouble 3.456789" ++ ++gdb_test "break 55" \ ++ "Breakpoint.*at.*file.*$testfile.c, line 55.*" \ ++ "set breakpoint" ++gdb_test "continue" \ ++ "Breakpoint.*at.*$testfile.c.*55.*" \ ++ "continue to bp at line 55" ++ ++# Lookup variables. ++check_var var_char 'c' ++check_var var_short 7 ++check_var var_int 1337 ++check_var var_long 123456 ++check_var var_longlong 123456789 ++xfail "check_var var_float 1.23" ++xfail "check_var var_double 2.3456" ++xfail "check_var var_longdouble 3.456789" ++ ++# Go to end of SPU thread. ++send_gdb "break $spu_file.c:31\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++ ++gdb_test "continue" \ ++ "Continuing.*"\ ++ "continuing to spu thread" ++ ++# In SPU Thread, arch should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K" ++ ++# Lookup variables. ++check_var var_char 'c' ++check_var var_short 7 ++check_var var_int 1337 ++check_var var_long 123456 ++check_var var_longlong 123456789 ++xfail "check_var var_float 1.23" ++xfail "check_var var_double 2.3456" ++xfail "check_var var_longdouble 3.456789" ++ ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/data-spu.c src/gdb/testsuite/gdb.combined/data-spu.c +--- src-orig/gdb/testsuite/gdb.combined/data-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/data-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,34 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ char var_char = 'c'; ++ short var_short = 7; ++ int var_int = 1337; ++ long var_long = 123456; ++ long long var_longlong = 123456789; ++ float var_float = 1.23; ++ double var_double = 2.3456; ++ long double var_longdouble = 3.45678; ++ ++ printf ("Hello from your local SPU\n"); ++ return 0; ++} ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/ea-cache.exp src/gdb/testsuite/gdb.combined/ea-cache.exp +--- src-orig/gdb/testsuite/gdb.combined/ea-cache.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ea-cache.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,108 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Testcase for ea software managed cache. ++ ++load_lib combined.exp ++ ++set testfile "ea-cache" ++set ppu_file "ea-cache-ppu" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "ea-cache-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported " Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++set spu_flags "additional_flags=-Wno-int-to-pointer-cast" ++set spu_flags "$spu_flags additional_flags=-mea32" ++if { [spu_combined_compile $spu_src $spu_bin "spu" $spu_flags] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Set breakpoint in SPU binary. ++send_gdb "break $spu_file.c:14\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" "" "" ++ ++gdb_test "p *ppe_int_ptr" \ ++ ".*=.*23.*" \ ++ "p *ppe_int_ptr" ++ ++gdb_test "set *ppe_int_ptr=42" "" "" ++ ++gdb_test "p *ppe_int_ptr" \ ++ ".*=.*42.*" \ ++ "p *ppe_int_ptr" ++ ++# Now switch to thread 1 (PPU) and look at int_var. ppe_int_ptr points to ++# int_var and should now also contain 42 (ea cache has been flushed). ++ ++gdb_test "t 1" \ ++ ".*Switching to thread 1.*" \ ++ "Switch to thread 1" ++ ++gdb_test "p int_var" \ ++ ".*=.*42.*" \ ++ "p int_var on ppu" ++ ++ ++gdb_exit ++ ++return 0 ++ ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/ea-cache-ppu.c src/gdb/testsuite/gdb.combined/ea-cache-ppu.c +--- src-orig/gdb/testsuite/gdb.combined/ea-cache-ppu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ea-cache-ppu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,48 @@ ++/* Simple combined applications for testing ea pointers on Cell ++ Broadband Engine. */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t spu; ++int int_var = 23; ++ ++void * spe_thread(void * arg) ++{ ++ int flags = 0; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &spu); ++ spe_context_run ++ (*ctx, &entry, flags, &int_var, NULL, NULL); ++ ++ pthread_exit(NULL); ++} ++ ++int main () ++{ ++ spe_context_ptr_t ctx; ++ pthread_t pts; ++ int thread_id; ++ ++ printf ("ppe.c | int_var vor %d | adr int_var %p\n", int_var, &int_var); ++ ++ /* Create SPE context and pthread. */ ++ ctx = spe_context_create (0, NULL); ++ thread_id = pthread_create (&pts, NULL, &spe_thread, &ctx); ++ ++ /* Join the pthread. */ ++ pthread_join (pts, NULL); ++ ++ /* Destroy the SPE context. */ ++ spe_context_destroy (ctx); ++ ++ printf ("ppe.c | int_var nach %d\n", int_var); ++ ++ return 0; ++} ++ ++ ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/ea-cache-spu.c src/gdb/testsuite/gdb.combined/ea-cache-spu.c +--- src-orig/gdb/testsuite/gdb.combined/ea-cache-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ea-cache-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,18 @@ ++#include ++#include ++ ++ ++__ea int *ppe_int_ptr; ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ printf ("spe.c | argp = 0x%llx\n", argp); ++ ++ ppe_int_ptr = (__ea int *)argp; ++ printf ("spe.c | value = %d\n", *ppe_int_ptr); ++ *ppe_int_ptr = 42; ++ printf ("spe.c | value = %d\n", *ppe_int_ptr); ++ ++ return 0; ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/ea-test.c src/gdb/testsuite/gdb.combined/ea-test.c +--- src-orig/gdb/testsuite/gdb.combined/ea-test.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ea-test.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,29 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++ ++__ea int *ppe_pointer; ++int *normal_pointer; ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ static __ea int *local_ppe_pointer; ++ static int *local_normal_pointer; ++ return 0; ++} ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/ea-test.exp src/gdb/testsuite/gdb.combined/ea-test.exp +--- src-orig/gdb/testsuite/gdb.combined/ea-test.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ea-test.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,133 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Testcase for __ea pointer ++ ++load_lib combined.exp ++ ++set testfile "ea-test" ++set spu_file "ea-test" ++set source ${srcdir}/${subdir}/${spu_file}.c ++set binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++set compile_flags {debug -c compiler=spu-gcc} ++set compile_flags "$compile_flags additional_flags=-mea32" ++if { [gdb_compile $source $binary executable $compile_flags] != "" } { ++ return "Error. SPU compile" ++} ++ ++if [get_compiler_info ${binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# p ++gdb_test "p ppe_pointer" \ ++ "(int.*@__ea).*0x0.*" \ ++ "p ppe_pointer" ++ ++gdb_test "p normal_pointer" \ ++ "(int.*).*0x0.*" \ ++ "p normal_pointer" ++ ++gdb_test "p local_ppe_pointer" \ ++ "(int.*@__ea).*0x0.*" \ ++ "p local_ppe_pointer" ++ ++gdb_test "p local_normal_pointer" \ ++ "(int.*).*0x0.*" \ ++ "p local_normal_pointer" ++ ++# ptype ++gdb_test "ptype ppe_pointer" \ ++ "type = int.*@__ea" \ ++ "ptype ppe_pointer" ++ ++gdb_test "ptype normal_pointer" \ ++ "type = int.*" \ ++ "ptype normal_pointer" ++ ++gdb_test "ptype local_ppe_pointer" \ ++ "type = int.*@__ea" \ ++ "ptype local_ppe_pointer" ++ ++gdb_test "ptype local_normal_pointer" \ ++ "type = int.*" \ ++ "ptype local_normal_pointer" ++ ++# info locals ++gdb_test "info locals" \ ++ ".*local_ppe_pointer =.*(int.*@__ea).*0x0.*local_normal_pointer =.*(int.*).*0x0.*" \ ++ "info locals" ++ ++# p & ++gdb_test "p &ppe_pointer" \ ++ ".*=.*(int.*@__ea.*).*0x.*" \ ++ "p &ppe_pointer" ++ ++gdb_test "p &normal_pointer" \ ++ ".*=.*(int.*).*0x.*" \ ++ "p &normal_pointer" ++ ++gdb_test "p &local_ppe_pointer" \ ++ ".*=.*(int.*@__ea.*).*0x.*" \ ++ "p &local_ppe_pointer" ++ ++gdb_test "p &local_normal_pointer" \ ++ ".*=.*(int.*).*0x.*" \ ++ "p &local_normal_pointer" ++ ++# p * ++gdb_test "p *ppe_pointer" \ ++ ".*=.*" \ ++ "p *ppe_pointer" ++ ++gdb_test "p *normal_pointer" \ ++ ".*=.*" \ ++ "p *normal_pointer" ++ ++gdb_test "p *local_ppe_pointer" \ ++ ".*=.*" \ ++ "p *local_ppe_pointer" ++ ++gdb_test "p *local_normal_pointer" \ ++ ".*=.*" \ ++ "p *local_normal_pointer" ++ ++gdb_exit ++ ++return 0 ++ ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/f-regs.exp src/gdb/testsuite/gdb.combined/f-regs.exp +--- src-orig/gdb/testsuite/gdb.combined/f-regs.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/f-regs.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,120 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcase tests access to SPU vector registers while language is fortran. ++# This testcase also would work SPU-only. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++proc check_vector_regs {} { ++ for {set check_reg 0} {$check_reg < 128} {incr check_reg} { ++ ++ gdb_test "p \$r$check_reg" \ ++ "r$check_reg.*uint128.*=.*v2\_int64.*v4\_int32.*v8\_int16.*v16\_int8.*v2\_double.*v4\_float.*" \ ++ "p \$r$check_reg" ++ ++ gdb_test "ptype \$r$check_reg" \ ++ "type.*=.*union.*__spu_builtin_type_vec128.*" \ ++ "ptype \$r$check_reg" ++ ++ } ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![is_remote target] { ++ # No programm running, no registers should be available. ++ gdb_test "info all-registers" \ ++ "The program has no registers now." \ ++ "info all-registers" ++} else { ++ # Gdbserver already started the inferior so the registers ++ # are available. ++ gdb_test "info all-registers" \ ++ "r0.*r1.*r31.*pc.*ps.*cr.*lr.*ctr.*xer.*fpscr.*orig_r3.*vr0.*" \ ++ "info all-registers" ++} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Go to SPU thread and check registers. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continuing to spu thread" ++ ++gdb_test "set language c" "" "set language c" ++check_vector_regs ++ ++gdb_test "set language fortran" \ ++ "Warning: the current language does not match this frame.*" \ ++ "set language fortran" ++check_vector_regs ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/info-spu.c src/gdb/testsuite/gdb.combined/info-spu.c +--- src-orig/gdb/testsuite/gdb.combined/info-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/info-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,56 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t break_spu_bin; ++ ++void * spe_thread(void * arg) ++{ ++ int flags = SPE_MAP_PS; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &break_spu_bin); ++ spe_context_run ++ (*ctx, &entry, flags, NULL, NULL, NULL); ++ ++ pthread_exit(NULL); ++} ++ ++int main() ++{ ++ pthread_t pthread; ++ spe_context_ptr_t ctx; ++ void *ps; ++ ++ ctx = spe_context_create(0, NULL); ++ pthread_create (&pthread, NULL, &spe_thread, &ctx); ++ ++ /* Write signals to the SPU. */ ++ ps = spe_ps_area_get (ctx, SPE_SIG_NOTIFY_1_AREA); ++ spe_signal_write (ctx, SPE_SIG_NOTIFY_REG_1 ,23); ++ spe_signal_write (ctx, SPE_SIG_NOTIFY_REG_2 ,0x12345678); ++ ++ pthread_join (pthread, NULL); ++ spe_context_destroy (ctx); ++ ++ return 0; ++} ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/info-spu.exp src/gdb/testsuite/gdb.combined/info-spu.exp +--- src-orig/gdb/testsuite/gdb.combined/info-spu.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/info-spu.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,113 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Test for 'info spu' commands. ++ ++load_lib combined.exp ++ ++set testfile "info-spu" ++set ppu_file "info-spu" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++gdb_test "info spu" \ ++ ".*info spu.* must be followed by the name of an SPU facility.*" \ ++ "info spu" ++gdb_test "help info spu" \ ++ "Various SPU specific commands.*List of info spu subcommands.*" \ ++ "help info spu" ++ ++# Go to SPU thread. ++gdb_test "set spu stop-on-load on" "" "set spu stop-on-load on" ++gdb_test "continue" "Continuing.*" "continue" ++ ++# In SPU Thread, architecture should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "architecture = spu256K" ++ ++# 'info spu event'. ++gdb_test "info spu event" \ ++ "Event Status.*0x00000000.*Event Mask.*0x00000000.*" \ ++ "info spu event" ++ ++# 'info spu signal'. ++gdb_test "info spu signal" \ ++ "Signal 1 control word 0x00000017.*Signal 2 control word 0x12345678.*" \ ++ "info spu signal" ++ ++# 'info spu mailbox'. ++gdb_test "info spu mailbox" \ ++ "SPU Outbound Mailbox.*0xc0000000.*SPU Outbound Interrupt Mailbox.*0xc0000000.*" \ ++ "info spu mailbox" ++ ++# 'info spu dma' ++gdb_test "info spu dma" \ ++ "Tag-Group Status.*0x00000000.*Tag-Group Mask.*0x00000000.*Stall-and-Notify.*0x00000000.*Atomic Cmd Status.*0x00000000.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*" \ ++ "info spu dma" ++ ++# 'info spu proxydma' ++gdb_test "info spu proxydma" \ ++ "Tag-Group Status.*Tag-Group Mask.*Opcode.*Tag.*TId.*RId.*EA.*LSA.*Size.*LstAddr.*LstSize.*E.*" \ ++ "info spu proxydma" ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/Makefile.in src/gdb/testsuite/gdb.combined/Makefile.in +--- src-orig/gdb/testsuite/gdb.combined/Makefile.in 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/Makefile.in 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,17 @@ ++VPATH = @srcdir@ ++srcdir = @srcdir@ ++ ++EXECUTABLES = break data ea-cache ea-test info-spu mem-access size \ ++ ++all info install-info dvi install uninstall installcheck check: ++ @echo "Nothing to be done for $@..." ++ ++clean mostlyclean: ++ -rm -f *~ *.o *.a a.out ++ -rm -f $(EXECUTABLES) ++ ++distclean maintainer-clean realclean: clean ++ -rm -f *~ ++ -rm -f Makefile config.status config.log ++ -rm -f *-init.exp ++ -rm -fr *.log summary detail *.plog *.sum *.psum site.* +diff -urN src-orig/gdb/testsuite/gdb.combined/mem-access.c src/gdb/testsuite/gdb.combined/mem-access.c +--- src-orig/gdb/testsuite/gdb.combined/mem-access.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/mem-access.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,63 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t break_spu_bin; ++#define nr_t 1 ++ ++void * spe_thread(void * arg) ++{ ++ int flags = 0; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &break_spu_bin); ++ spe_context_run ++ (*ctx, &entry, flags, NULL, NULL, NULL); ++ ++ pthread_exit (NULL); ++} ++ ++int main() ++{ ++ int thread_id[nr_t]; ++ pthread_t pts[nr_t]; ++ spe_context_ptr_t ctx[nr_t]; ++ int value = 1; ++ int cnt; ++ static int test_var; ++ ++ test_var = 5; ++ for (cnt = 0; cnt < nr_t; cnt++) ++ { ++ ctx[cnt] = spe_context_create(0, NULL); ++ thread_id[cnt] = pthread_create ++ (&pts[cnt], NULL, &spe_thread, &ctx[cnt]); ++ } ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ pthread_join (pts[cnt], NULL); ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ spe_context_destroy (ctx[cnt]); ++ ++ return 0; ++} ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/mem-access.exp src/gdb/testsuite/gdb.combined/mem-access.exp +--- src-orig/gdb/testsuite/gdb.combined/mem-access.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/mem-access.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,201 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcases tests on PPU and SPU if variables and registers are accessible ++# via print and set by using names and adresses. ++ ++load_lib combined.exp ++ ++set testfile "mem-access" ++set ppu_file "mem-access" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "mem-access-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++# Get the adress to symbol name. If $reg ++# is set to 1, get address from a register. ++proc get_adress_from_name { name reg } { ++ global gdb_prompt ++ set adr "" ++ ++ if { $reg == 1 } { ++ set q "x/x $name" ++ } else { ++ set q "x/x &$name" ++ } ++ ++ gdb_test_multiple $q "get address from $name" { ++ -re "(0x.....):.*$gdb_prompt $" { # Registers. ++ set adr $expect_out(1,string) ++ pass "get adress from $name = $adr" ++ } ++ -re "(0x........) <.*$gdb_prompt $" { # PPU address. ++ set adr $expect_out(1,string) ++ pass "get adress from $name = $adr" ++ } ++ -re "(0x....) <.*$gdb_prompt $" { # SPU address. ++ set adr $expect_out(1,string) ++ pass "get adress from $name = $adr" ++ } ++ -re "(0x...) <.*$gdb_prompt $" { # SPU address. ++ set adr $expect_out(1,string) ++ pass "get adress from $name = $adr" ++ } ++ } ++ ++ return ${adr} ++} ++ ++# Try to set a $value at adress $adr. ++proc set_adr_content { adr value } { ++ gdb_test "set *$adr=$value" \ ++ "" \ ++ "set *$adr=$value" ++} ++ ++# Try to set a $value for $symbol. ++proc set_symbol_content { symbol value } { ++ gdb_test "set $symbol=$value" \ ++ "" \ ++ "set *$symbol=$value" ++} ++ ++# Check if $value is at *adr ++proc test_adr_content { adr value } { ++ gdb_test "p *$adr" \ ++ ".*=.*$value.*" \ ++ "(ptr) *$adr==$value" ++} ++ ++proc test_symbol_content { symbol value } { ++ gdb_test "p $symbol" \ ++ ".*=.*$value.*" \ ++ "(symbol) $symbol==$value" ++} ++ ++# Check VARNAME. Check if it has the inital ++# value INITIALVALUE. Set it to NEWVALUE. ++# Check if set properly. Do it via symbols and ++# pointers. ++proc check_var { varname initalvalue newvalue } { ++ ++ # Initial value should be $initalvalue. ++ test_symbol_content $varname $initalvalue ++ ++ # Get pointer to symbol and check if the ++ # initial value is found. ++ set adr [get_adress_from_name $varname 0] ++ test_adr_content $adr $initalvalue ++ ++ # Re-set value using the pointer. ++ set_adr_content $adr $newvalue ++ ++ # Test values by pointer and by symbol. ++ test_adr_content $adr $newvalue ++ test_symbol_content $varname $newvalue ++ ++ # Set value back to initalvalue using symbol ++ # name and check it. ++ set_symbol_content $varname $initalvalue ++ test_adr_content $adr $initalvalue ++ test_symbol_content $varname $initalvalue ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Go to PPU thread. ++gdb_test "break $ppu_file.c:48" \ ++ "Breakpoint.*at.*0x.*:.*file.*$ppu_file.*line 48.*" \ ++ "reached ppu breakpoint" ++ ++# Continute to breakpoint. ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continuing to breakpoint" ++ ++# Check on PPU. ++check_var "test_var" 5 7 ++ ++ ++# Go to SPU thread. ++send_gdb "break $spu_file.c:28\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continuing to spu thread" ++ ++# In SPU thread, architecture should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K" ++ ++# Check on spu side. ++check_var "test_var" 5 7 ++ ++# Check $sp register. ++set adr [get_adress_from_name "\$sp" 1] ++set_adr_content $adr 8 ++test_adr_content $adr 8 ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/mem-access-spu.c src/gdb/testsuite/gdb.combined/mem-access-spu.c +--- src-orig/gdb/testsuite/gdb.combined/mem-access-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/mem-access-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,32 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ int i; ++ static int test_var; ++ ++ printf("Hello World! from spu\n"); ++ ++ test_var = 5; ++ i = 5; ++ printf ("i = %d\n", i); ++ ++ return 0; ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/ptype.exp src/gdb/testsuite/gdb.combined/ptype.exp +--- src-orig/gdb/testsuite/gdb.combined/ptype.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/ptype.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,163 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Test ptype and print/set of SPU-side registers. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Set breakpoint in SPU binary. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++ ++gdb_test "continue" \ ++ "Continuing.*Breakpoint.*at.*file.*$spu_file.c.*Pending breakpoint.*resolved.*Switching to Thread.*" \ ++ "continuing to spu thread" ++ ++gdb_test "info registers r2" \ ++ "r2.*\{uint128 =.*v2_int64 =.*v4_int32 =.*v8_int16 =.*v16_int8 =.*v2_double =.*v4_float =.*\}.*" \ ++ "info registers r2" ++ ++for {set check_reg 10} {$check_reg < 12} {incr check_reg} { ++ gdb_test "print \$r$check_reg\.v4_int32" \ ++ ".*= \{.*,.*,.*,.*\}" \ ++ "print \$r$check_reg\.v4_int32" ++ ++ gdb_test "ptype \$r$check_reg" \ ++ "type = union __spu_builtin_type_vec128.*\{.*int128_t uint128.* \ ++ int64_t v2_int64.*int32_t v4_int32.*int16_t v8_int16.* \ ++ int8_t v16_int8.*double v2_double.*float v4_float.*\}" \ ++ "ptype \$r$check_reg" ++ ++ gdb_test "set \$r$check_reg\.v4_int32 = {1,2,3,4}" \ ++ "" \ ++ "set \$r$check_reg\.v4_int32 = {1,2,3,4}" ++ ++ gdb_test "print \$r$check_reg\.v4_int32" \ ++ ".*= \{.*1, 2, 3, 4.*\}" \ ++ "print \$r$check_reg\.v4_int32" ++ ++ gdb_test "print \$r$check_reg.v4_int32\[0\]" \ ++ ".*= 1.*" \ ++ "print \$r$check_reg.v4_int32\[0\]" ++ ++ gdb_test "print \$r$check_reg.v4_int32\[1\]" \ ++ ".*= 2.*" \ ++ "print \$r$check_reg.v4_int32\[1\]" ++ ++ gdb_test "print \$r$check_reg.v4_int32\[2\]" \ ++ ".*= 3.*" \ ++ "print \$r$check_reg.v4_int32\[2\]" ++ ++ gdb_test "print \$r$check_reg.v4_int32\[3\]" \ ++ ".*= 4.*" \ ++ "print \$r$check_reg.v4_int32\[3\]" ++ ++ gdb_test "print \$r$check_reg.v4_int32\[4\]" \ ++ "no such vector element" \ ++ "print \$r$check_reg.v4_int32\[4\]" ++ ++ # Set single array elements to other values and check the results. ++ gdb_test "set \$r$check_reg\.v4_int32\[0\] = 5" \ ++ "" \ ++ "set \$r$check_reg\.v4_int32\[0\] = 5" ++ gdb_test "print \$r$check_reg.v4_int32\[0\]" \ ++ ".*= 5.*" \ ++ "print \$r$check_reg.v4_int32\[0\]" ++ ++ gdb_test "set \$r$check_reg\.v4_int32\[1\] = 6" \ ++ "" \ ++ "set \$r$check_reg\.v4_int32\[1\] = 6" ++ gdb_test "print \$r$check_reg.v4_int32\[1\]" \ ++ ".*= 6.*" \ ++ "print \$r$check_reg.v4_int32\[1\]" ++ ++ gdb_test "set \$r$check_reg\.v4_int32\[2\] = 7" \ ++ "" \ ++ "set \$r$check_reg\.v4_int32\[2\] = 7" ++ gdb_test "print \$r$check_reg.v4_int32\[2\]" \ ++ ".*= 7.*" \ ++ "print \$r$check_reg.v4_int32\[2\]" ++ ++ gdb_test "set \$r$check_reg\.v4_int32\[3\] = 8" \ ++ "" \ ++ "set \$r$check_reg\.v4_int32\[3\] = 8" ++ gdb_test "print \$r$check_reg.v4_int32\[3\]" \ ++ ".*= 8.*" \ ++ "print \$r$check_reg.v4_int32\[3\]" ++ ++ # Now there should be {5, 6, 7, 8} in that array. ++ gdb_test "print \$r$check_reg\.v4_int32" \ ++ ".*= \{.*5, 6, 7, 8.*\}" \ ++ "print \$r$check_reg\.v4_int32" ++} ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/registers.exp src/gdb/testsuite/gdb.combined/registers.exp +--- src-orig/gdb/testsuite/gdb.combined/registers.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/registers.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,131 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcase tests registers on PPU and SPU. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![is_remote target] { ++ # No programm running, no registers should be available. ++ gdb_test "info all-registers" \ ++ "The program has no registers now." \ ++ "info all-registers" ++} else { ++ # Gdbserver already started the inferior so the registers ++ # are available. ++ gdb_test "info all-registers" \ ++ "r0.*r1.*r31.*pc.*ps.*cr.*lr.*ctr.*xer.*fpscr.*orig_r3.*vr0.*" \ ++ "info all-registers" ++} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Check registers on PPU. ++gdb_test "info reg r0" "r0.*" "info register r0" ++gdb_test "info reg r31" "r31.*" "info register r31" ++gdb_test "info reg r32" "Invalid register.*r32.*" "(invalid) info register r32" ++gdb_test "info reg pc" "pc.*" "info register pc" ++gdb_test "info reg cr" "cr.*" "info register cr" ++gdb_test "info reg lr" "lr.*" "info register lr" ++gdb_test "info reg ctr" "ctr.*" "info register ctr" ++gdb_test "info reg xer" "xer.*" "info register xer" ++ ++# Go to SPU thread and check registers. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continuing to spu thread" ++ ++# In SPU thread, check SPU registers. ++for {set check_reg 0} {$check_reg < 128} {incr check_reg} { ++ gdb_test "info reg r$check_reg" \ ++ "r$check_reg.*uint128.*=.*v2\_int64.*v4\_int32.*v8\_int16.*v16\_int8.*v2\_double.*v4\_float.*" \ ++ "info register r$check_reg" ++} ++gdb_test "info reg r128" \ ++ "Invalid register.*r128.*" \ ++ "(invalid) info register r128" ++ ++gdb_test "info reg pc" "pc.*main.*" "info register pc" ++gdb_test "info reg id" "id.*" "info register id" ++gdb_test "info reg sp" "sp.*" "info register sp" ++gdb_test "info reg fpscr" "fpscr.*" "info register fpscr" ++gdb_test "info reg srr0" "srr0.*" "info register srr0" ++gdb_test "info reg lslr" "lslr.*" "info register lslr" ++gdb_test "info reg decr" "decr.*" "info register decr" ++gdb_test "info reg decr_status" "decr_status.*" "info register decr-status" ++ ++gdb_test "info reg cr" "Invalid register.*cr.*" "info register cr" ++gdb_test "info reg lr" "Invalid register.*lr.*" "info register lr" ++gdb_test "info reg ctr" "Invalid register.*ctr.*" "info register ctr" ++gdb_test "info reg xer" "Invalid register.*xer.*" "info register xer" ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/size.c src/gdb/testsuite/gdb.combined/size.c +--- src-orig/gdb/testsuite/gdb.combined/size.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/size.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,83 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++#include ++#include ++#include ++ ++extern spe_program_handle_t spu_bin; ++#define nr_t 1 ++ ++void * spe_thread(void * arg) ++{ ++ int flags = 0; ++ unsigned int entry = SPE_DEFAULT_ENTRY; ++ spe_context_ptr_t * ctx = (spe_context_ptr_t *) arg; ++ ++ spe_program_load (*ctx, &spu_bin); ++ spe_context_run ++ (*ctx, &entry, flags, NULL, NULL, NULL); ++ ++ pthread_exit (NULL); ++} ++ ++int main (void) ++{ ++ int thread_id[nr_t]; ++ pthread_t pts[nr_t]; ++ spe_context_ptr_t ctx[nr_t]; ++ int cnt; ++ ++ int c = sizeof (char); ++ printf ("sizeof(char)=%d\n", c); ++ ++ int s = sizeof (short); ++ printf ("sizeof(short)=%d\n", s); ++ ++ int i = sizeof (int); ++ printf ("sizeof(int)=%d\n", i); ++ ++ int l = sizeof (long); ++ printf ("sizeof(long)=%d\n", l); ++ ++ int ll = sizeof (long long); ++ printf ("sizeof(long long)=%d\n", ll); ++ ++ int f = sizeof (float); ++ printf ("sizeof(float)=%d\n", f); ++ ++ int d = sizeof (double); ++ printf ("sizeof(double)=%d\n", d); ++ ++ int ld = sizeof (long double); ++ printf ("sizeof(long double)=%d\n", ld); ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ { ++ ctx[cnt] = spe_context_create(0, NULL); ++ thread_id[cnt] = pthread_create ++ (&pts[cnt], NULL, &spe_thread, &ctx[cnt]); ++ } ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ pthread_join (pts[cnt], NULL); ++ ++ for (cnt = 0; cnt < nr_t; cnt++) ++ spe_context_destroy (ctx[cnt]); ++ ++ return 0; ++} +diff -urN src-orig/gdb/testsuite/gdb.combined/sizeof.exp src/gdb/testsuite/gdb.combined/sizeof.exp +--- src-orig/gdb/testsuite/gdb.combined/sizeof.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/sizeof.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,141 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Check size of data types both on PPU and SPU. ++ ++load_lib combined.exp ++ ++set testfile "size" ++set ppu_file "size" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "size-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++# Ask GDB about the sizes of data types. This has ++# to be done on PPU and SPU. ++proc get_gdb_size { type } { ++ global gdb_prompt ++ ++ set val "0" ++ gdb_test_multiple "print/d sizeof(${type})" "get sizeof(${type})" { ++ -re "\\$\[0-9\]* = (\[-\]*\[0-9\]*).*$gdb_prompt $" { ++ set val $expect_out(1,string) ++ pass "get sizeof ($type) = $val" ++ } ++ } ++ return ${val} ++} ++ ++# Compare sizes from GDB and sizeof(). ++proc size_compare { type gdb_size } { ++ set expr [string_to_regexp "sizeof(${type})=${gdb_size}"] ++ gdb_test "next" \ ++ ".*" \ ++ "next" ++ # Checks against string_to_regexp fails in remote testing. ++ if ![is_remote target] { ++ gdb_test "next" \ ++ "${expr}.*" \ ++ "check sizeof \"$type\" \"$gdb_size\" " ++ } else { ++ gdb_test "next" ".*" "check sizeof deactivate in remote testing" ++ } ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++gdb_test "next" "" "" ++ ++# Compare sizes. ++size_compare "char" [get_gdb_size "char"] ++size_compare "short" [get_gdb_size "short"] ++size_compare "int" [get_gdb_size "int"] ++size_compare "long" [get_gdb_size "long"] ++size_compare "long long" [get_gdb_size "long long"] ++size_compare "float" [get_gdb_size "float"] ++size_compare "double" [get_gdb_size "double"] ++size_compare "long double" [get_gdb_size "long double"] ++ ++# Go to SPU thread. ++send_gdb "break $spu_file.c:23\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continuing to spu thread" ++ ++# In SPU thread, architecture should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K" ++ ++# Compare sizes in SPU thread. ++size_compare "char" [get_gdb_size "char"] ++size_compare "short" [get_gdb_size "short"] ++size_compare "int" [get_gdb_size "int"] ++size_compare "long" [get_gdb_size "long"] ++size_compare "long long" [get_gdb_size "long long"] ++size_compare "float" [get_gdb_size "float"] ++size_compare "double" [get_gdb_size "double"] ++size_compare "long double" [get_gdb_size "long double"] ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/size-spu.c src/gdb/testsuite/gdb.combined/size-spu.c +--- src-orig/gdb/testsuite/gdb.combined/size-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/size-spu.c 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,49 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling */ ++#include ++ ++ ++int main(unsigned long long speid, unsigned long long argp, ++ unsigned long long envp) ++{ ++ int c = sizeof (char); /* Break here. */ ++ printf ("sizeof(char)=%d\n", c); ++ ++ int s = sizeof (short); ++ printf ("sizeof(short)=%d\n", s); ++ ++ int i = sizeof (int); ++ printf ("sizeof(int)=%d\n", i); ++ ++ int l = sizeof (long); ++ printf ("sizeof(long)=%d\n", l); ++ ++ int ll = sizeof (long long); ++ printf ("sizeof(long long)=%d\n", ll); ++ ++ int f = sizeof (float); ++ printf ("sizeof(float)=%d\n", f); ++ ++ int d = sizeof (double); ++ printf ("sizeof(double)=%d\n", d); ++ ++ int ld = sizeof (long double); ++ printf ("sizeof(long double)=%d\n", ld); ++ ++ return 0; ++} ++ +diff -urN src-orig/gdb/testsuite/gdb.combined/solib.exp src/gdb/testsuite/gdb.combined/solib.exp +--- src-orig/gdb/testsuite/gdb.combined/solib.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/solib.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,115 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# This testcase checks 'info sharedlibrary ' command. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![is_remote target] { ++ # No programm running, no libraries should be loaded. ++ gdb_test "info sharedlibrary" \ ++ "No shared libraries loaded at this time." \ ++ "no shared library is loaded" ++} else { ++ # Gdbserver already started the inferior so ld should ++ # be given by info sharedlibrary. ++ gdb_test "info sharedlibrary" \ ++ "From.*To.*Syms Read.*Shared Object Library.*lib.*ld.*so.*" \ ++ "gdbserver started inferior, some libraries loaded" ++} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Standing in PPU thread, now some libs should be loaded ++# including libspe library. ++gdb_test "info sharedlibrary" \ ++ "From.*To.*Syms Read.*Shared Object Library.*libspe.*" \ ++ "binary started, some libraries loaded" ++ ++# Go to SPU thread, check SPU registers. ++send_gdb "break $spu_file.c:10\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++# Continue into SPU thread. ++gdb_test "continue" \ ++ "Continuing.*"\ ++ "continuing to spu thread" ++ ++# In SPU thread, architecture should now be spu:256K. ++gdb_test "show architecture" \ ++ "The target architecture is set automatically.*currently spu:256K.*" \ ++ "spu architecture is spu256K" ++ ++# In SPU thread now, the SPU binary should now appear in the list ++# of shared libraries. ++gdb_test "info sharedlibrary" \ ++ "From.*To.*Syms Read.*Shared Object Library.*libspe.*$spu_bin.*@.*x.*" \ ++ "spu thread, spu binary as shared library" ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/gdb.combined/solib-symbol.exp src/gdb/testsuite/gdb.combined/solib-symbol.exp +--- src-orig/gdb/testsuite/gdb.combined/solib-symbol.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.combined/solib-symbol.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,96 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++# Testsuite for Cell Broadband Engine combined debugger ++# Testcase for multiple symbol disambiguation patch. ++ ++load_lib combined.exp ++ ++set testfile "break" ++set ppu_file "break" ++set ppu_src ${srcdir}/${subdir}/${ppu_file}.c ++set ppu_bin ${objdir}/${subdir}/${ppu_file}.o ++set spu_file "break-spu" ++set spu_src ${srcdir}/${subdir}/${spu_file}.c ++set spu_bin ${objdir}/${subdir}/${spu_file}.a ++set combined_binary ${objdir}/${subdir}/${testfile} ++ ++if { ![ishost "powerpc*-linux*"] || ++ ![istarget "powerpc*-linux*"] || ++ ![do_combined_tests "${objdir}/${subdir}/"] } then { ++ unsupported "Skipping combined debugger testcase (wrong host/target)" ++ return -1 ++} ++ ++# Compile SPU binary. ++if { [spu_combined_compile $spu_src $spu_bin "break_spu_bin" ""] != "" } { ++ unsupported "Compile spu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Compile PPU binary. ++set compile_flags {debug -c compiler=ppu-gcc} ++if { [gdb_compile $ppu_src $ppu_bin object $compile_flags] != "" } { ++ unsupported "Compile ppu binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++# Assemble combined binary. ++if { [assemble_combined $ppu_bin $spu_bin $combined_binary] != "" } { ++ unsupported "Assemble combined binary failed, so all tests in this file will automatically fail." ++ return -1 ++} ++ ++if [get_compiler_info ${combined_binary}] { ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${combined_binary} ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Breakpoint resolved in PPE executable. ++gdb_test "break foo" \ ++ "Breakpoint.*file.*$ppu_file.c.*" \ ++ "br foo in break" ++ ++# Go to SPU thread ++send_gdb "break $spu_file.c:26\n" ++gdb_expect { ++ -re ".*$spu_file.c.*Make breakpoint pending.*y or \\\[n\\\]. $" { ++ gdb_test "y" "Breakpoint.*$spu_file.*pending." "set pending breakpoint" ++ } ++ timeout { fail "Timeout while setting breakpoint in spu binary" } ++} ++# Continue into SPU thread. ++gdb_test "continue" \ ++ "Continuing.*"\ ++ "continuing to spu thread" ++ ++# Breakpoint resolved in SPE executable. ++delete_breakpoints ++gdb_test "break foo" \ ++ "Breakpoint.*file.*$spu_file.c.*" \ ++ "br foo in $spu_file.c" ++ ++gdb_exit ++ ++return 0 +diff -urN src-orig/gdb/testsuite/lib/combined.exp src/gdb/testsuite/lib/combined.exp +--- src-orig/gdb/testsuite/lib/combined.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/lib/combined.exp 2007-07-30 06:53:18.000000000 +0200 +@@ -0,0 +1,59 @@ ++# Testsuite for Cell Broadband Engine combined debugger ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# Support library for testing the combined debugger for Linux on Cell ++# Broadband Engine. ++ ++# Compiler and embed SPU binary. ++proc spu_combined_compile {source dest symbol flags} { ++ set compile_flags {debug -c compiler=spu-gcc} ++ set compile_flags "$compile_flags $flags" ++ if { [gdb_compile $source $dest.o executable $compile_flags] != "" } { ++ return "ERR" ++ } ++ ++ set compile_flags {debug -c compiler=ppu-embedspu} ++ if { [gdb_compile "$symbol $dest.o $dest-embed.o" "" none $compile_flags] != "" } { ++ return "ERR" ++ } ++ ++ set compile_flags {compiler=ar} ++ if { [gdb_compile "-qcs $dest $dest-embed.o" "" none $compile_flags] != "" } { ++ return "ERR" ++ } ++ ++ return "" ++} ++ ++# Assembles SPU- and PPU-binaries to one combined binary. ++proc assemble_combined {ppu_bin spu_bin dest} { ++ set compile_flags {debug -c compiler=ppu-gcc} ++ set compile_flags "$compile_flags additional_flags=-lspe2 -lpthread" ++ ++ if { [gdb_compile "$ppu_bin $spu_bin" $dest executable $compile_flags] != "" } { ++ return "ERR" ++ } ++ ++ return "" ++} ++ ++# Check if $dir exists. If so GDB was configure with ++# --enable-targets=all | spu. ++proc do_combined_tests { dir } { ++ return [file isdirectory "$dir"] ++} ++ --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-frame +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-frame @@ -0,0 +1,755 @@ +diff -urNp src-orig/gdb/elfread.c src/gdb/elfread.c +--- src-orig/gdb/elfread.c 2007-07-13 21:17:47.990734527 +0200 ++++ src/gdb/elfread.c 2007-07-13 21:04:36.654531994 +0200 +@@ -301,7 +301,8 @@ elf_symtab_read (struct objfile *objfile + /* Bfd symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + /* Relocate all non-absolute symbols by the section offset. */ +- if (sym->section != &bfd_abs_section) ++ if (sym->section != &bfd_abs_section ++ && !(sym->section->flags & SEC_THREAD_LOCAL)) + { + symaddr += offset; + } +diff -urNp src-orig/gdb/frame.c src/gdb/frame.c +--- src-orig/gdb/frame.c 2007-07-13 21:17:47.999733231 +0200 ++++ src/gdb/frame.c 2007-07-13 21:20:34.720978872 +0200 +@@ -95,6 +95,13 @@ struct frame_info + int p; + struct frame_id value; + } this_id; ++ ++ /* This frame's architecture. */ ++ struct ++ { ++ int p; ++ struct gdbarch *arch; ++ } this_arch; + + /* The frame's high-level base methods, and corresponding cache. + The high level base methods are selected based on the frame's +@@ -191,6 +198,9 @@ fprint_frame_type (struct ui_file *file, + case SIGTRAMP_FRAME: + fprintf_unfiltered (file, "SIGTRAMP_FRAME"); + return; ++ case ARCH_FRAME: ++ fprintf_unfiltered (file, "ARCH_FRAME"); ++ return; + default: + fprintf_unfiltered (file, ""); + return; +@@ -829,13 +839,15 @@ put_frame_register_bytes (struct frame_i + int + frame_map_name_to_regnum (struct frame_info *frame, const char *name, int len) + { +- return user_reg_map_name_to_regnum (get_frame_arch (frame), name, len); ++ struct gdbarch *gdbarch = frame? get_frame_arch (frame) : current_gdbarch; ++ return user_reg_map_name_to_regnum (gdbarch, name, len); + } + + const char * + frame_map_regnum_to_name (struct frame_info *frame, int regnum) + { +- return user_reg_map_regnum_to_name (get_frame_arch (frame), regnum); ++ struct gdbarch *gdbarch = frame? get_frame_arch (frame) : current_gdbarch; ++ return user_reg_map_regnum_to_name (gdbarch, regnum); + } + + /* Create a sentinel frame. */ +@@ -997,6 +1009,8 @@ select_frame (struct frame_info *fi) + source language of this frame, and switch to it if desired. */ + if (fi) + { ++ current_gdbarch = get_frame_arch (fi); ++ + /* We retrieve the frame's symtab by using the frame PC. However + we cannot use the frame PC as-is, because it usually points to + the instruction following the "call", which is sometimes the +@@ -1186,6 +1200,7 @@ get_prev_frame_1 (struct frame_info *thi + go backwards) and sentinel frames (the test is meaningless). */ + if (this_frame->next->level >= 0 + && this_frame->next->unwind->type != SIGTRAMP_FRAME ++ && this_frame->next->unwind->type != ARCH_FRAME + && frame_id_inner (this_id, get_frame_id (this_frame->next))) + { + if (frame_debug) +@@ -1707,7 +1722,31 @@ safe_frame_unwind_memory (struct frame_i + struct gdbarch * + get_frame_arch (struct frame_info *this_frame) + { +- return current_gdbarch; ++ if (!this_frame->this_arch.p) ++ { ++ struct gdbarch *arch; ++ ++ if (this_frame->unwind == NULL) ++ this_frame->unwind ++ = frame_unwind_find_by_frame (this_frame->next, ++ &this_frame->prologue_cache); ++ ++ if (this_frame->unwind->this_arch != NULL) ++ arch = this_frame->unwind->this_arch (this_frame->next, ++ &this_frame->prologue_cache); ++ else ++ arch = get_frame_arch (this_frame->next); ++ ++ this_frame->this_arch.arch = arch; ++ this_frame->this_arch.p = 1; ++ if (frame_debug) ++ fprintf_unfiltered (gdb_stdlog, ++ "{ get_frame_arch (this_frame=%d) -> %s }\n", ++ this_frame->level, ++ gdbarch_bfd_arch_info (arch)->printable_name); ++ } ++ ++ return this_frame->this_arch.arch; + } + + /* Stack pointer methods. */ +diff -urNp src-orig/gdb/frame.h src/gdb/frame.h +--- src-orig/gdb/frame.h 2007-06-09 15:55:50.000000000 +0200 ++++ src/gdb/frame.h 2007-07-13 21:21:21.739385911 +0200 +@@ -198,6 +198,8 @@ enum frame_type + /* In a signal handler, various OSs handle this in various ways. + The main thing is that the frame may be far from normal. */ + SIGTRAMP_FRAME, ++ /* Fake frame representing a cross-architecture call. */ ++ ARCH_FRAME, + /* Sentinel or registers frame. This frame obtains register values + direct from the inferior's registers. */ + SENTINEL_FRAME +diff -urNp src-orig/gdb/frame-unwind.h src/gdb/frame-unwind.h +--- src-orig/gdb/frame-unwind.h 2007-07-13 21:17:48.005732367 +0200 ++++ src/gdb/frame-unwind.h 2007-07-13 21:04:36.667530122 +0200 +@@ -130,6 +130,13 @@ typedef CORE_ADDR (frame_prev_pc_ftype) + typedef void (frame_dealloc_cache_ftype) (struct frame_info *self, + void *this_cache); + ++/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); ++ use the NEXT frame, and its register unwind method, to return THIS ++ frame's architecture. */ ++ ++typedef struct gdbarch *(frame_this_arch_ftype) (struct frame_info *next_frame, ++ void **this_prologue_cache); ++ + struct frame_unwind + { + /* The frame's type. Should this instead be a collection of +@@ -143,6 +150,7 @@ struct frame_unwind + frame_sniffer_ftype *sniffer; + frame_prev_pc_ftype *prev_pc; + frame_dealloc_cache_ftype *dealloc_cache; ++ frame_this_arch_ftype *this_arch; + }; + + /* Register a frame unwinder, _prepending_ it to the front of the +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-07-13 21:17:48.018730494 +0200 ++++ src/gdb/Makefile.in 2007-07-13 21:18:01.178828182 +0200 +@@ -2691,7 +2691,7 @@ spu-tdep.o: spu-tdep.c $(defs_h) $(arch_ + spu-thread.o: spu-thread.c $(defs_h) $(gdbcore_h) $(gdbcmd_h) $(gdb_string_h) \ + $(gdb_assert_h) $(arch_utils_h) $(observer_h) $(inferior_h) \ + $(regcache_h) $(symfile_h) $(objfiles_h) $(block_h) $(exec_h) \ +- $(ppc_tdep_h) $(spu_tdep_h) ++ $(exceptions_h) $(frame_unwind_h) $(ppc_tdep_h) $(spu_tdep_h) + stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \ + $(symtab_h) $(gdbtypes_h) $(expression_h) $(symfile_h) $(objfiles_h) \ + $(aout_stab_gnu_h) $(libaout_h) $(aout_aout64_h) $(gdb_stabs_h) \ +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-07-13 21:17:48.026729342 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-07-13 21:04:36.689526953 +0200 +@@ -905,6 +905,8 @@ static struct tramp_frame ppc64_linux_si + ppc64_linux_sighandler_cache_init + }; + ++const struct frame_unwind *ppc_linux_extra_unwind = NULL; ++ + static void + ppc_linux_init_abi (struct gdbarch_info info, + struct gdbarch *gdbarch) +@@ -957,6 +959,10 @@ ppc_linux_init_abi (struct gdbarch_info + /* Enable TLS support. */ + set_gdbarch_fetch_tls_load_module_address (gdbarch, + svr4_fetch_objfile_link_map); ++ ++ /* Extra unwinder support. */ ++ if (ppc_linux_extra_unwind) ++ frame_unwind_prepend_unwinder (gdbarch, ppc_linux_extra_unwind); + } + + void +diff -urNp src-orig/gdb/ppc-tdep.h src/gdb/ppc-tdep.h +--- src-orig/gdb/ppc-tdep.h 2007-07-13 21:17:48.031728622 +0200 ++++ src/gdb/ppc-tdep.h 2007-07-13 21:04:36.694526233 +0200 +@@ -68,6 +68,8 @@ enum return_value_convention ppc64_sysv_ + gdb_byte *readbuf, + const gdb_byte *writebuf); + ++extern const struct frame_unwind *ppc_linux_extra_unwind; ++ + /* From rs6000-tdep.c... */ + int altivec_register_p (struct gdbarch *gdbarch, int regno); + int spe_register_p (struct gdbarch *gdbarch, int regno); +diff -urNp src-orig/gdb/regcache.c src/gdb/regcache.c +--- src-orig/gdb/regcache.c 2007-07-13 21:17:48.039727470 +0200 ++++ src/gdb/regcache.c 2007-07-13 21:04:36.701525225 +0200 +@@ -225,6 +225,15 @@ regcache_xmalloc (struct gdbarch *gdbarc + return regcache; + } + ++struct regcache * ++regcache_thread_xmalloc (struct gdbarch *gdbarch, ptid_t ptid) ++{ ++ struct regcache *regcache = regcache_xmalloc (gdbarch); ++ regcache->readonly_p = 0; ++ regcache->ptid = ptid; ++ return regcache; ++} ++ + void + regcache_xfree (struct regcache *regcache) + { +diff -urNp src-orig/gdb/regcache.h src/gdb/regcache.h +--- src-orig/gdb/regcache.h 2007-07-13 21:17:48.044726750 +0200 ++++ src/gdb/regcache.h 2007-07-13 21:04:36.705524649 +0200 +@@ -32,6 +32,7 @@ extern struct regcache *get_thread_regca + void regcache_xfree (struct regcache *regcache); + struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache); + struct regcache *regcache_xmalloc (struct gdbarch *gdbarch); ++struct regcache *regcache_thread_xmalloc (struct gdbarch *gdbarch, ptid_t ptid); + + /* Return REGCACHE's architecture. */ + +diff -urNp src-orig/gdb/sentinel-frame.c src/gdb/sentinel-frame.c +--- src-orig/gdb/sentinel-frame.c 2007-07-13 21:17:48.049726030 +0200 ++++ src/gdb/sentinel-frame.c 2007-07-13 21:04:36.709524072 +0200 +@@ -89,6 +89,14 @@ sentinel_frame_prev_pc (struct frame_inf + return gdbarch_unwind_pc (gdbarch, next_frame); + } + ++static struct gdbarch * ++sentinel_frame_this_arch (struct frame_info *next_frame, ++ void **this_prologue_cache) ++{ ++ struct frame_unwind_cache *cache = *this_prologue_cache; ++ return get_regcache_arch (cache->regcache); ++} ++ + const struct frame_unwind sentinel_frame_unwinder = + { + SENTINEL_FRAME, +@@ -97,6 +105,8 @@ const struct frame_unwind sentinel_frame + NULL, /* unwind_data */ + NULL, /* sniffer */ + sentinel_frame_prev_pc, ++ NULL, /* dealloc_cache */ ++ sentinel_frame_this_arch, + }; + + const struct frame_unwind *const sentinel_frame_unwind = &sentinel_frame_unwinder; +diff -urNp src-orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src-orig/gdb/spu-tdep.c 2007-07-13 21:17:48.058724734 +0200 ++++ src/gdb/spu-tdep.c 2007-07-13 21:04:36.718522776 +0200 +@@ -383,7 +383,8 @@ spu_pointer_to_address (struct type *typ + && !TYPE_ADDRESS_CLASS_1 (type)) /* Pointer to ppe. */ + { + struct frame_info *frame = get_selected_frame (NULL); +- id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch == bfd_arch_spu) ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + } + + return addr? SPUADDR (id, addr) : 0; +@@ -402,7 +403,8 @@ spu_integer_to_address (struct gdbarch * + && type != builtin_type_uint32) + { + struct frame_info *frame = get_selected_frame (NULL); +- id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch == bfd_arch_spu) ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + } + + return SPUADDR (id, addr); +@@ -2161,6 +2163,8 @@ show_spu_stop_on_load (struct ui_file *f + + /* Set up gdbarch struct. */ + ++const struct frame_unwind *spu_extra_unwind = NULL; ++ + static struct gdbarch * + spu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) + { +@@ -2250,6 +2254,10 @@ spu_gdbarch_init (struct gdbarch_info in + /* Overlays. */ + set_gdbarch_overlay_update (gdbarch, spu_overlay_update); + ++ /* Extra unwinder support. */ ++ if (spu_extra_unwind) ++ frame_unwind_prepend_unwinder (gdbarch, spu_extra_unwind); ++ + return gdbarch; + } + +diff -urNp src-orig/gdb/spu-tdep.h src/gdb/spu-tdep.h +--- src-orig/gdb/spu-tdep.h 2007-07-13 21:17:48.062724157 +0200 ++++ src/gdb/spu-tdep.h 2007-07-13 21:04:36.723522056 +0200 +@@ -69,4 +69,6 @@ enum spu_regnum + /* Routines from spu-thread.c. */ + extern int spu_switch_arch (int spu); + ++extern const struct frame_unwind *spu_extra_unwind; ++ + #endif +diff -urNp src-orig/gdb/spu-thread.c src/gdb/spu-thread.c +--- src-orig/gdb/spu-thread.c 2007-07-13 21:17:48.069723149 +0200 ++++ src/gdb/spu-thread.c 2007-07-13 21:30:24.982562065 +0200 +@@ -33,6 +33,8 @@ + #include "objfiles.h" + #include "block.h" + #include "exec.h" ++#include "exceptions.h" ++#include "frame-unwind.h" + + #include "ppc-tdep.h" + #include "spu-tdep.h" +@@ -47,6 +49,10 @@ static int standalone_spufs_fd = 0; + static int spufs_fd = 0; + static CORE_ADDR spufs_addr = 0; + ++/* Cached value of __spe_current_active_context in the current thread. */ ++static CORE_ADDR spe_current_active_context = 0; ++ ++ + /* Find gdbarch for SPU. */ + static struct gdbarch * + spu_gdbarch_spu (void) +@@ -206,6 +212,7 @@ spu_wait (ptid_t ptid, struct target_wai + static void + spu_switch_to_thread (void) + { ++ spe_current_active_context = 0; + spu_detect_arch (inferior_ptid, &spufs_fd, &spufs_addr); + } + +@@ -438,6 +445,315 @@ spu_xfer_partial (struct target_ops *ops + } + + ++/* Retrieve contents of the N'th element in the current thread's ++ linked SPE context list into ID, NPC, and STATUS. Return the ++ address of said context element, or 0 if not found. */ ++static CORE_ADDR ++spu_active_context (int n, int *id, unsigned int *npc, unsigned int *status) ++{ ++ CORE_ADDR context_addr; ++ gdb_byte buf[16]; ++ int prev_arch; ++ int word_size; ++ int i; ++ ++ /* Switch to PPC arch while accessing target memory. */ ++ prev_arch = spu_switch_arch (0); ++ word_size = gdbarch_addr_bit (current_gdbarch) / 8; ++ ++ /* Look up value of thread-local __spe_current_active_context variable. */ ++ if (!spe_current_active_context) ++ { ++ struct objfile *objfile = NULL; ++ struct minimal_symbol *sym = NULL; ++ ++ ALL_OBJFILES (objfile) ++ { ++ sym = lookup_minimal_symbol ("__spe_current_active_context", ++ NULL, objfile); ++ if (sym) ++ break; ++ } ++ ++ if (objfile && objfile->separate_debug_objfile_backlink) ++ objfile = objfile->separate_debug_objfile_backlink; ++ ++ if (sym) ++ { ++ volatile struct gdb_exception e; ++ TRY_CATCH (e, RETURN_MASK_ERROR) ++ { ++ CORE_ADDR sym_addr; ++ sym_addr = SYMBOL_VALUE_ADDRESS (sym); ++ sym_addr = target_translate_tls_address (objfile, sym_addr); ++ if (target_read_memory (sym_addr, buf, word_size) == 0) ++ spe_current_active_context ++ = extract_unsigned_integer (buf, word_size); ++ } ++ } ++ } ++ ++ /* Cyle through to N'th linked list element. */ ++ context_addr = spe_current_active_context; ++ for (i = 0; i < n && context_addr; i++) ++ if (target_read_memory (context_addr + align_up (12, word_size), ++ buf, word_size) == 0) ++ context_addr = extract_unsigned_integer (buf, word_size); ++ else ++ context_addr = 0; ++ ++ /* Read current context. */ ++ if (context_addr ++ && target_read_memory (context_addr, buf, 12) != 0) ++ context_addr = 0; ++ ++ /* Switch back to previous architecture. */ ++ spu_switch_arch (prev_arch); ++ ++ /* Extract data elements. */ ++ if (context_addr) ++ { ++ if (id) ++ *id = extract_signed_integer (buf, 4); ++ if (npc) ++ *npc = extract_unsigned_integer (buf + 4, 4); ++ if (status) ++ *status = extract_unsigned_integer (buf + 8, 4); ++ } ++ ++ return context_addr; ++} ++ ++ ++/* PPU architecture sniffer to switch to SPU. */ ++ ++struct ppu2spu_cache ++{ ++ struct frame_id frame_id; ++ int id; ++ unsigned int npc; ++ gdb_byte gprs[128*16]; ++}; ++ ++static struct gdbarch * ++ppu2spu_this_arch (struct frame_info *next_frame, void **this_prologue_cache) ++{ ++ return spu_gdbarch_spu (); ++} ++ ++static void ++ppu2spu_this_id (struct frame_info *next_frame, ++ void **this_cache, struct frame_id *this_id) ++{ ++ struct ppu2spu_cache *cache = *this_cache; ++ *this_id = cache->frame_id; ++} ++ ++static void ++ppu2spu_prev_register (struct frame_info *next_frame, void **this_cache, ++ int regnum, int *optimizedp, enum lval_type *lvalp, ++ CORE_ADDR *addrp, int *realnump, gdb_byte *valuep) ++{ ++ struct ppu2spu_cache *cache = *this_cache; ++ ++ *optimizedp = 0; ++ *lvalp = not_lval; ++ *addrp = 0; ++ *realnump = -1; ++ ++ if (!valuep) ++ return; ++ ++ if (regnum == SPU_ID_REGNUM) ++ store_unsigned_integer (valuep, 4, cache->id); ++ ++ else if (regnum == SPU_PC_REGNUM) ++ store_unsigned_integer (valuep, 4, cache->npc); ++ ++ else if (regnum == SPU_SP_REGNUM) ++ memcpy (valuep, cache->gprs + 16*SPU_RAW_SP_REGNUM, 4); ++ ++ else if (regnum >= 0 && regnum < SPU_NUM_GPRS) ++ memcpy (valuep, cache->gprs + 16*regnum, 16); ++ ++ else ++ internal_error (__FILE__, __LINE__, ++ "ppu2spu_prev_register: unexpected regnum"); ++} ++ ++static int ++ppu2spu_sniffer (const struct frame_unwind *self, ++ struct frame_info *next_frame, void **this_prologue_cache) ++{ ++ struct frame_info *fi; ++ struct gdbarch *arch = get_frame_arch (next_frame); ++ CORE_ADDR base, func, backchain, context_addr; ++ int n = 0; ++ int id = -1; ++ unsigned int npc = 0; ++ ++ /* Count the number of SPU contexts already in the frame chain. */ ++ for (fi = get_next_frame (next_frame); fi; fi = get_next_frame (fi)) ++ if (get_frame_arch (fi) != get_frame_arch (get_prev_frame (fi)) ++ && gdbarch_bfd_arch_info (get_frame_arch (fi))->arch == bfd_arch_spu) ++ n++; ++ ++ base = frame_sp_unwind (next_frame); ++ func = frame_pc_unwind (next_frame); ++ backchain = read_memory_unsigned_integer (base, gdbarch_addr_bit (arch) / 8); ++ ++ context_addr = spu_active_context (n, &id, &npc, NULL); ++ if (base <= context_addr && context_addr < backchain) ++ { ++ char annex[32]; ++ ++ struct ppu2spu_cache *cache ++ = FRAME_OBSTACK_CALLOC (1, struct ppu2spu_cache); ++ ++ cache->frame_id = frame_id_build (base, func); ++ cache->id = id; ++ cache->npc = npc; ++ ++ xsnprintf (annex, sizeof annex, "%d/regs", cache->id); ++ if (target_read (¤t_target, TARGET_OBJECT_SPU, annex, ++ cache->gprs, 0, sizeof cache->gprs) ++ == sizeof cache->gprs) ++ { ++ *this_prologue_cache = cache; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct frame_unwind ppu2spu_unwind = { ++ ARCH_FRAME, ++ ppu2spu_this_id, ++ ppu2spu_prev_register, ++ NULL, ++ ppu2spu_sniffer, ++ NULL, ++ NULL, ++ ppu2spu_this_arch, ++}; ++ ++ ++/* SPU architecture sniffer to switch to PPU. */ ++ ++struct spu2ppu_cache ++{ ++ struct frame_id frame_id; ++ struct regcache *regcache; ++}; ++ ++static struct gdbarch * ++spu2ppu_this_arch (struct frame_info *next_frame, void **this_prologue_cache) ++{ ++ return spu_gdbarch_ppu (); ++} ++ ++static void ++spu2ppu_this_id (struct frame_info *next_frame, ++ void **this_cache, struct frame_id *this_id) ++{ ++ struct spu2ppu_cache *cache = *this_cache; ++ *this_id = cache->frame_id; ++} ++ ++static void ++spu2ppu_prev_register (struct frame_info *next_frame, void **this_cache, ++ int regnum, int *optimizedp, enum lval_type *lvalp, ++ CORE_ADDR *addrp, int *realnump, gdb_byte *valuep) ++{ ++ struct spu2ppu_cache *cache = *this_cache; ++ ++ *optimizedp = 0; ++ *lvalp = not_lval; ++ *addrp = 0; ++ *realnump = -1; ++ ++ if (valuep) ++ regcache_cooked_read (cache->regcache, regnum, valuep); ++} ++ ++static int ++spu2ppu_unwind_register (void *src, int regnum, gdb_byte *buf) ++{ ++ frame_unwind_register (src, regnum, buf); ++ return 1; ++} ++ ++static int ++spu2ppu_sniffer (const struct frame_unwind *self, ++ struct frame_info *next_frame, void **this_prologue_cache) ++{ ++ struct gdbarch *arch = get_frame_arch (next_frame); ++ CORE_ADDR base, func, backchain; ++ ++ base = frame_sp_unwind (next_frame); ++ func = frame_pc_unwind (next_frame); ++ backchain = read_memory_unsigned_integer (base, 4); ++ ++ if (!backchain) ++ { ++ struct frame_info *fi; ++ ++ struct spu2ppu_cache *cache ++ = FRAME_OBSTACK_CALLOC (1, struct spu2ppu_cache); ++ ++ cache->frame_id = frame_id_build (base, func); ++ ++ for (fi = next_frame; fi; fi = get_next_frame (fi)) ++ if (get_frame_arch (fi) != arch) ++ break; ++ ++ if (fi) ++ { ++ struct regcache *regcache = regcache_xmalloc (get_frame_arch (fi)); ++ struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache); ++ regcache_save (regcache, spu2ppu_unwind_register, fi); ++ discard_cleanups (cleanups); ++ ++ cache->regcache = regcache; ++ *this_prologue_cache = cache; ++ return 1; ++ } ++ else ++ { ++ struct regcache *regcache = regcache_thread_xmalloc ++ (spu_gdbarch_ppu (), inferior_ptid); ++ struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache); ++ cache->regcache = regcache_dup (regcache); ++ do_cleanups (cleanups); ++ ++ *this_prologue_cache = cache; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++void ++spu2ppu_dealloc_cache (struct frame_info *self, void *this_cache) ++{ ++ struct spu2ppu_cache *cache = this_cache; ++ regcache_xfree (cache->regcache); ++} ++ ++static const struct frame_unwind spu2ppu_unwind = { ++ ARCH_FRAME, ++ spu2ppu_this_id, ++ spu2ppu_prev_register, ++ NULL, ++ spu2ppu_sniffer, ++ NULL, ++ spu2ppu_dealloc_cache, ++ spu2ppu_this_arch, ++}; ++ ++ + /* Initialize the SPU thread target. */ + + static void +@@ -472,5 +788,9 @@ _initialize_spu_nat (void) + + /* FIXME: Add ourselves to detach hook. */ + deprecated_detach_hook = spu_detach_hook; ++ ++ /* Install mixed PPE/SPE frame support. */ ++ ppc_linux_extra_unwind = &ppu2spu_unwind; ++ spu_extra_unwind = &spu2ppu_unwind; + } + +diff -urNp src-orig/gdb/stack.c src/gdb/stack.c +--- src-orig/gdb/stack.c 2007-07-13 21:17:48.078721853 +0200 ++++ src/gdb/stack.c 2007-07-13 21:23:44.471497951 +0200 +@@ -70,6 +70,21 @@ static void print_frame (struct frame_in + int annotation_level = 0; + + ++static void ++do_switch_current_gdbarch_cleanup (void *arg) ++{ ++ current_gdbarch = arg; ++} ++ ++static struct cleanup * ++make_cleanup_switch_current_gdbarch (struct frame_info *frame) ++{ ++ struct gdbarch *old_gdbarch = current_gdbarch; ++ current_gdbarch = get_frame_arch (frame); ++ return make_cleanup (do_switch_current_gdbarch_cleanup, old_gdbarch); ++} ++ ++ + struct print_stack_frame_args + { + struct frame_info *frame; +@@ -102,6 +117,7 @@ print_stack_frame (struct frame_info *fr + enum print_what print_what) + { + struct print_stack_frame_args args; ++ struct cleanup *old_chain = make_cleanup_switch_current_gdbarch (frame); + + args.frame = frame; + args.print_level = print_level; +@@ -111,6 +127,7 @@ print_stack_frame (struct frame_info *fr + args.print_args = 1; + + catch_errors (print_stack_frame_stub, &args, "", RETURN_MASK_ALL); ++ do_cleanups (old_chain); + } + + struct print_args_args +@@ -175,6 +192,7 @@ print_frame_args (struct symbol *func, s + + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); ++ make_cleanup_switch_current_gdbarch (frame); + + if (func) + { +@@ -407,7 +425,8 @@ print_frame_info (struct frame_info *fra + int location_print; + + if (get_frame_type (frame) == DUMMY_FRAME +- || get_frame_type (frame) == SIGTRAMP_FRAME) ++ || get_frame_type (frame) == SIGTRAMP_FRAME ++ || get_frame_type (frame) == ARCH_FRAME) + { + struct cleanup *uiout_cleanup + = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); +@@ -440,6 +459,10 @@ print_frame_info (struct frame_info *fra + annotate_signal_handler_caller (); + ui_out_field_string (uiout, "func", ""); + } ++ else if (get_frame_type (frame) == ARCH_FRAME) ++ { ++ ui_out_field_string (uiout, "func", ""); ++ } + ui_out_text (uiout, "\n"); + annotate_frame_end (); + +@@ -1382,6 +1405,7 @@ static void + print_frame_local_vars (struct frame_info *frame, int num_tabs, + struct ui_file *stream) + { ++ struct cleanup *old_chain; + struct block *block = get_frame_block (frame, 0); + int values_printed = 0; + +@@ -1391,6 +1415,8 @@ print_frame_local_vars (struct frame_inf + return; + } + ++ old_chain = make_cleanup_switch_current_gdbarch (frame); ++ + while (block) + { + if (print_block_frame_locals (block, frame, num_tabs, stream)) +@@ -1404,6 +1430,8 @@ print_frame_local_vars (struct frame_inf + + if (!values_printed) + fprintf_filtered (stream, _("No locals.\n")); ++ ++ do_cleanups (old_chain); + } + + /* Same, but print labels. */ --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-ppc-longdoublefix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-ppc-longdoublefix @@ -0,0 +1,20 @@ +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-06-25 21:38:36.813757479 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-06-25 21:39:24.390223812 +0200 +@@ -931,16 +931,6 @@ ppc_linux_init_abi (struct gdbarch_info + { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + +- /* NOTE: jimb/2004-03-26: The System V ABI PowerPC Processor +- Supplement says that long doubles are sixteen bytes long. +- However, as one of the known warts of its ABI, PPC GNU/Linux uses +- eight-byte long doubles. GCC only recently got 128-bit long +- double support on PPC, so it may be changing soon. The +- Linux[sic] Standards Base says that programs that use 'long +- double' on PPC GNU/Linux are non-conformant. */ +- /* NOTE: cagney/2005-01-25: True for both 32- and 64-bit. */ +- set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); +- + /* Handle PPC GNU/Linux 64-bit function pointers (which are really + function descriptors) and 32-bit secure PLT entries. */ + set_gdbarch_convert_from_func_ptr_addr --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-overlay +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-overlay @@ -0,0 +1,33 @@ +diff -urNp src-orig/gdb/breakpoint.c src/gdb/breakpoint.c +--- src-orig/gdb/breakpoint.c 2007-06-13 19:59:50.000000000 +0200 ++++ src/gdb/breakpoint.c 2007-06-25 21:50:01.857276676 +0200 +@@ -4324,12 +4324,12 @@ disable_longjmp_breakpoint (void) + } + + static void +-create_overlay_event_breakpoint (char *func_name) ++create_overlay_event_breakpoint_1 (char *func_name, struct objfile *objfile) + { + struct breakpoint *b; + struct minimal_symbol *m; + +- if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL) ++ if ((m = lookup_minimal_symbol_text (func_name, objfile)) == NULL) + return; + + b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), +@@ -4348,6 +4348,14 @@ create_overlay_event_breakpoint (char *f + } + } + ++static void ++create_overlay_event_breakpoint (char *func_name) ++{ ++ struct objfile *objfile; ++ ALL_OBJFILES (objfile) ++ create_overlay_event_breakpoint_1 (func_name, objfile); ++} ++ + void + enable_overlay_breakpoints (void) + { --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/series +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/series @@ -0,0 +1,45 @@ +# These are shared between spu-gdb and ppu-gdb +# 1: in mainline +diff-spu-gdb-regformatfix -p0 + +# 2..3: under discussion +diff-spu-gdb-fix-fortran_registers -p0 +diff-spu-ext-mi -p0 + +# Combined debugger patches start at 100 +# 100..102: ppc-only changes +diff-gdb-ppc-fptrfix -p0 +diff-gdb-ppc-msymfix -p0 +diff-gdb-ppc-longdoublefix -p0 + +# 103: under discussion +diff-gdb-corewrite -p0 + +# 104..119: t.b.d. +diff-gdb-ppcorigr3 -p0 +diff-gdb-ppc-morefixes -p0 +diff-gdb-prepareproceed -p0 +diff-gdb-switchtothread -p0 +diff-gdb-solib-alignfix -p0 +diff-gdb-solib-multiple -p0 +diff-gdb-solib-openbfd -p0 +diff-gdb-solib-auxv -p0 +diff-combined-gdb -p0 +diff-combined-gdb-address -p0 +diff-combined-gdb-linuxfix -p0 +diff-combined-gdb-infrunfix -p0 +diff-combined-gdb-skipprologue -p0 +diff-combined-gdb-gdbserver -p0 +diff-combined-gdb-core -p0 +diff-combined-gdb-core-bfd -p0 +diff-combined-gdb-overlay -p0 +diff-combined-gdb-ea-ptr -p0 +diff-combined-gdb-currarch -p0 +diff-combined-gdb-frame -p0 +diff-combined-gdb-ea-cache -p0 +diff-combined-testsuite -p0 +diff-dejagnu-config -p0 +diff-combined-gdb-pr36764 -p0 +diff-wrap-spu-addr -p0 +diff-fix-gdbsrv-dejagnu -p0 +diff-combined-gdb-pr37807 -p0 --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-spu-ext-mi +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-spu-ext-mi @@ -0,0 +1,15 @@ +diff -urNp src-orig/gdb/mi/mi-cmds.c src/gdb/mi/mi-cmds.c +--- src-orig/gdb/mi/mi-cmds.c 2007-04-14 11:51:29.000000000 +0200 ++++ src/gdb/mi/mi-cmds.c 2007-06-25 21:37:23.172186121 +0200 +@@ -100,6 +100,11 @@ struct mi_cmd mi_cmds[] = + { "signal-handle", { NULL, 0 }, NULL, NULL }, + { "signal-list-handle-actions", { NULL, 0 }, NULL, NULL }, + { "signal-list-signal-types", { NULL, 0 }, NULL, NULL }, ++ { "spu-info-event", { "info spu event", 0 }, NULL, NULL }, ++ { "spu-info-signal", { "info spu signal", 0 }, NULL, NULL }, ++ { "spu-info-mailbox", { "info spu mailbox", 0 }, NULL, NULL }, ++ { "spu-info-dma", { "info spu dma", 0 }, NULL, NULL }, ++ { "spu-info-proxydma", { "info spu proxydma", 0 }, NULL, NULL }, + { "stack-info-depth", { NULL, 0 }, 0, mi_cmd_stack_info_depth}, + { "stack-info-frame", { NULL, 0 }, 0, mi_cmd_stack_info_frame}, + { "stack-list-arguments", { NULL, 0 }, 0, mi_cmd_stack_list_args}, --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-fix-gdbsrv-dejagnu +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-fix-gdbsrv-dejagnu @@ -0,0 +1,32 @@ +diff -urpN src-orig/gdb/testsuite/lib/gdbserver-support.exp src/gdb/testsuite/lib/gdbserver-support.exp +--- src-orig/gdb/testsuite/lib/gdbserver-support.exp 2007-05-23 14:41:12.000000000 +0200 ++++ src/gdb/testsuite/lib/gdbserver-support.exp 2007-08-17 19:28:49.000000000 +0200 +@@ -179,10 +179,10 @@ proc gdbserver_spawn { child_args } { + } + + # Extract the local and remote host ids from the target board struct. +- if [target_info exists sockethost] { +- set debughost [target_info sockethost] ++ if [target_info exists gdb,sockethost] { ++ set debughost [target_info gdb,sockethost] + } else { +- set debughost "localhost:" ++ set debughost "localhost" + } + + # Extract the protocol +@@ -195,12 +195,12 @@ proc gdbserver_spawn { child_args } { + set gdbserver [find_gdbserver] + + # Export the host:port pair. +- set gdbport $debughost$portnum ++ set gdbport $debughost:$portnum + + # Fire off the debug agent. This flavour of gdbserver takes as + # arguments the port information, the name of the executable file to + # be debugged, and any arguments. +- set gdbserver_command "$gdbserver :$portnum $gdbserver_server_exec" ++ set gdbserver_command "$gdbserver $gdbport $gdbserver_server_exec" + if { $child_args != "" } { + append gdbserver_command " $child_args" + } --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-linuxfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-linuxfix @@ -0,0 +1,54 @@ +diff -urNp src-orig/gdb/linux-nat.c src/gdb/linux-nat.c +--- src-orig/gdb/linux-nat.c 2007-06-25 21:46:18.677493094 +0200 ++++ src/gdb/linux-nat.c 2007-06-25 21:46:55.156695077 +0200 +@@ -1771,24 +1771,35 @@ cancel_breakpoints_callback (struct lwp_ + tripped on it. */ + + if (lp->status != 0 +- && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP +- && breakpoint_inserted_here_p (read_pc_pid (lp->ptid) - +- gdbarch_decr_pc_after_break +- (current_gdbarch))) ++ && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP) + { +- if (debug_linux_nat) +- fprintf_unfiltered (gdb_stdlog, +- "CBC: Push back breakpoint for %s\n", +- target_pid_to_str (lp->ptid)); ++ int decr_pc_after_break; ++ CORE_ADDR break_pc; + +- /* Back up the PC if necessary. */ +- if (gdbarch_decr_pc_after_break (current_gdbarch)) +- write_pc_pid (read_pc_pid (lp->ptid) - gdbarch_decr_pc_after_break +- (current_gdbarch), +- lp->ptid); ++ struct gdbarch *saved_gdbarch = current_gdbarch; ++ ptid_t saved_ptid = inferior_ptid; ++ switch_to_thread (lp->ptid); + +- /* Throw away the SIGTRAP. */ +- lp->status = 0; ++ decr_pc_after_break = gdbarch_decr_pc_after_break (current_gdbarch); ++ break_pc = read_pc_pid (lp->ptid) - decr_pc_after_break; ++ ++ if (breakpoint_inserted_here_p (break_pc)) ++ { ++ if (debug_linux_nat) ++ fprintf_unfiltered (gdb_stdlog, ++ "CBC: Push back breakpoint for %s\n", ++ target_pid_to_str (lp->ptid)); ++ ++ /* Back up the PC if necessary. */ ++ if (decr_pc_after_break) ++ write_pc_pid (break_pc, lp->ptid); ++ ++ /* Throw away the SIGTRAP. */ ++ lp->status = 0; ++ } ++ ++ inferior_ptid = saved_ptid; ++ deprecated_current_gdbarch_select_hack (saved_gdbarch); + } + + return 0; --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-switchtothread +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-switchtothread @@ -0,0 +1,80 @@ +diff -urNp src-orig/gdb/target.c src/gdb/target.c +--- src-orig/gdb/target.c 2007-06-09 15:42:16.000000000 +0200 ++++ src/gdb/target.c 2007-08-01 20:33:40.382820644 +0200 +@@ -466,6 +466,7 @@ update_current_target (void) + INHERIT (to_find_memory_regions, t); + INHERIT (to_make_corefile_notes, t); + INHERIT (to_get_thread_local_address, t); ++ INHERIT (to_switch_to_thread, t); + /* Do not inherit to_read_description. */ + INHERIT (to_magic, t); + /* Do not inherit to_memory_map. */ +@@ -644,6 +645,9 @@ update_current_target (void) + de_fault (to_async, + (void (*) (void (*) (enum inferior_event_type, void*), void*)) + tcomplain); ++ de_fault (to_switch_to_thread, ++ (void (*) (void)) ++ target_ignore); + current_target.to_read_description = NULL; + #undef de_fault + +@@ -2643,6 +2647,14 @@ debug_to_find_new_threads (void) + } + + static void ++debug_to_switch_to_thread (void) ++{ ++ debug_target.to_switch_to_thread (); ++ ++ fputs_unfiltered ("target_switch_to_thread ()\n", gdb_stdlog); ++} ++ ++static void + debug_to_stop (void) + { + debug_target.to_stop (); +@@ -2748,6 +2760,7 @@ setup_target_debug (void) + current_target.to_enable_exception_callback = debug_to_enable_exception_callback; + current_target.to_get_current_exception_event = debug_to_get_current_exception_event; + current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file; ++ current_target.to_switch_to_thread = debug_to_switch_to_thread; + } + + +diff -urNp src-orig/gdb/target.h src/gdb/target.h +--- src-orig/gdb/target.h 2007-06-12 16:35:25.000000000 +0200 ++++ src/gdb/target.h 2007-08-01 20:33:40.426814327 +0200 +@@ -503,6 +503,9 @@ struct target_ops + was available. */ + const struct target_desc *(*to_read_description) (struct target_ops *ops); + ++ /* Target-specific thread switch callback. */ ++ void (*to_switch_to_thread) (void); ++ + int to_magic; + /* Need sub-structure for target machine related rather than comm related? + */ +@@ -1029,6 +1032,11 @@ extern char *normal_pid_to_str (ptid_t p + #define target_pid_to_exec_file(pid) \ + (current_target.to_pid_to_exec_file) (pid) + ++/* Perform target-specific thread-switch actions. */ ++ ++#define target_switch_to_thread() \ ++ (current_target.to_switch_to_thread ()) ++ + /* + * Iterator function for target memory regions. + * Calls a callback function once for each memory region 'mapped' +diff -urNp src-orig/gdb/thread.c src/gdb/thread.c +--- src-orig/gdb/thread.c 2007-08-01 20:32:26.833210198 +0200 ++++ src/gdb/thread.c 2007-08-01 20:33:40.479806718 +0200 +@@ -461,6 +461,7 @@ switch_to_thread (ptid_t ptid) + + inferior_ptid = ptid; + reinit_frame_cache (); ++ target_switch_to_thread (); + registers_changed (); + stop_pc = read_pc (); + } --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-wrap-spu-addr +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-wrap-spu-addr @@ -0,0 +1,51 @@ +diff -urpN src.orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src.orig/gdb/spu-tdep.c 2007-08-09 08:56:05.420156000 +0200 ++++ src/gdb/spu-tdep.c 2007-08-09 10:09:53.697033167 +0200 +@@ -377,6 +377,7 @@ static CORE_ADDR + spu_pointer_to_address (struct type *type, const gdb_byte *buf) + { + ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); ++ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */ + ULONGEST id = 0; + + if (target_has_registers && target_has_stack && target_has_memory +@@ -384,10 +385,13 @@ spu_pointer_to_address (struct type *typ + { + struct frame_info *frame = get_selected_frame (NULL); + if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch == bfd_arch_spu) +- id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ { ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ lslr = get_frame_register_unsigned (frame, SPU_LSLR_REGNUM); ++ } + } + +- return addr? SPUADDR (id, addr) : 0; ++ return addr? SPUADDR (id, addr & lslr) : 0; + } + + static CORE_ADDR +@@ -395,6 +399,7 @@ spu_integer_to_address (struct gdbarch * + struct type *type, const gdb_byte *buf) + { + ULONGEST addr = unpack_long (type, buf); ++ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */ + ULONGEST id = 0; + + if (target_has_registers && target_has_stack && target_has_memory +@@ -404,10 +409,13 @@ spu_integer_to_address (struct gdbarch * + { + struct frame_info *frame = get_selected_frame (NULL); + if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch == bfd_arch_spu) +- id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ { ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ lslr = get_frame_register_unsigned (frame, SPU_LSLR_REGNUM); ++ } + } + +- return SPUADDR (id, addr); ++ return SPUADDR (id, addr & lslr); + } + + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-ea-cache +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-ea-cache @@ -0,0 +1,126 @@ +diff -urN src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-07-04 07:45:22.147201000 +0200 ++++ src/gdb/Makefile.in 2007-07-04 08:37:58.252089562 +0200 +@@ -2691,7 +2691,8 @@ + spu-thread.o: spu-thread.c $(defs_h) $(gdbcore_h) $(gdbcmd_h) $(gdb_string_h) \ + $(gdb_assert_h) $(arch_utils_h) $(observer_h) $(inferior_h) \ + $(regcache_h) $(symfile_h) $(objfiles_h) $(block_h) $(exec_h) \ +- $(exceptions_h) $(frame_unwind_h) $(ppc_tdep_h) $(spu_tdep_h) ++ $(exceptions_h) $(frame_unwind_h) $(ppc_tdep_h) $(spu_tdep_h) \ ++ $(infcall_h) $(value_h) $(symtab_h) + stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \ + $(symtab_h) $(gdbtypes_h) $(expression_h) $(symfile_h) $(objfiles_h) \ + $(aout_stab_gnu_h) $(libaout_h) $(aout_aout64_h) $(gdb_stabs_h) \ +diff -urN src-orig/gdb/spu-thread.c src/gdb/spu-thread.c +--- src-orig/gdb/spu-thread.c 2007-07-04 07:45:22.224323000 +0200 ++++ src/gdb/spu-thread.c 2007-07-04 08:48:41.685991856 +0200 +@@ -35,6 +35,9 @@ + #include "exec.h" + #include "exceptions.h" + #include "frame-unwind.h" ++#include "infcall.h" ++#include "value.h" ++#include "symtab.h" + + #include "ppc-tdep.h" + #include "spu-tdep.h" +@@ -52,7 +55,6 @@ + /* Cached value of __spe_current_active_context in the current thread. */ + static CORE_ADDR spe_current_active_context = 0; + +- + /* Find gdbarch for SPU. */ + static struct gdbarch * + spu_gdbarch_spu (void) +@@ -525,6 +527,81 @@ + } + + ++/* Lookup OBJFILE corresponding to the current SPU context. */ ++ ++static struct objfile * ++spu_objfile_from_context (void) ++{ ++ struct objfile *obj; ++ struct frame_info *frame = get_current_frame (); ++ int fd = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ ++ ALL_OBJFILES (obj) ++ { ++ if (obj->sections ++ && SPUADDR_SPU (obj->sections->addr) == fd) ++ return obj; ++ } ++ ++ return NULL; ++} ++ ++ ++/* Flush cache for ea pointer access if available and return 1. Return 0 if ++ inferior call was not executed. */ ++ ++static void ++flush_ea_cache (void) ++{ ++ struct value *ea_flush_fn = NULL; ++ struct minimal_symbol *msymbol; ++ struct objfile *obj; ++ ++ obj = spu_objfile_from_context (); ++ if (obj == NULL) ++ return; ++ ++ /* Lookup inferior function __cache_flush. */ ++ msymbol = lookup_minimal_symbol ("__cache_flush", NULL, obj); ++ if (msymbol != NULL) ++ { ++ struct type *type; ++ CORE_ADDR addr; ++ ++ type = lookup_pointer_type (builtin_type_char); ++ type = lookup_function_type (type); ++ type = lookup_pointer_type (type); ++ addr = SYMBOL_VALUE_ADDRESS (msymbol); ++ ea_flush_fn = value_from_pointer (type, addr); ++ } ++ ++ if (ea_flush_fn) ++ call_function_by_hand (ea_flush_fn, 0, NULL); ++} ++ ++ ++/* This handler is called when the inferior has stopped. If it is stopped in ++ SPU architecture then flush the ea cache if used. */ ++ ++static void ++spu_attach_normal_stop (struct bpstats *bs) ++{ ++ static int spu_flush_flag = 0; ++ ++ if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_spu) ++ return; ++ ++ /* After an inferior call this callback is called again. This flag is used ++ to prevent recursive cache flushes. */ ++ if (spu_flush_flag) ++ return; ++ ++ spu_flush_flag = 1; ++ flush_ea_cache (); ++ spu_flush_flag = 0; ++} ++ ++ + /* PPU architecture sniffer to switch to SPU. */ + + struct ppu2spu_cache +@@ -786,6 +863,9 @@ + /* Attach to inferior_created observer. */ + observer_attach_inferior_created (spu_inferior_created); + ++ /* Add ourselves to normal_stop event chain. */ ++ observer_attach_normal_stop (spu_attach_normal_stop); ++ + /* FIXME: Add ourselves to detach hook. */ + deprecated_detach_hook = spu_detach_hook; + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-solib-openbfd +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-solib-openbfd @@ -0,0 +1,210 @@ +diff -urNp src-orig/gdb/solib.c src/gdb/solib.c +--- src-orig/gdb/solib.c 2007-06-25 21:43:47.016316085 +0200 ++++ src/gdb/solib.c 2007-06-25 21:44:02.567338117 +0200 +@@ -229,24 +229,22 @@ solib_open (char *in_pathname, char **fo + return found_file; + } + +- + /* + +- LOCAL FUNCTION ++ GLOBAL FUNCTION + +- solib_map_sections -- open bfd and build sections for shared lib ++ solib_open_bfd -- Open BFD for shared library file. + + SYNOPSIS + +- static int solib_map_sections (struct so_list *so) ++ struct bfd *solib_open (char *pathname, int already_resolved); + + DESCRIPTION + +- Given a pointer to one of the shared objects in our list +- of mapped objects, use the recorded name to open a bfd +- descriptor for the object, build a section table, and then +- relocate all the section addresses by the base address at +- which the shared object was mapped. ++ Find and open shared library object identified by PATHNAME, ++ and return a BFD pointer for it. If ALREADY_RESOLVED is true, ++ the pathname has already been fully resolved by an earlier ++ call to this function. + + FIXMES + +@@ -255,20 +253,23 @@ solib_open (char *in_pathname, char **fo + cases where it isn't, do we really mimic the systems search + mechanism correctly in the below code (particularly the tilde + expansion stuff?). ++ + */ + +-static int +-solib_map_sections (void *arg) ++struct bfd * ++solib_open_bfd (char *pathname, int already_resolved) + { +- struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */ + char *filename; + char *scratch_pathname; + int scratch_chan; +- struct section_table *p; + struct cleanup *old_chain; + bfd *abfd; + +- filename = tilde_expand (so->so_name); ++ /* If we've got an already-resolved name, just call symfile_bfd_open. */ ++ if (already_resolved) ++ return symfile_bfd_open (pathname); ++ ++ filename = tilde_expand (pathname); + + old_chain = make_cleanup (xfree, filename); + scratch_chan = solib_open (filename, &scratch_pathname); +@@ -288,30 +289,69 @@ solib_map_sections (void *arg) + } + + /* Leave bfd open, core_xfer_memory and "info files" need it. */ +- so->abfd = abfd; + bfd_set_cacheable (abfd, 1); + +- /* copy full path name into so_name, so that later symbol_file_add +- can find it */ +- if (strlen (scratch_pathname) >= SO_NAME_MAX_PATH_SIZE) +- error (_("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure.")); +- strcpy (so->so_name, scratch_pathname); +- + if (!bfd_check_format (abfd, bfd_object)) + { + error (_("\"%s\": not in executable format: %s."), + scratch_pathname, bfd_errmsg (bfd_get_error ())); + } +- if (build_section_table (abfd, &so->sections, &so->sections_end)) ++ ++ /* Free the file names, close the file now. */ ++ do_cleanups (old_chain); ++ ++ return abfd; ++} ++ ++/* ++ ++ LOCAL FUNCTION ++ ++ solib_map_sections -- open bfd and build sections for shared lib ++ ++ SYNOPSIS ++ ++ static int solib_map_sections (struct so_list *so) ++ ++ DESCRIPTION ++ ++ Given a pointer to one of the shared objects in our list ++ of mapped objects, use the recorded name to open a bfd ++ descriptor for the object, build a section table, and then ++ relocate all the section addresses by the base address at ++ which the shared object was mapped. ++ ++ */ ++ ++static int ++solib_map_sections (void *arg) ++{ ++ struct target_so_ops *ops = solib_ops (current_gdbarch); ++ struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */ ++ struct section_table *p; ++ char *pathname; ++ ++ /* Open the BFD. */ ++ if (ops->open_bfd) ++ so->abfd = ops->open_bfd (so->so_name, 0); ++ else ++ so->abfd = solib_open_bfd (so->so_name, 0); ++ ++ /* Copy full path name into so_name, so that later symbol_file_add ++ can find it. */ ++ pathname = bfd_get_filename (so->abfd); ++ if (strlen (pathname) >= SO_NAME_MAX_PATH_SIZE) ++ error (_("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure.")); ++ strcpy (so->so_name, pathname); ++ ++ if (build_section_table (so->abfd, &so->sections, &so->sections_end)) + { + error (_("Can't find the file sections in `%s': %s"), +- bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ())); ++ pathname, bfd_errmsg (bfd_get_error ())); + } + + for (p = so->sections; p < so->sections_end; p++) + { +- struct target_so_ops *ops = solib_ops (current_gdbarch); +- + /* Relocate the section binding addresses as recorded in the shared + object's file by the base address to which the object was actually + mapped. */ +@@ -322,9 +362,6 @@ solib_map_sections (void *arg) + } + } + +- /* Free the file names, close the file now. */ +- do_cleanups (old_chain); +- + return (1); + } + +@@ -388,8 +425,10 @@ master_so_list (void) + static int + symbol_add_stub (void *arg) + { ++ struct target_so_ops *ops = solib_ops (current_gdbarch); + struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */ + struct section_addr_info *sap; ++ struct bfd *abfd; + + /* Have we already loaded this shared object? */ + ALL_OBJFILES (so->objfile) +@@ -398,11 +437,17 @@ symbol_add_stub (void *arg) + return 1; + } + ++ /* Open a second BFD for this file. */ ++ if (ops->open_bfd) ++ abfd = ops->open_bfd (so->so_name, 1); ++ else ++ abfd = solib_open_bfd (so->so_name, 1); ++ + sap = build_section_addr_info_from_section_table (so->sections, + so->sections_end); + +- so->objfile = symbol_file_add (so->so_name, so->from_tty, +- sap, 0, OBJF_SHARED); ++ so->objfile = symbol_file_add_from_bfd (abfd, so->from_tty, ++ sap, 0, OBJF_SHARED); + free_section_addr_info (sap); + + return (1); +diff -urNp src-orig/gdb/solist.h src/gdb/solist.h +--- src-orig/gdb/solist.h 2007-06-25 21:43:47.066308891 +0200 ++++ src/gdb/solist.h 2007-06-25 21:44:02.572337398 +0200 +@@ -113,6 +113,9 @@ struct target_so_ops + const domain_enum domain, + struct symtab **symtab); + ++ /* Extra hook for opening a BFD for a solib. Can be used to ++ retrieve solibs from inferior memory instead of from files. */ ++ struct bfd *(*open_bfd) (char *pathname, int already_resolved); + }; + + /* Free the memory associated with a (so_list *). */ +@@ -124,6 +127,10 @@ struct so_list *master_so_list (void); + /* Find solib binary file and open it. */ + extern int solib_open (char *in_pathname, char **found_pathname); + ++/* Find solib binary file and open BFD for it. */ ++extern struct bfd *solib_open_bfd (char *pathname, int already_resolved); ++ ++ + /* FIXME: gdbarch needs to control this variable */ + extern struct target_so_ops *current_target_so_ops; + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-core-bfd +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-core-bfd @@ -0,0 +1,61 @@ +diff -urNp src-orig/bfd/elf.c src/bfd/elf.c +--- src-orig/bfd/elf.c 2007-05-30 16:29:27.000000000 +0200 ++++ src/bfd/elf.c 2007-06-25 21:49:24.866882839 +0200 +@@ -8173,6 +8173,31 @@ elfcore_grok_nto_note (bfd *abfd, Elf_In + } + } + ++static bfd_boolean ++elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note) ++{ ++ char *name; ++ asection *sect; ++ ++ /* Use note name as section name. */ ++ name = bfd_alloc (abfd, strlen (note->namedata) + 1); ++ if (name == NULL) ++ return FALSE; ++ strcpy (name, note->namedata); ++ ++ sect = bfd_make_section_anyway (abfd, name); ++ if (sect == NULL) ++ return FALSE; ++ ++ sect->size = note->descsz; ++ sect->filepos = note->descpos; ++ sect->flags = SEC_HAS_CONTENTS; ++ sect->alignment_power = 1; ++ ++ return TRUE; ++} ++ ++ + /* Function: elfcore_write_note + + Inputs: +@@ -8485,6 +8510,11 @@ elfcore_read_notes (bfd *abfd, file_ptr + if (! elfcore_grok_nto_note (abfd, &in)) + goto error; + } ++ else if (CONST_STRNEQ (in.namedata, "SPU/")) ++ { ++ if (! elfcore_grok_spu_note (abfd, &in)) ++ goto error; ++ } + else + { + if (! elfcore_grok_note (abfd, &in)) +diff -urNp src-orig/include/elf/common.h src/include/elf/common.h +--- src-orig/include/elf/common.h 2007-04-26 08:59:55.000000000 +0200 ++++ src/include/elf/common.h 2007-06-25 21:49:24.910876508 +0200 +@@ -405,6 +405,10 @@ + #define NT_NETBSDCORE_PROCINFO 1 /* Has a struct procinfo */ + #define NT_NETBSDCORE_FIRSTMACH 32 /* start of machdep note types */ + ++/* Note segments for core files on SPU systems. Note name ++ must start with "SPU/". */ ++ ++#define NT_SPU 1 + + /* Values of note segment descriptor types for object files. */ + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-ppc-msymfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-ppc-msymfix @@ -0,0 +1,12 @@ +diff -urNp src-orig/gdb/minsyms.c src/gdb/minsyms.c +--- src-orig/gdb/minsyms.c 2007-06-16 00:39:52.000000000 +0200 ++++ src/gdb/minsyms.c 2007-06-25 21:38:46.998887244 +0200 +@@ -489,6 +489,8 @@ lookup_minimal_symbol_by_pc_section (COR + don't fill the bfd_section member, so don't + throw away symbols on those platforms. */ + && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL ++ /* Don't ignore symbols for solib trampolines */ ++ && MSYMBOL_TYPE (&msymbol[hi]) != mst_solib_trampoline + && (!matching_bfd_sections + (SYMBOL_BFD_SECTION (&msymbol[hi]), section))) + { --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-currarch +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-currarch @@ -0,0 +1,4068 @@ +diff -urNp src-orig/gdb/alpha-tdep.c src/gdb/alpha-tdep.c +--- src-orig/gdb/alpha-tdep.c 2007-06-28 03:23:18.582533735 +0200 ++++ src/gdb/alpha-tdep.c 2007-06-28 01:54:00.609951670 +0200 +@@ -56,7 +56,7 @@ + compatibility with existing remote alpha targets. */ + + static const char * +-alpha_register_name (int regno) ++alpha_register_name (struct gdbarch *gdbarch, int regno) + { + static const char * const register_names[] = + { +@@ -79,17 +79,17 @@ alpha_register_name (int regno) + } + + static int +-alpha_cannot_fetch_register (int regno) ++alpha_cannot_fetch_register (struct gdbarch *gdbarch, int regno) + { + return (regno == ALPHA_ZERO_REGNUM +- || strlen (alpha_register_name (regno)) == 0); ++ || strlen (alpha_register_name (gdbarch, regno)) == 0); + } + + static int +-alpha_cannot_store_register (int regno) ++alpha_cannot_store_register (struct gdbarch *gdbarch, int regno) + { + return (regno == ALPHA_ZERO_REGNUM +- || strlen (alpha_register_name (regno)) == 0); ++ || strlen (alpha_register_name (gdbarch, regno)) == 0); + } + + static struct type * +@@ -200,7 +200,7 @@ alpha_sts (void *out, const void *in) + registers is different. */ + + static int +-alpha_convert_register_p (int regno, struct type *type) ++alpha_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type) + { + return (regno >= ALPHA_FP0_REGNUM && regno < ALPHA_FP0_REGNUM + 31); + } +@@ -606,7 +606,7 @@ alpha_return_in_memory_always (struct ty + } + + static const gdb_byte * +-alpha_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++alpha_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static const gdb_byte break_insn[] = { 0x80, 0, 0, 0 }; /* call_pal bpt */ + +@@ -658,7 +658,7 @@ alpha_read_insn (CORE_ADDR pc) + anything which might clobber the registers which are being saved. */ + + static CORE_ADDR +-alpha_skip_prologue (CORE_ADDR pc) ++alpha_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + unsigned long inst; + int offset; +diff -urNp src-orig/gdb/amd64-linux-tdep.c src/gdb/amd64-linux-tdep.c +--- src-orig/gdb/amd64-linux-tdep.c 2007-06-28 03:23:18.623527830 +0200 ++++ src/gdb/amd64-linux-tdep.c 2007-06-28 01:54:00.614950950 +0200 +@@ -206,12 +206,12 @@ static int amd64_linux_sc_reg_offset[] = + /* Replacement register functions which know about %orig_rax. */ + + static const char * +-amd64_linux_register_name (int reg) ++amd64_linux_register_name (struct gdbarch *gdbarch, int reg) + { + if (reg == AMD64_LINUX_ORIG_RAX_REGNUM) + return "orig_rax"; + +- return amd64_register_name (reg); ++ return amd64_register_name (gdbarch, reg); + } + + static struct type * +diff -urNp src-orig/gdb/amd64-tdep.c src/gdb/amd64-tdep.c +--- src-orig/gdb/amd64-tdep.c 2007-06-28 03:23:18.629526966 +0200 ++++ src/gdb/amd64-tdep.c 2007-06-28 01:54:00.622084000 +0200 +@@ -75,7 +75,7 @@ static const char *amd64_register_names[ + /* Return the name of register REGNUM. */ + + const char * +-amd64_register_name (int regnum) ++amd64_register_name (struct gdbarch *gdbarch, int regnum) + { + if (regnum >= 0 && regnum < AMD64_NUM_REGS) + return amd64_register_names[regnum]; +@@ -189,7 +189,7 @@ static const int amd64_dwarf_regmap_len + number used by GDB. */ + + static int +-amd64_dwarf_reg_to_regnum (int reg) ++amd64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + int regnum = -1; + +@@ -206,7 +206,7 @@ amd64_dwarf_reg_to_regnum (int reg) + needs any special handling. */ + + static int +-amd64_convert_register_p (int regnum, struct type *type) ++amd64_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) + { + return i386_fp_regnum_p (regnum); + } +@@ -776,7 +776,7 @@ amd64_analyze_prologue (CORE_ADDR pc, CO + /* Return PC of first real instruction. */ + + static CORE_ADDR +-amd64_skip_prologue (CORE_ADDR start_pc) ++amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + struct amd64_frame_cache cache; + CORE_ADDR pc; +diff -urNp src-orig/gdb/amd64-tdep.h src/gdb/amd64-tdep.h +--- src-orig/gdb/amd64-tdep.h 2007-06-28 03:23:18.671520917 +0200 ++++ src/gdb/amd64-tdep.h 2007-06-28 01:54:00.627083280 +0200 +@@ -67,7 +67,7 @@ extern void amd64_init_abi (struct gdbar + /* Functions from amd64-tdep.c which may be needed on architectures + with extra registers. */ + +-extern const char *amd64_register_name (int regnum); ++extern const char *amd64_register_name (struct gdbarch *gdbarch, int regnum); + extern struct type *amd64_register_type (struct gdbarch *gdbarch, int regnum); + + /* Fill register REGNUM in REGCACHE with the appropriate +diff -urNp src-orig/gdb/arch-utils.c src/gdb/arch-utils.c +--- src-orig/gdb/arch-utils.c 2007-06-28 03:23:18.676520197 +0200 ++++ src/gdb/arch-utils.c 2007-06-28 01:54:00.634082272 +0200 +@@ -55,7 +55,7 @@ legacy_return_value (struct gdbarch *gdb + || TYPE_CODE (valtype) == TYPE_CODE_UNION + || TYPE_CODE (valtype) == TYPE_CODE_ARRAY) + && gdbarch_deprecated_use_struct_convention +- (current_gdbarch, 0, valtype)); ++ (gdbarch, 0, valtype)); + + if (writebuf != NULL) + { +@@ -65,13 +65,13 @@ legacy_return_value (struct gdbarch *gdb + structures. Should not be called with such types. */ + gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_STRUCT + && TYPE_CODE (valtype) != TYPE_CODE_UNION); +- gdbarch_store_return_value (current_gdbarch, valtype, regcache, writebuf); ++ gdbarch_store_return_value (gdbarch, valtype, regcache, writebuf); + } + + if (readbuf != NULL) + { + gdb_assert (!struct_return); +- gdbarch_extract_return_value (current_gdbarch, ++ gdbarch_extract_return_value (gdbarch, + valtype, regcache, readbuf); + } + +@@ -82,16 +82,16 @@ legacy_return_value (struct gdbarch *gdb + } + + int +-legacy_register_sim_regno (int regnum) ++legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum) + { + /* Only makes sense to supply raw registers. */ +- gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch)); ++ gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)); + /* NOTE: cagney/2002-05-13: The old code did it this way and it is + suspected that some GDB/SIM combinations may rely on this + behavour. The default should be one2one_register_sim_regno + (below). */ +- if (gdbarch_register_name (current_gdbarch, regnum) != NULL +- && gdbarch_register_name (current_gdbarch, regnum)[0] != '\0') ++ if (gdbarch_register_name (gdbarch, regnum) != NULL ++ && gdbarch_register_name (gdbarch, regnum)[0] != '\0') + return regnum; + else + return LEGACY_SIM_REGNO_IGNORE; +@@ -151,7 +151,7 @@ convert_from_func_ptr_addr_identity (str + } + + int +-no_op_reg_to_regnum (int reg) ++no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + return reg; + } +@@ -169,7 +169,7 @@ default_coff_make_msymbol_special (int v + } + + int +-cannot_register_not (int regnum) ++cannot_register_not (struct gdbarch *gdbarch, int regnum) + { + return 0; + } +@@ -179,7 +179,8 @@ cannot_register_not (int regnum) + raw. */ + + void +-legacy_virtual_frame_pointer (CORE_ADDR pc, ++legacy_virtual_frame_pointer (struct gdbarch *gdbarch, ++ CORE_ADDR pc, + int *frame_regnum, + LONGEST *frame_offset) + { +@@ -188,14 +189,14 @@ legacy_virtual_frame_pointer (CORE_ADDR + register and an offset can determine this. I think it should + instead generate a byte code expression as that would work better + with things like Dwarf2's CFI. */ +- if (gdbarch_deprecated_fp_regnum (current_gdbarch) >= 0 +- && gdbarch_deprecated_fp_regnum (current_gdbarch) +- < gdbarch_num_regs (current_gdbarch)) +- *frame_regnum = gdbarch_deprecated_fp_regnum (current_gdbarch); +- else if (gdbarch_sp_regnum (current_gdbarch) >= 0 +- && gdbarch_sp_regnum (current_gdbarch) +- < gdbarch_num_regs (current_gdbarch)) +- *frame_regnum = gdbarch_sp_regnum (current_gdbarch); ++ if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0 ++ && gdbarch_deprecated_fp_regnum (gdbarch) ++ < gdbarch_num_regs (gdbarch)) ++ *frame_regnum = gdbarch_deprecated_fp_regnum (gdbarch); ++ else if (gdbarch_sp_regnum (gdbarch) >= 0 ++ && gdbarch_sp_regnum (gdbarch) ++ < gdbarch_num_regs (gdbarch)) ++ *frame_regnum = gdbarch_sp_regnum (gdbarch); + else + /* Should this be an internal error? I guess so, it is reflecting + an architectural limitation in the current design. */ +@@ -205,7 +206,8 @@ legacy_virtual_frame_pointer (CORE_ADDR + + + int +-generic_convert_register_p (int regnum, struct type *type) ++generic_convert_register_p (struct gdbarch *gdbarch, int regnum, ++ struct type *type) + { + return 0; + } +diff -urNp src-orig/gdb/arch-utils.h src/gdb/arch-utils.h +--- src-orig/gdb/arch-utils.h 2007-06-28 03:23:18.681519477 +0200 ++++ src/gdb/arch-utils.h 2007-06-28 01:54:00.639081551 +0200 +@@ -56,7 +56,7 @@ extern gdbarch_convert_from_func_ptr_add + + /* No-op conversion of reg to regnum. */ + +-extern int no_op_reg_to_regnum (int reg); ++extern int no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg); + + /* Do nothing version of elf_make_msymbol_special. */ + +@@ -69,7 +69,7 @@ void default_coff_make_msymbol_special ( + /* Version of cannot_fetch_register() / cannot_store_register() that + always fails. */ + +-int cannot_register_not (int regnum); ++int cannot_register_not (struct gdbarch *gdbarch, int regnum); + + /* Legacy version of target_virtual_frame_pointer(). Assumes that + there is an gdbarch_deprecated_fp_regnum and that it is the same, cooked or +@@ -88,7 +88,8 @@ extern int generic_in_solib_return_tramp + extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc); + + /* By default, registers are not convertible. */ +-extern int generic_convert_register_p (int regnum, struct type *type); ++extern int generic_convert_register_p (struct gdbarch *gdbarch, ++ int regnum, struct type *type); + + extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch, + struct type *type); +@@ -103,7 +104,7 @@ int default_remote_register_number (stru + (LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid + name. */ + +-extern int legacy_register_sim_regno (int regnum); ++extern int legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum); + + /* Return the selected byte order, or BFD_ENDIAN_UNKNOWN if no byte + order was explicitly selected. */ +diff -urNp src-orig/gdb/arm-tdep.c src/gdb/arm-tdep.c +--- src-orig/gdb/arm-tdep.c 2007-06-28 03:23:18.690518181 +0200 ++++ src/gdb/arm-tdep.c 2007-06-28 01:54:00.650079967 +0200 +@@ -424,7 +424,7 @@ thumb_analyze_prologue (struct gdbarch * + sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */ + + static CORE_ADDR +-arm_skip_prologue (CORE_ADDR pc) ++arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + unsigned long inst; + CORE_ADDR skip_pc; +@@ -1405,7 +1405,7 @@ arm_register_type (struct gdbarch *gdbar + number. */ + + static int +-arm_dwarf_reg_to_regnum (int reg) ++arm_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* Core integer regs. */ + if (reg >= 0 && reg <= 15) +@@ -1437,7 +1437,7 @@ arm_dwarf_reg_to_regnum (int reg) + + /* Map GDB internal REGNUM onto the Arm simulator register numbers. */ + static int +-arm_register_sim_regno (int regnum) ++arm_register_sim_regno (struct gdbarch *gdbarch, int regnum) + { + int reg = regnum; + gdb_assert (reg >= 0 && reg < gdbarch_num_regs (current_gdbarch)); +@@ -2022,7 +2022,7 @@ static const char arm_default_thumb_be_b + breakpoint should be inserted. */ + + static const unsigned char * +-arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++arm_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + +@@ -2527,7 +2527,7 @@ set_disassembly_style_sfunc (char *args, + + /* Return the ARM register name corresponding to register I. */ + static const char * +-arm_register_name (int i) ++arm_register_name (struct gdbarch *gdbarch, int i) + { + if (i >= ARRAY_SIZE (arm_register_names)) + /* These registers are only supported on targets which supply +diff -urNp src-orig/gdb/avr-tdep.c src/gdb/avr-tdep.c +--- src-orig/gdb/avr-tdep.c 2007-06-28 03:23:18.733511988 +0200 ++++ src/gdb/avr-tdep.c 2007-06-28 01:54:00.658078814 +0200 +@@ -190,7 +190,7 @@ struct gdbarch_tdep + /* Lookup the name of a register given it's number. */ + + static const char * +-avr_register_name (int regnum) ++avr_register_name (struct gdbarch *gdbarch, int regnum) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -746,7 +746,7 @@ avr_scan_prologue (CORE_ADDR pc, struct + } + + static CORE_ADDR +-avr_skip_prologue (CORE_ADDR pc) ++avr_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end; + CORE_ADDR prologue_end = pc; +@@ -790,7 +790,7 @@ avr_skip_prologue (CORE_ADDR pc) + only target, this shouldn't be a problem (I hope). TRoth/2003-05-14 */ + + static const unsigned char * +-avr_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) ++avr_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char avr_break_insn [] = { 0x98, 0x95 }; + *lenptr = sizeof (avr_break_insn); +diff -urNp src-orig/gdb/cris-tdep.c src/gdb/cris-tdep.c +--- src-orig/gdb/cris-tdep.c 2007-06-28 03:23:18.744510404 +0200 ++++ src/gdb/cris-tdep.c 2007-06-28 01:54:00.671076941 +0200 +@@ -1434,7 +1434,7 @@ crisv32_scan_prologue (CORE_ADDR pc, str + of the first instruction after the function prologue. */ + + static CORE_ADDR +-cris_skip_prologue (CORE_ADDR pc) ++cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end; + struct symtab_and_line sal; +@@ -1482,7 +1482,7 @@ cris_unwind_sp (struct gdbarch *gdbarch, + the breakpoint should be inserted. */ + + static const unsigned char * +-cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++cris_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char break8_insn[] = {0x38, 0xe9}; + static unsigned char break15_insn[] = {0x3f, 0xe9}; +@@ -1582,7 +1582,7 @@ cris_register_size (int regno) + for unimplemented (size 0) and non-existant registers. */ + + static int +-cris_cannot_fetch_register (int regno) ++cris_cannot_fetch_register (struct gdbarch *gdbarch, int regno) + { + return ((regno < 0 || regno >= gdbarch_num_regs (current_gdbarch)) + || (cris_register_size (regno) == 0)); +@@ -1592,7 +1592,7 @@ cris_cannot_fetch_register (int regno) + reasons. */ + + static int +-cris_cannot_store_register (int regno) ++cris_cannot_store_register (struct gdbarch *gdbarch, int regno) + { + /* There are three kinds of registers we refuse to write to. + 1. Those that not implemented. +@@ -1624,7 +1624,7 @@ cris_cannot_store_register (int regno) + for unimplemented (size 0) and non-existant registers. */ + + static int +-crisv32_cannot_fetch_register (int regno) ++crisv32_cannot_fetch_register (struct gdbarch *gdbarch, int regno) + { + return ((regno < 0 || regno >= gdbarch_num_regs (current_gdbarch)) + || (cris_register_size (regno) == 0)); +@@ -1634,7 +1634,7 @@ crisv32_cannot_fetch_register (int regno + reasons. */ + + static int +-crisv32_cannot_store_register (int regno) ++crisv32_cannot_store_register (struct gdbarch *gdbarch, int regno) + { + /* There are three kinds of registers we refuse to write to. + 1. Those that not implemented. +@@ -1770,7 +1770,7 @@ cris_special_register_name (int regno) + } + + static const char * +-cris_register_name (int regno) ++cris_register_name (struct gdbarch *gdbarch, int regno) + { + static char *cris_genreg_names[] = + { "r0", "r1", "r2", "r3", \ +@@ -1795,7 +1795,7 @@ cris_register_name (int regno) + } + + static const char * +-crisv32_register_name (int regno) ++crisv32_register_name (struct gdbarch *gdbarch, int regno) + { + static char *crisv32_genreg_names[] = + { "r0", "r1", "r2", "r3", \ +@@ -1839,7 +1839,7 @@ crisv32_register_name (int regno) + number used by GDB. */ + + static int +-cris_dwarf2_reg_to_regnum (int reg) ++cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* We need to re-map a couple of registers (SRP is 16 in Dwarf-2 register + numbering, MOF is 18). +diff -urNp src-orig/gdb/dwarf2expr.c src/gdb/dwarf2expr.c +--- src-orig/gdb/dwarf2expr.c 2007-06-28 03:23:18.789503924 +0200 ++++ src/gdb/dwarf2expr.c 2007-06-28 01:54:00.679075789 +0200 +@@ -33,7 +33,7 @@ + + static void execute_stack_op (struct dwarf_expr_context *, + gdb_byte *, gdb_byte *); +-static struct type *unsigned_address_type (void); ++static struct type *unsigned_address_type (int); + + /* Create a new context for the expression evaluator. */ + +@@ -198,15 +198,13 @@ read_sleb128 (gdb_byte *buf, gdb_byte *b + number of bytes read from BUF. */ + + CORE_ADDR +-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read) ++dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size) + { + CORE_ADDR result; + +- if (buf_end - buf < gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) ++ if (buf_end - buf < addr_size) + error (_("dwarf2_read_address: Corrupted DWARF expression.")); + +- *bytes_read = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT; +- + /* For most architectures, calling extract_unsigned_integer() alone + is sufficient for extracting an address. However, some + architectures (e.g. MIPS) use signed addresses and using +@@ -230,11 +228,8 @@ dwarf2_read_address (gdb_byte *buf, gdb_ + address being returned. */ + + result = value_as_address (value_from_longest +- (unsigned_address_type (), +- extract_unsigned_integer +- (buf, +- gdbarch_addr_bit (current_gdbarch) +- / TARGET_CHAR_BIT))); ++ (unsigned_address_type (addr_size), ++ extract_unsigned_integer (buf, addr_size))); + + return result; + } +@@ -242,9 +237,9 @@ dwarf2_read_address (gdb_byte *buf, gdb_ + /* Return the type of an address, for unsigned arithmetic. */ + + static struct type * +-unsigned_address_type (void) ++unsigned_address_type (int addr_size) + { +- switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) ++ switch (addr_size) + { + case 2: + return builtin_type_uint16; +@@ -261,9 +256,9 @@ unsigned_address_type (void) + /* Return the type of an address, for signed arithmetic. */ + + static struct type * +-signed_address_type (void) ++signed_address_type (int addr_size) + { +- switch (gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT) ++ switch (addr_size) + { + case 2: + return builtin_type_int16; +@@ -293,7 +288,6 @@ execute_stack_op (struct dwarf_expr_cont + CORE_ADDR result; + ULONGEST uoffset, reg; + LONGEST offset; +- int bytes_read; + + switch (op) + { +@@ -333,8 +327,8 @@ execute_stack_op (struct dwarf_expr_cont + break; + + case DW_OP_addr: +- result = dwarf2_read_address (op_ptr, op_end, &bytes_read); +- op_ptr += bytes_read; ++ result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size); ++ op_ptr += ctx->addr_size; + break; + + case DW_OP_const1u: +@@ -551,34 +545,19 @@ execute_stack_op (struct dwarf_expr_cont + { + case DW_OP_deref: + { +- gdb_byte *buf = alloca (gdbarch_addr_bit (current_gdbarch) +- / TARGET_CHAR_BIT); +- int bytes_read; +- +- (ctx->read_mem) (ctx->baton, buf, result, +- gdbarch_addr_bit (current_gdbarch) +- / TARGET_CHAR_BIT); +- result = dwarf2_read_address (buf, +- buf + (gdbarch_addr_bit +- (current_gdbarch) +- / TARGET_CHAR_BIT), +- &bytes_read); ++ gdb_byte *buf = alloca (ctx->addr_size); ++ (ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size); ++ result = dwarf2_read_address (buf, buf + ctx->addr_size, ++ ctx->addr_size); + } + break; + + case DW_OP_deref_size: + { +- gdb_byte *buf +- = alloca (gdbarch_addr_bit (current_gdbarch) +- / TARGET_CHAR_BIT); +- int bytes_read; +- ++ gdb_byte *buf = alloca (ctx->addr_size); + (ctx->read_mem) (ctx->baton, buf, result, *op_ptr++); +- result = dwarf2_read_address (buf, +- buf + (gdbarch_addr_bit +- (current_gdbarch) +- / TARGET_CHAR_BIT), +- &bytes_read); ++ result = dwarf2_read_address (buf, buf + ctx->addr_size, ++ ctx->addr_size); + } + break; + +@@ -629,8 +608,10 @@ execute_stack_op (struct dwarf_expr_cont + first = dwarf_expr_fetch (ctx, 0); + dwarf_expr_pop (ctx); + +- val1 = value_from_longest (unsigned_address_type (), first); +- val2 = value_from_longest (unsigned_address_type (), second); ++ val1 = value_from_longest ++ (unsigned_address_type (ctx->addr_size), first); ++ val2 = value_from_longest ++ (unsigned_address_type (ctx->addr_size), second); + + switch (op) + { +@@ -663,7 +644,8 @@ execute_stack_op (struct dwarf_expr_cont + break; + case DW_OP_shra: + binop = BINOP_RSH; +- val1 = value_from_longest (signed_address_type (), first); ++ val1 = value_from_longest ++ (signed_address_type (ctx->addr_size), first); + break; + case DW_OP_xor: + binop = BINOP_BITWISE_XOR; +diff -urNp src-orig/gdb/dwarf2expr.h src/gdb/dwarf2expr.h +--- src-orig/gdb/dwarf2expr.h 2007-06-28 03:23:18.793503348 +0200 ++++ src/gdb/dwarf2expr.h 2007-06-28 01:54:00.683075212 +0200 +@@ -54,6 +54,9 @@ struct dwarf_expr_context + DW_OP_GNU_push_tls_address. */ + CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset); + ++ /* Target address size in bytes. */ ++ int addr_size; ++ + #if 0 + /* Not yet implemented. */ + +@@ -137,6 +140,6 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf + gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r); + gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r); + CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, +- int *bytes_read); ++ int addr_size); + + #endif /* dwarf2expr.h */ +diff -urNp src-orig/gdb/dwarf2-frame.c src/gdb/dwarf2-frame.c +--- src-orig/gdb/dwarf2-frame.c 2007-06-28 03:23:18.801502195 +0200 ++++ src/gdb/dwarf2-frame.c 2007-06-28 01:54:00.694073628 +0200 +@@ -237,7 +237,7 @@ read_reg (void *baton, int reg) + int regnum; + gdb_byte *buf; + +- regnum = gdbarch_dwarf2_reg_to_regnum (current_gdbarch, reg); ++ regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg); + + buf = alloca (register_size (gdbarch, regnum)); + frame_unwind_register (next_frame, regnum, buf); +@@ -274,6 +274,7 @@ static CORE_ADDR + execute_stack_op (gdb_byte *exp, ULONGEST len, + struct frame_info *next_frame, CORE_ADDR initial) + { ++ struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct dwarf_expr_context *ctx; + CORE_ADDR result; + +@@ -283,6 +284,7 @@ execute_stack_op (gdb_byte *exp, ULONGES + ctx->read_mem = read_mem; + ctx->get_frame_base = no_get_frame_base; + ctx->get_tls_address = no_get_tls_address; ++ ctx->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + + dwarf_expr_push (ctx, initial); + dwarf_expr_eval (ctx, exp, len); +@@ -303,8 +305,8 @@ execute_cfa_program (gdb_byte *insn_ptr, + struct dwarf2_frame_state *fs, int eh_frame_p) + { + CORE_ADDR pc = frame_pc_unwind (next_frame); +- int bytes_read; + struct gdbarch *gdbarch = get_frame_arch (next_frame); ++ int addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + + while (insn_ptr < insn_end && fs->pc <= pc) + { +@@ -340,9 +342,8 @@ execute_cfa_program (gdb_byte *insn_ptr, + incomplete CFI data; DW_CFA_restore unspecified\n\ + register %s (#%d) at 0x%s"), + gdbarch_register_name +- (current_gdbarch, gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, reg)), +- gdbarch_dwarf2_reg_to_regnum (current_gdbarch, reg), ++ (gdbarch, gdbarch_dwarf2_reg_to_regnum (gdbarch, reg)), ++ gdbarch_dwarf2_reg_to_regnum (gdbarch, reg), + paddr (fs->pc)); + } + else +@@ -350,8 +351,8 @@ register %s (#%d) at 0x%s"), + switch (insn) + { + case DW_CFA_set_loc: +- fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read); +- insn_ptr += bytes_read; ++ fs->pc = dwarf2_read_address (insn_ptr, insn_end, addr_size); ++ insn_ptr += addr_size; + break; + + case DW_CFA_advance_loc1: +@@ -649,9 +650,9 @@ dwarf2_frame_default_init_reg (struct gd + (e.g. IBM S/390 and zSeries). Those architectures should provide + their own architecture-specific initialization function. */ + +- if (regnum == gdbarch_pc_regnum (current_gdbarch)) ++ if (regnum == gdbarch_pc_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_RA; +- else if (regnum == gdbarch_sp_regnum (current_gdbarch)) ++ else if (regnum == gdbarch_sp_regnum (gdbarch)) + reg->how = DWARF2_FRAME_REG_CFA; + } + +@@ -811,8 +812,8 @@ dwarf2_frame_cache (struct frame_info *n + { + struct cleanup *old_chain; + struct gdbarch *gdbarch = get_frame_arch (next_frame); +- const int num_regs = gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch); ++ const int num_regs = gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch); + struct dwarf2_frame_cache *cache; + struct dwarf2_frame_state *fs; + struct dwarf2_fde *fde; +@@ -911,7 +912,7 @@ dwarf2_frame_cache (struct frame_info *n + for (column = 0; column < fs->regs.num_regs; column++) + { + /* Use the GDB register number as the destination index. */ +- int regnum = gdbarch_dwarf2_reg_to_regnum (current_gdbarch, column); ++ int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, column); + + /* If there's no corresponding GDB register, ignore it. */ + if (regnum < 0 || regnum >= num_regs) +@@ -1070,7 +1071,7 @@ dwarf2_frame_prev_register (struct frame + *lvalp = lval_register; + *addrp = 0; + *realnump = gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, cache->reg[regnum].loc.reg); ++ (gdbarch, cache->reg[regnum].loc.reg); + if (valuep) + frame_unwind_register (next_frame, (*realnump), valuep); + break; +@@ -1165,7 +1166,7 @@ dwarf2_frame_prev_register (struct frame + CORE_ADDR pc = cache->reg[regnum].loc.offset; + + regnum = gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, cache->retaddr_reg.loc.reg); ++ (gdbarch, cache->retaddr_reg.loc.reg); + pc += frame_unwind_register_unsigned (next_frame, regnum); + pack_long (valuep, register_type (gdbarch, regnum), pc); + } +@@ -1408,32 +1409,12 @@ encoding_for_size (unsigned int size) + } + } + +-static unsigned int +-size_of_encoded_value (gdb_byte encoding) +-{ +- if (encoding == DW_EH_PE_omit) +- return 0; +- +- switch (encoding & 0x07) +- { +- case DW_EH_PE_absptr: +- return TYPE_LENGTH (builtin_type_void_data_ptr); +- case DW_EH_PE_udata2: +- return 2; +- case DW_EH_PE_udata4: +- return 4; +- case DW_EH_PE_udata8: +- return 8; +- default: +- internal_error (__FILE__, __LINE__, _("Invalid or unsupported encoding")); +- } +-} +- + static CORE_ADDR + read_encoded_value (struct comp_unit *unit, gdb_byte encoding, + gdb_byte *buf, unsigned int *bytes_read_ptr) + { +- int ptr_len = size_of_encoded_value (DW_EH_PE_absptr); ++ struct gdbarch *gdbarch = unit->objfile->gdbarch; ++ int ptr_len = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + ptrdiff_t offset; + CORE_ADDR base; + +@@ -1611,6 +1592,7 @@ static gdb_byte *decode_frame_entry (str + static gdb_byte * + decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) + { ++ struct gdbarch *gdbarch = unit->objfile->gdbarch; + gdb_byte *buf, *end; + LONGEST length; + unsigned int bytes_read; +@@ -1702,7 +1684,7 @@ decode_frame_entry_1 (struct comp_unit * + if (augmentation[0] == 'e' && augmentation[1] == 'h') + { + /* Skip. */ +- buf += TYPE_LENGTH (builtin_type_void_data_ptr); ++ buf += gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + augmentation += 2; + } + +@@ -1723,7 +1705,7 @@ decode_frame_entry_1 (struct comp_unit * + cie->return_address_register = read_unsigned_leb128 (unit->abfd, buf, + &bytes_read); + cie->return_address_register +- = dwarf2_frame_adjust_regnum (current_gdbarch, ++ = dwarf2_frame_adjust_regnum (gdbarch, + cie->return_address_register, + eh_frame_p); + +diff -urNp src-orig/gdb/dwarf2loc.c src/gdb/dwarf2loc.c +--- src-orig/gdb/dwarf2loc.c 2007-06-28 03:23:18.807501331 +0200 ++++ src/gdb/dwarf2loc.c 2007-06-28 01:54:00.701072619 +0200 +@@ -52,10 +52,11 @@ static gdb_byte * + find_location_expression (struct dwarf2_loclist_baton *baton, + size_t *locexpr_length, CORE_ADDR pc) + { ++ struct gdbarch *gdbarch = baton->objfile->gdbarch; + CORE_ADDR low, high; + gdb_byte *loc_ptr, *buf_end; + int length; +- unsigned int addr_size = gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT; ++ unsigned int addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); + /* Adjust base_address for relocatable objects. */ + CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets, +@@ -67,10 +68,10 @@ find_location_expression (struct dwarf2_ + + while (1) + { +- low = dwarf2_read_address (loc_ptr, buf_end, &length); +- loc_ptr += length; +- high = dwarf2_read_address (loc_ptr, buf_end, &length); +- loc_ptr += length; ++ low = dwarf2_read_address (loc_ptr, buf_end, addr_size); ++ loc_ptr += addr_size; ++ high = dwarf2_read_address (loc_ptr, buf_end, addr_size); ++ loc_ptr += addr_size; + + /* An end-of-list entry. */ + if (low == 0 && high == 0) +@@ -116,11 +117,12 @@ static CORE_ADDR + dwarf_expr_read_reg (void *baton, int dwarf_regnum) + { + struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; ++ struct gdbarch *gdbarch = get_frame_arch (debaton->frame); + CORE_ADDR result; + int regnum; + +- regnum = gdbarch_dwarf2_reg_to_regnum (current_gdbarch, dwarf_regnum); +- result = address_from_register (builtin_type_void_data_ptr, ++ regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum); ++ result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr, + regnum, debaton->frame); + return result; + } +@@ -187,7 +189,7 @@ dwarf2_evaluate_loc_desc (struct symbol + gdb_byte *data, unsigned short size, + struct objfile *objfile) + { +- struct gdbarch *arch = get_frame_arch (frame); ++ struct gdbarch *gdbarch = get_frame_arch (frame); + struct value *retval; + struct dwarf_expr_baton baton; + struct dwarf_expr_context *ctx; +@@ -209,6 +211,7 @@ dwarf2_evaluate_loc_desc (struct symbol + ctx->read_mem = dwarf_expr_read_mem; + ctx->get_frame_base = dwarf_expr_frame_base; + ctx->get_tls_address = dwarf_expr_tls_address; ++ ctx->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + + dwarf_expr_eval (ctx, data, size); + if (ctx->num_pieces > 0) +@@ -225,8 +228,7 @@ dwarf2_evaluate_loc_desc (struct symbol + if (p->in_reg) + { + bfd_byte regval[MAX_REGISTER_SIZE]; +- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, p->value); ++ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, p->value); + get_frame_register (frame, gdb_regnum, regval); + memcpy (contents + offset, regval, p->size); + } +@@ -240,8 +242,7 @@ dwarf2_evaluate_loc_desc (struct symbol + else if (ctx->in_reg) + { + CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0); +- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, dwarf_regnum); ++ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum); + retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame); + } + else +@@ -314,8 +315,10 @@ needs_frame_tls_address (void *baton, CO + requires a frame to evaluate. */ + + static int +-dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size) ++dwarf2_loc_desc_needs_frame (struct objfile *objfile, ++ gdb_byte *data, unsigned short size) + { ++ struct gdbarch *gdbarch = objfile->gdbarch; + struct needs_frame_baton baton; + struct dwarf_expr_context *ctx; + int in_reg; +@@ -328,6 +331,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d + ctx->read_mem = needs_frame_read_mem; + ctx->get_frame_base = needs_frame_frame_base; + ctx->get_tls_address = needs_frame_tls_address; ++ ctx->addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + + dwarf_expr_eval (ctx, data, size); + +@@ -435,7 +439,8 @@ static int + locexpr_read_needs_frame (struct symbol *symbol) + { + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); +- return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size); ++ return dwarf2_loc_desc_needs_frame (dlbaton->objfile, ++ dlbaton->data, dlbaton->size); + } + + /* Print a natural-language description of SYMBOL to STREAM. */ +@@ -444,16 +449,18 @@ locexpr_describe_location (struct symbol + { + /* FIXME: be more extensive. */ + struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); ++ struct gdbarch *gdbarch = dlbaton->objfile->gdbarch; ++ int addr_size = gdbarch_addr_bit (gdbarch) / TARGET_CHAR_BIT; + + if (dlbaton->size == 1 + && dlbaton->data[0] >= DW_OP_reg0 + && dlbaton->data[0] <= DW_OP_reg31) + { + int regno = gdbarch_dwarf2_reg_to_regnum +- (current_gdbarch, dlbaton->data[0] - DW_OP_reg0); ++ (gdbarch, dlbaton->data[0] - DW_OP_reg0); + fprintf_filtered (stream, + "a variable in register %s", +- gdbarch_register_name (current_gdbarch, regno)); ++ gdbarch_register_name (gdbarch, regno)); + return 1; + } + +@@ -473,10 +480,9 @@ locexpr_describe_location (struct symbol + && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address) + if (dlbaton->data[0] == DW_OP_addr) + { +- int bytes_read; + CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1], + &dlbaton->data[dlbaton->size - 1], +- &bytes_read); ++ addr_size); + fprintf_filtered (stream, + "a thread-local variable at offset %s in the " + "thread-local storage for `%s'", +diff -urNp src-orig/gdb/dwarf2read.c src/gdb/dwarf2read.c +--- src-orig/gdb/dwarf2read.c 2007-06-28 03:23:18.827498451 +0200 ++++ src/gdb/dwarf2read.c 2007-06-28 01:54:00.726069017 +0200 +@@ -4525,6 +4525,7 @@ namespace_name (struct die_info *die, in + static void + read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) + { ++ struct gdbarch *gdbarch = cu->objfile->gdbarch; + struct comp_unit_head *cu_header = &cu->header; + struct type *type; + struct attribute *attr_byte_size; +@@ -4555,12 +4556,12 @@ read_tag_pointer_type (struct die_info * + length accordingly. */ + if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none) + { +- if (gdbarch_address_class_type_flags_p (current_gdbarch)) ++ if (gdbarch_address_class_type_flags_p (gdbarch)) + { + int type_flags; + + type_flags = gdbarch_address_class_type_flags +- (current_gdbarch, byte_size, addr_class); ++ (gdbarch, byte_size, addr_class); + gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); + type = make_type_with_address_space (type, type_flags); + } +@@ -4915,6 +4916,7 @@ read_base_type (struct die_info *die, st + static void + read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) + { ++ struct gdbarch *gdbarch = cu->objfile->gdbarch; + struct type *base_type; + struct type *range_type; + struct attribute *attr; +@@ -4932,7 +4934,7 @@ read_subrange_type (struct die_info *die + _("DW_AT_type missing from DW_TAG_subrange_type")); + base_type + = dwarf_base_type (DW_ATE_signed, +- gdbarch_addr_bit (current_gdbarch) / 8, cu); ++ gdbarch_addr_bit (gdbarch) / 8, cu); + } + + if (cu->language == language_fortran) +@@ -7067,6 +7069,7 @@ static struct symbol * + new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) + { + struct objfile *objfile = cu->objfile; ++ struct gdbarch *gdbarch = objfile->gdbarch; + struct symbol *sym = NULL; + char *name; + struct attribute *attr = NULL; +@@ -7150,8 +7153,7 @@ new_symbol (struct die_info *die, struct + with missing type entries. Change the misleading `void' type + to something sensible. */ + if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID) +- SYMBOL_TYPE (sym) +- = builtin_type (current_gdbarch)->nodebug_data_symbol; ++ SYMBOL_TYPE (sym) = builtin_type (gdbarch)->nodebug_data_symbol; + + attr = dwarf2_attr (die, DW_AT_const_value, cu); + if (attr) +diff -urNp src-orig/gdb/frame.c src/gdb/frame.c +--- src-orig/gdb/frame.c 2007-06-28 03:23:18.871492114 +0200 ++++ src/gdb/frame.c 2007-06-28 03:23:09.282410634 +0200 +@@ -437,7 +437,7 @@ frame_pc_unwind (struct frame_info *this + /* A per-frame unwinder, prefer it. */ + pc = this_frame->unwind->prev_pc (this_frame->next, + &this_frame->prologue_cache); +- else if (gdbarch_unwind_pc_p (current_gdbarch)) ++ else if (gdbarch_unwind_pc_p (get_frame_arch (this_frame))) + { + /* The right way. The `pure' way. The one true way. This + method depends solely on the register-unwind code to +@@ -455,7 +455,7 @@ frame_pc_unwind (struct frame_info *this + frame. This is all in stark contrast to the old + FRAME_SAVED_PC which would try to directly handle all the + different ways that a PC could be unwound. */ +- pc = gdbarch_unwind_pc (current_gdbarch, this_frame); ++ pc = gdbarch_unwind_pc (get_frame_arch (this_frame), this_frame); + } + else + internal_error (__FILE__, __LINE__, _("No unwind_pc method")); +@@ -504,7 +504,7 @@ do_frame_register_read (void *src, int r + struct regcache * + frame_save_as_regcache (struct frame_info *this_frame) + { +- struct regcache *regcache = regcache_xmalloc (current_gdbarch); ++ struct regcache *regcache = regcache_xmalloc (get_frame_arch (this_frame)); + struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache); + regcache_save (regcache, do_frame_register_read, this_frame); + discard_cleanups (cleanups); +@@ -603,7 +603,7 @@ frame_register_unwind (struct frame_info + int i; + const unsigned char *buf = bufferp; + fprintf_unfiltered (gdb_stdlog, "["); +- for (i = 0; i < register_size (current_gdbarch, regnum); i++) ++ for (i = 0; i < register_size (get_frame_arch (frame), regnum); i++) + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + fprintf_unfiltered (gdb_stdlog, "]"); + } +@@ -1229,7 +1229,7 @@ get_prev_frame_1 (struct frame_info *thi + method set the same lval and location information as + frame_register_unwind. */ + if (this_frame->level > 0 +- && gdbarch_pc_regnum (current_gdbarch) >= 0 ++ && gdbarch_pc_regnum (get_frame_arch (this_frame)) >= 0 + && get_frame_type (this_frame) == NORMAL_FRAME + && get_frame_type (this_frame->next) == NORMAL_FRAME) + { +@@ -1238,10 +1238,10 @@ get_prev_frame_1 (struct frame_info *thi + CORE_ADDR addr, naddr; + + frame_register_unwind_location (this_frame, +- gdbarch_pc_regnum (current_gdbarch), ++ gdbarch_pc_regnum (get_frame_arch (this_frame)), + &optimized, &lval, &addr, &realnum); + frame_register_unwind_location (get_next_frame (this_frame), +- gdbarch_pc_regnum (current_gdbarch), ++ gdbarch_pc_regnum (get_frame_arch (this_frame)), + &optimized, &nlval, &naddr, &realnum); + + if (lval == lval_memory && lval == nlval && addr == naddr) +@@ -1338,7 +1338,7 @@ inside_main_func (struct frame_info *thi + return 0; + /* Make certain that the code, and not descriptor, address is + returned. */ +- maddr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, ++ maddr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame), + SYMBOL_VALUE_ADDRESS (msymbol), + ¤t_target); + return maddr == get_frame_func (this_frame); +@@ -1723,15 +1723,15 @@ frame_sp_unwind (struct frame_info *next + { + /* Normality - an architecture that provides a way of obtaining any + frame inner-most address. */ +- if (gdbarch_unwind_sp_p (current_gdbarch)) +- return gdbarch_unwind_sp (current_gdbarch, next_frame); ++ if (gdbarch_unwind_sp_p (get_frame_arch (next_frame))) ++ return gdbarch_unwind_sp (get_frame_arch (next_frame), next_frame); + /* Now things are really are grim. Hope that the value returned by + the gdbarch_sp_regnum register is meaningful. */ +- if (gdbarch_sp_regnum (current_gdbarch) >= 0) ++ if (gdbarch_sp_regnum (get_frame_arch (next_frame)) >= 0) + { + ULONGEST sp; + frame_unwind_unsigned_register (next_frame, +- gdbarch_sp_regnum (current_gdbarch), &sp); ++ gdbarch_sp_regnum (get_frame_arch (next_frame)), &sp); + return sp; + } + internal_error (__FILE__, __LINE__, _("Missing unwind SP method")); +diff -urNp src-orig/gdb/frv-tdep.c src/gdb/frv-tdep.c +--- src-orig/gdb/frv-tdep.c 2007-06-28 03:23:18.878491106 +0200 ++++ src/gdb/frv-tdep.c 2007-06-28 01:54:00.744066424 +0200 +@@ -279,7 +279,7 @@ set_variant_scratch_registers (struct gd + } + + static const char * +-frv_register_name (int reg) ++frv_register_name (struct gdbarch *gdbarch, int reg) + { + if (reg < 0) + return "?toosmall?"; +@@ -352,7 +352,7 @@ frv_pseudo_register_write (struct gdbarc + } + + static int +-frv_register_sim_regno (int reg) ++frv_register_sim_regno (struct gdbarch *gdbarch, int reg) + { + static const int spr_map[] = + { +@@ -419,7 +419,7 @@ frv_register_sim_regno (int reg) + } + + static const unsigned char * +-frv_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenp) ++frv_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenp) + { + static unsigned char breakpoint[] = {0xc0, 0x70, 0x00, 0x01}; + *lenp = sizeof (breakpoint); +@@ -970,7 +970,7 @@ frv_analyze_prologue (CORE_ADDR pc, stru + + + static CORE_ADDR +-frv_skip_prologue (CORE_ADDR pc) ++frv_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end, new_pc; + +diff -urNp src-orig/gdb/gdbarch.c src/gdb/gdbarch.c +--- src-orig/gdb/gdbarch.c 2007-06-28 03:23:18.889489522 +0200 ++++ src/gdb/gdbarch.c 2007-06-28 01:54:00.758064407 +0200 +@@ -268,7 +268,7 @@ struct gdbarch startup_gdbarch = + 1, /* char_signed */ + 0, /* read_pc */ + 0, /* write_pc */ +- 0, /* virtual_frame_pointer */ ++ legacy_virtual_frame_pointer, /* virtual_frame_pointer */ + 0, /* pseudo_register_read */ + 0, /* pseudo_register_write */ + 0, /* num_regs */ +@@ -277,11 +277,11 @@ struct gdbarch startup_gdbarch = + -1, /* pc_regnum */ + -1, /* ps_regnum */ + 0, /* fp0_regnum */ +- 0, /* stab_reg_to_regnum */ +- 0, /* ecoff_reg_to_regnum */ +- 0, /* dwarf_reg_to_regnum */ +- 0, /* sdb_reg_to_regnum */ +- 0, /* dwarf2_reg_to_regnum */ ++ no_op_reg_to_regnum, /* stab_reg_to_regnum */ ++ no_op_reg_to_regnum, /* ecoff_reg_to_regnum */ ++ no_op_reg_to_regnum, /* dwarf_reg_to_regnum */ ++ no_op_reg_to_regnum, /* sdb_reg_to_regnum */ ++ no_op_reg_to_regnum, /* dwarf2_reg_to_regnum */ + 0, /* register_name */ + 0, /* register_type */ + 0, /* unwind_dummy_id */ +@@ -292,12 +292,12 @@ struct gdbarch startup_gdbarch = + default_print_registers_info, /* print_registers_info */ + 0, /* print_float_info */ + 0, /* print_vector_info */ +- 0, /* register_sim_regno */ +- 0, /* cannot_fetch_register */ +- 0, /* cannot_store_register */ ++ legacy_register_sim_regno, /* register_sim_regno */ ++ cannot_register_not, /* cannot_fetch_register */ ++ cannot_register_not, /* cannot_store_register */ + 0, /* get_longjmp_target */ + 0, /* believe_pcc_promotion */ +- 0, /* convert_register_p */ ++ generic_convert_register_p, /* convert_register_p */ + 0, /* register_to_value */ + 0, /* value_to_register */ + 0, /* value_from_register */ +@@ -312,8 +312,8 @@ struct gdbarch startup_gdbarch = + 0, /* inner_than */ + 0, /* breakpoint_from_pc */ + 0, /* adjust_breakpoint_address */ +- 0, /* memory_insert_breakpoint */ +- 0, /* memory_remove_breakpoint */ ++ default_memory_insert_breakpoint, /* memory_insert_breakpoint */ ++ default_memory_remove_breakpoint, /* memory_remove_breakpoint */ + 0, /* decr_pc_after_break */ + 0, /* deprecated_function_start_offset */ + default_remote_register_number, /* remote_register_number */ +@@ -531,6 +531,8 @@ verify_gdbarch (struct gdbarch *current_ + /* Skip verify of dwarf_reg_to_regnum, invalid_p == 0 */ + /* Skip verify of sdb_reg_to_regnum, invalid_p == 0 */ + /* Skip verify of dwarf2_reg_to_regnum, invalid_p == 0 */ ++ if (current_gdbarch->register_name == 0) ++ fprintf_unfiltered (log, "\n\tregister_name"); + /* Skip verify of register_type, has predicate */ + /* Skip verify of unwind_dummy_id, has predicate */ + /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ +@@ -1360,7 +1362,7 @@ gdbarch_virtual_frame_pointer (struct gd + gdb_assert (gdbarch->virtual_frame_pointer != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_virtual_frame_pointer called\n"); +- gdbarch->virtual_frame_pointer (pc, frame_regnum, frame_offset); ++ gdbarch->virtual_frame_pointer (gdbarch, pc, frame_regnum, frame_offset); + } + + void +@@ -1528,7 +1530,7 @@ gdbarch_stab_reg_to_regnum (struct gdbar + gdb_assert (gdbarch->stab_reg_to_regnum != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_stab_reg_to_regnum called\n"); +- return gdbarch->stab_reg_to_regnum (stab_regnr); ++ return gdbarch->stab_reg_to_regnum (gdbarch, stab_regnr); + } + + void +@@ -1545,7 +1547,7 @@ gdbarch_ecoff_reg_to_regnum (struct gdba + gdb_assert (gdbarch->ecoff_reg_to_regnum != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_ecoff_reg_to_regnum called\n"); +- return gdbarch->ecoff_reg_to_regnum (ecoff_regnr); ++ return gdbarch->ecoff_reg_to_regnum (gdbarch, ecoff_regnr); + } + + void +@@ -1562,7 +1564,7 @@ gdbarch_dwarf_reg_to_regnum (struct gdba + gdb_assert (gdbarch->dwarf_reg_to_regnum != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf_reg_to_regnum called\n"); +- return gdbarch->dwarf_reg_to_regnum (dwarf_regnr); ++ return gdbarch->dwarf_reg_to_regnum (gdbarch, dwarf_regnr); + } + + void +@@ -1579,7 +1581,7 @@ gdbarch_sdb_reg_to_regnum (struct gdbarc + gdb_assert (gdbarch->sdb_reg_to_regnum != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_sdb_reg_to_regnum called\n"); +- return gdbarch->sdb_reg_to_regnum (sdb_regnr); ++ return gdbarch->sdb_reg_to_regnum (gdbarch, sdb_regnr); + } + + void +@@ -1596,7 +1598,7 @@ gdbarch_dwarf2_reg_to_regnum (struct gdb + gdb_assert (gdbarch->dwarf2_reg_to_regnum != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf2_reg_to_regnum called\n"); +- return gdbarch->dwarf2_reg_to_regnum (dwarf2_regnr); ++ return gdbarch->dwarf2_reg_to_regnum (gdbarch, dwarf2_regnr); + } + + void +@@ -1613,7 +1615,7 @@ gdbarch_register_name (struct gdbarch *g + gdb_assert (gdbarch->register_name != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_name called\n"); +- return gdbarch->register_name (regnr); ++ return gdbarch->register_name (gdbarch, regnr); + } + + void +@@ -1825,7 +1827,7 @@ gdbarch_register_sim_regno (struct gdbar + gdb_assert (gdbarch->register_sim_regno != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_register_sim_regno called\n"); +- return gdbarch->register_sim_regno (reg_nr); ++ return gdbarch->register_sim_regno (gdbarch, reg_nr); + } + + void +@@ -1842,7 +1844,7 @@ gdbarch_cannot_fetch_register (struct gd + gdb_assert (gdbarch->cannot_fetch_register != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_fetch_register called\n"); +- return gdbarch->cannot_fetch_register (regnum); ++ return gdbarch->cannot_fetch_register (gdbarch, regnum); + } + + void +@@ -1859,7 +1861,7 @@ gdbarch_cannot_store_register (struct gd + gdb_assert (gdbarch->cannot_store_register != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_cannot_store_register called\n"); +- return gdbarch->cannot_store_register (regnum); ++ return gdbarch->cannot_store_register (gdbarch, regnum); + } + + void +@@ -1916,7 +1918,7 @@ gdbarch_convert_register_p (struct gdbar + gdb_assert (gdbarch->convert_register_p != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_register_p called\n"); +- return gdbarch->convert_register_p (regnum, type); ++ return gdbarch->convert_register_p (gdbarch, regnum, type); + } + + void +@@ -2118,7 +2120,7 @@ gdbarch_skip_prologue (struct gdbarch *g + gdb_assert (gdbarch->skip_prologue != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_skip_prologue called\n"); +- return gdbarch->skip_prologue (ip); ++ return gdbarch->skip_prologue (gdbarch, ip); + } + + void +@@ -2152,7 +2154,7 @@ gdbarch_breakpoint_from_pc (struct gdbar + gdb_assert (gdbarch->breakpoint_from_pc != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_breakpoint_from_pc called\n"); +- return gdbarch->breakpoint_from_pc (pcptr, lenptr); ++ return gdbarch->breakpoint_from_pc (gdbarch, pcptr, lenptr); + } + + void +@@ -2193,7 +2195,7 @@ gdbarch_memory_insert_breakpoint (struct + gdb_assert (gdbarch->memory_insert_breakpoint != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_insert_breakpoint called\n"); +- return gdbarch->memory_insert_breakpoint (bp_tgt); ++ return gdbarch->memory_insert_breakpoint (gdbarch, bp_tgt); + } + + void +@@ -2210,7 +2212,7 @@ gdbarch_memory_remove_breakpoint (struct + gdb_assert (gdbarch->memory_remove_breakpoint != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_memory_remove_breakpoint called\n"); +- return gdbarch->memory_remove_breakpoint (bp_tgt); ++ return gdbarch->memory_remove_breakpoint (gdbarch, bp_tgt); + } + + void +diff -urNp src-orig/gdb/gdbarch.h src/gdb/gdbarch.h +--- src-orig/gdb/gdbarch.h 2007-06-28 03:23:18.934483042 +0200 ++++ src/gdb/gdbarch.h 2007-06-28 01:54:00.768062967 +0200 +@@ -162,7 +162,7 @@ extern void set_gdbarch_write_pc (struct + whole scheme for dealing with "frames" and "frame pointers" needs a + serious shakedown. */ + +-typedef void (gdbarch_virtual_frame_pointer_ftype) (CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset); ++typedef void (gdbarch_virtual_frame_pointer_ftype) (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset); + extern void gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset); + extern void set_gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer); + +@@ -208,33 +208,33 @@ extern void set_gdbarch_fp0_regnum (stru + + /* Convert stab register number (from `r' declaration) to a gdb REGNUM. */ + +-typedef int (gdbarch_stab_reg_to_regnum_ftype) (int stab_regnr); ++typedef int (gdbarch_stab_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int stab_regnr); + extern int gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, int stab_regnr); + extern void set_gdbarch_stab_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_stab_reg_to_regnum_ftype *stab_reg_to_regnum); + + /* Provide a default mapping from a ecoff register number to a gdb REGNUM. */ + +-typedef int (gdbarch_ecoff_reg_to_regnum_ftype) (int ecoff_regnr); ++typedef int (gdbarch_ecoff_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int ecoff_regnr); + extern int gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int ecoff_regnr); + extern void set_gdbarch_ecoff_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_ecoff_reg_to_regnum_ftype *ecoff_reg_to_regnum); + + /* Provide a default mapping from a DWARF register number to a gdb REGNUM. */ + +-typedef int (gdbarch_dwarf_reg_to_regnum_ftype) (int dwarf_regnr); ++typedef int (gdbarch_dwarf_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int dwarf_regnr); + extern int gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_regnr); + extern void set_gdbarch_dwarf_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_dwarf_reg_to_regnum_ftype *dwarf_reg_to_regnum); + + /* Convert from an sdb register number to an internal gdb register number. */ + +-typedef int (gdbarch_sdb_reg_to_regnum_ftype) (int sdb_regnr); ++typedef int (gdbarch_sdb_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int sdb_regnr); + extern int gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, int sdb_regnr); + extern void set_gdbarch_sdb_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_sdb_reg_to_regnum_ftype *sdb_reg_to_regnum); + +-typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (int dwarf2_regnr); ++typedef int (gdbarch_dwarf2_reg_to_regnum_ftype) (struct gdbarch *gdbarch, int dwarf2_regnr); + extern int gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2_regnr); + extern void set_gdbarch_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, gdbarch_dwarf2_reg_to_regnum_ftype *dwarf2_reg_to_regnum); + +-typedef const char * (gdbarch_register_name_ftype) (int regnr); ++typedef const char * (gdbarch_register_name_ftype) (struct gdbarch *gdbarch, int regnr); + extern const char * gdbarch_register_name (struct gdbarch *gdbarch, int regnr); + extern void set_gdbarch_register_name (struct gdbarch *gdbarch, gdbarch_register_name_ftype *register_name); + +@@ -298,15 +298,15 @@ extern void set_gdbarch_print_vector_inf + /* MAP a GDB RAW register number onto a simulator register number. See + also include/...-sim.h. */ + +-typedef int (gdbarch_register_sim_regno_ftype) (int reg_nr); ++typedef int (gdbarch_register_sim_regno_ftype) (struct gdbarch *gdbarch, int reg_nr); + extern int gdbarch_register_sim_regno (struct gdbarch *gdbarch, int reg_nr); + extern void set_gdbarch_register_sim_regno (struct gdbarch *gdbarch, gdbarch_register_sim_regno_ftype *register_sim_regno); + +-typedef int (gdbarch_cannot_fetch_register_ftype) (int regnum); ++typedef int (gdbarch_cannot_fetch_register_ftype) (struct gdbarch *gdbarch, int regnum); + extern int gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, int regnum); + extern void set_gdbarch_cannot_fetch_register (struct gdbarch *gdbarch, gdbarch_cannot_fetch_register_ftype *cannot_fetch_register); + +-typedef int (gdbarch_cannot_store_register_ftype) (int regnum); ++typedef int (gdbarch_cannot_store_register_ftype) (struct gdbarch *gdbarch, int regnum); + extern int gdbarch_cannot_store_register (struct gdbarch *gdbarch, int regnum); + extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_cannot_store_register_ftype *cannot_store_register); + +@@ -321,7 +321,7 @@ extern void set_gdbarch_get_longjmp_targ + extern int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch); + extern void set_gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch, int believe_pcc_promotion); + +-typedef int (gdbarch_convert_register_p_ftype) (int regnum, struct type *type); ++typedef int (gdbarch_convert_register_p_ftype) (struct gdbarch *gdbarch, int regnum, struct type *type); + extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type); + extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p); + +@@ -386,7 +386,7 @@ typedef int (gdbarch_deprecated_use_stru + extern int gdbarch_deprecated_use_struct_convention (struct gdbarch *gdbarch, int gcc_p, struct type *value_type); + extern void set_gdbarch_deprecated_use_struct_convention (struct gdbarch *gdbarch, gdbarch_deprecated_use_struct_convention_ftype *deprecated_use_struct_convention); + +-typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (CORE_ADDR ip); ++typedef CORE_ADDR (gdbarch_skip_prologue_ftype) (struct gdbarch *gdbarch, CORE_ADDR ip); + extern CORE_ADDR gdbarch_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip); + extern void set_gdbarch_skip_prologue (struct gdbarch *gdbarch, gdbarch_skip_prologue_ftype *skip_prologue); + +@@ -394,7 +394,7 @@ typedef int (gdbarch_inner_than_ftype) ( + extern int gdbarch_inner_than (struct gdbarch *gdbarch, CORE_ADDR lhs, CORE_ADDR rhs); + extern void set_gdbarch_inner_than (struct gdbarch *gdbarch, gdbarch_inner_than_ftype *inner_than); + +-typedef const gdb_byte * (gdbarch_breakpoint_from_pc_ftype) (CORE_ADDR *pcptr, int *lenptr); ++typedef const gdb_byte * (gdbarch_breakpoint_from_pc_ftype) (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr); + extern const gdb_byte * gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr); + extern void set_gdbarch_breakpoint_from_pc (struct gdbarch *gdbarch, gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc); + +@@ -404,11 +404,11 @@ typedef CORE_ADDR (gdbarch_adjust_breakp + extern CORE_ADDR gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr); + extern void set_gdbarch_adjust_breakpoint_address (struct gdbarch *gdbarch, gdbarch_adjust_breakpoint_address_ftype *adjust_breakpoint_address); + +-typedef int (gdbarch_memory_insert_breakpoint_ftype) (struct bp_target_info *bp_tgt); ++typedef int (gdbarch_memory_insert_breakpoint_ftype) (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); + extern int gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); + extern void set_gdbarch_memory_insert_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint); + +-typedef int (gdbarch_memory_remove_breakpoint_ftype) (struct bp_target_info *bp_tgt); ++typedef int (gdbarch_memory_remove_breakpoint_ftype) (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); + extern int gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt); + extern void set_gdbarch_memory_remove_breakpoint (struct gdbarch *gdbarch, gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint); + +diff -urNp src-orig/gdb/gdbarch.sh src/gdb/gdbarch.sh +--- src-orig/gdb/gdbarch.sh 2007-06-28 03:23:18.943481745 +0200 ++++ src/gdb/gdbarch.sh 2007-06-28 01:54:00.778061526 +0200 +@@ -423,7 +423,7 @@ F::void:write_pc:struct regcache *regcac + # Function for getting target's idea of a frame pointer. FIXME: GDB's + # whole scheme for dealing with "frames" and "frame pointers" needs a + # serious shakedown. +-f::void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset:0:legacy_virtual_frame_pointer::0 ++m::void:virtual_frame_pointer:CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset:pc, frame_regnum, frame_offset:0:legacy_virtual_frame_pointer::0 + # + M::void:pseudo_register_read:struct regcache *regcache, int cookednum, gdb_byte *buf:regcache, cookednum, buf + M::void:pseudo_register_write:struct regcache *regcache, int cookednum, const gdb_byte *buf:regcache, cookednum, buf +@@ -444,15 +444,15 @@ v::int:pc_regnum:::-1:-1::0 + v::int:ps_regnum:::-1:-1::0 + v::int:fp0_regnum:::0:-1::0 + # Convert stab register number (from \`r\' declaration) to a gdb REGNUM. +-f::int:stab_reg_to_regnum:int stab_regnr:stab_regnr::no_op_reg_to_regnum::0 ++m::int:stab_reg_to_regnum:int stab_regnr:stab_regnr::no_op_reg_to_regnum::0 + # Provide a default mapping from a ecoff register number to a gdb REGNUM. +-f::int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr::no_op_reg_to_regnum::0 ++m::int:ecoff_reg_to_regnum:int ecoff_regnr:ecoff_regnr::no_op_reg_to_regnum::0 + # Provide a default mapping from a DWARF register number to a gdb REGNUM. +-f::int:dwarf_reg_to_regnum:int dwarf_regnr:dwarf_regnr::no_op_reg_to_regnum::0 ++m::int:dwarf_reg_to_regnum:int dwarf_regnr:dwarf_regnr::no_op_reg_to_regnum::0 + # Convert from an sdb register number to an internal gdb register number. +-f::int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr::no_op_reg_to_regnum::0 +-f::int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr::no_op_reg_to_regnum::0 +-f::const char *:register_name:int regnr:regnr ++m::int:sdb_reg_to_regnum:int sdb_regnr:sdb_regnr::no_op_reg_to_regnum::0 ++m::int:dwarf2_reg_to_regnum:int dwarf2_regnr:dwarf2_regnr::no_op_reg_to_regnum::0 ++m::const char *:register_name:int regnr:regnr:0:0 + + # Return the type of a register specified by the architecture. Only + # the register cache should call this function directly; others should +@@ -475,15 +475,15 @@ M::void:print_float_info:struct ui_file + M::void:print_vector_info:struct ui_file *file, struct frame_info *frame, const char *args:file, frame, args + # MAP a GDB RAW register number onto a simulator register number. See + # also include/...-sim.h. +-f::int:register_sim_regno:int reg_nr:reg_nr::legacy_register_sim_regno::0 +-f::int:cannot_fetch_register:int regnum:regnum::cannot_register_not::0 +-f::int:cannot_store_register:int regnum:regnum::cannot_register_not::0 ++m::int:register_sim_regno:int reg_nr:reg_nr::legacy_register_sim_regno::0 ++m::int:cannot_fetch_register:int regnum:regnum::cannot_register_not::0 ++m::int:cannot_store_register:int regnum:regnum::cannot_register_not::0 + # setjmp/longjmp support. + F::int:get_longjmp_target:struct frame_info *frame, CORE_ADDR *pc:frame, pc + # + v::int:believe_pcc_promotion::::::: + # +-f::int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0 ++m::int:convert_register_p:int regnum, struct type *type:regnum, type:0:generic_convert_register_p::0 + f::void:register_to_value:struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf:frame, regnum, type, buf:0 + f::void:value_to_register:struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf:frame, regnum, type, buf:0 + # Construct a value representing the contents of register REGNUM in +@@ -515,12 +515,12 @@ f::void:extract_return_value:struct type + f::void:store_return_value:struct type *type, struct regcache *regcache, const gdb_byte *valbuf:type, regcache, valbuf:0 + f::int:deprecated_use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type::generic_use_struct_convention::0 + +-f::CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 ++m::CORE_ADDR:skip_prologue:CORE_ADDR ip:ip:0:0 + f::int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs:0:0 +-f::const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: ++m::const gdb_byte *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr::0: + M::CORE_ADDR:adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr +-f::int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0 +-f::int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0 ++m::int:memory_insert_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_insert_breakpoint::0 ++m::int:memory_remove_breakpoint:struct bp_target_info *bp_tgt:bp_tgt:0:default_memory_remove_breakpoint::0 + v::CORE_ADDR:decr_pc_after_break:::0:::0 + + # A function can be addressed by either it's "pointer" (possibly a +diff -urNp src-orig/gdb/h8300-tdep.c src/gdb/h8300-tdep.c +--- src-orig/gdb/h8300-tdep.c 2007-06-28 03:23:18.949480881 +0200 ++++ src/gdb/h8300-tdep.c 2007-06-28 01:54:00.786060373 +0200 +@@ -565,7 +565,7 @@ static const struct frame_base h8300_fra + }; + + static CORE_ADDR +-h8300_skip_prologue (CORE_ADDR pc) ++h8300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr = 0 , func_end = 0; + +@@ -948,7 +948,7 @@ h8300h_return_value (struct gdbarch *gdb + static struct cmd_list_element *setmachinelist; + + static const char * +-h8300_register_name (int regno) ++h8300_register_name (struct gdbarch *gdbarch, int regno) + { + /* The register names change depending on which h8300 processor + type is selected. */ +@@ -966,7 +966,7 @@ h8300_register_name (int regno) + } + + static const char * +-h8300s_register_name (int regno) ++h8300s_register_name (struct gdbarch *gdbarch, int regno) + { + static char *register_names[] = { + "er0", "er1", "er2", "er3", "er4", "er5", "er6", +@@ -984,7 +984,7 @@ h8300s_register_name (int regno) + } + + static const char * +-h8300sx_register_name (int regno) ++h8300sx_register_name (struct gdbarch *gdbarch, int regno) + { + static char *register_names[] = { + "er0", "er1", "er2", "er3", "er4", "er5", "er6", +@@ -1176,7 +1176,7 @@ h8300_pseudo_register_write (struct gdba + } + + static int +-h8300_dbg_reg_to_regnum (int regno) ++h8300_dbg_reg_to_regnum (struct gdbarch *gdbarch, int regno) + { + if (regno == E_CCR_REGNUM) + return E_PSEUDO_CCR_REGNUM; +@@ -1184,7 +1184,7 @@ h8300_dbg_reg_to_regnum (int regno) + } + + static int +-h8300s_dbg_reg_to_regnum (int regno) ++h8300s_dbg_reg_to_regnum (struct gdbarch *gdbarch, int regno) + { + if (regno == E_CCR_REGNUM) + return E_PSEUDO_CCR_REGNUM; +@@ -1194,7 +1194,7 @@ h8300s_dbg_reg_to_regnum (int regno) + } + + const static unsigned char * +-h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++h8300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + /*static unsigned char breakpoint[] = { 0x7A, 0xFF }; *//* ??? */ + static unsigned char breakpoint[] = { 0x01, 0x80 }; /* Sleep */ +diff -urNp src-orig/gdb/hppa-linux-tdep.c src/gdb/hppa-linux-tdep.c +--- src-orig/gdb/hppa-linux-tdep.c 2007-06-28 03:23:18.954480161 +0200 ++++ src/gdb/hppa-linux-tdep.c 2007-06-28 01:54:00.791059653 +0200 +@@ -40,7 +40,7 @@ + /* Convert DWARF register number REG to the appropriate register + number used by GDB. */ + static int +-hppa_dwarf_reg_to_regnum (int reg) ++hppa_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* registers 0 - 31 are the same in both sets */ + if (reg < 32) +diff -urNp src-orig/gdb/hppa-tdep.c src/gdb/hppa-tdep.c +--- src-orig/gdb/hppa-tdep.c 2007-06-28 03:23:18.964478721 +0200 ++++ src/gdb/hppa-tdep.c 2007-06-28 01:54:00.803057924 +0200 +@@ -577,7 +577,7 @@ hppa_in_function_epilogue_p (struct gdba + } + + static const unsigned char * +-hppa_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++hppa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static const unsigned char breakpoint[] = {0x00, 0x01, 0x00, 0x04}; + (*len) = sizeof (breakpoint); +@@ -587,7 +587,7 @@ hppa_breakpoint_from_pc (CORE_ADDR *pc, + /* Return the name of a register. */ + + static const char * +-hppa32_register_name (int i) ++hppa32_register_name (struct gdbarch *gdbarch, int i) + { + static char *names[] = { + "flags", "r1", "rp", "r3", +@@ -630,7 +630,7 @@ hppa32_register_name (int i) + } + + static const char * +-hppa64_register_name (int i) ++hppa64_register_name (struct gdbarch *gdbarch, int i) + { + static char *names[] = { + "flags", "r1", "rp", "r3", +@@ -665,7 +665,7 @@ hppa64_register_name (int i) + } + + static int +-hppa64_dwarf_reg_to_regnum (int reg) ++hppa64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* r0-r31 and sar map one-to-one. */ + if (reg <= 32) +@@ -1765,7 +1765,7 @@ after_prologue (CORE_ADDR pc) + skip over the branch in that case. */ + + static CORE_ADDR +-hppa_skip_prologue (CORE_ADDR pc) ++hppa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + unsigned long inst; + int offset; +@@ -2667,7 +2667,7 @@ hppa64_register_type (struct gdbarch *gd + through ptrace/ttrace. */ + + static int +-hppa32_cannot_store_register (int regnum) ++hppa32_cannot_store_register (struct gdbarch *gdbarch, int regnum) + { + return (regnum == 0 + || regnum == HPPA_PCSQ_HEAD_REGNUM +@@ -2676,7 +2676,7 @@ hppa32_cannot_store_register (int regnum + } + + static int +-hppa64_cannot_store_register (int regnum) ++hppa64_cannot_store_register (struct gdbarch *gdbarch, int regnum) + { + return (regnum == 0 + || regnum == HPPA_PCSQ_HEAD_REGNUM +diff -urNp src-orig/gdb/i386-linux-tdep.c src/gdb/i386-linux-tdep.c +--- src-orig/gdb/i386-linux-tdep.c 2007-06-28 03:23:18.969478001 +0200 ++++ src/gdb/i386-linux-tdep.c 2007-06-28 01:54:00.809057060 +0200 +@@ -40,13 +40,13 @@ + /* Return the name of register REG. */ + + static const char * +-i386_linux_register_name (int reg) ++i386_linux_register_name (struct gdbarch *gdbarch, int reg) + { + /* Deal with the extra "orig_eax" pseudo register. */ + if (reg == I386_LINUX_ORIG_EAX_REGNUM) + return "orig_eax"; + +- return i386_register_name (reg); ++ return i386_register_name (gdbarch, reg); + } + + /* Return non-zero, when the register is in the corresponding register +diff -urNp src-orig/gdb/i386-tdep.c src/gdb/i386-tdep.c +--- src-orig/gdb/i386-tdep.c 2007-06-28 03:23:18.977476849 +0200 ++++ src/gdb/i386-tdep.c 2007-06-28 01:54:00.819055619 +0200 +@@ -154,7 +154,7 @@ i386_fpc_regnum_p (int regnum) + /* Return the name of register REGNUM. */ + + const char * +-i386_register_name (int regnum) ++i386_register_name (struct gdbarch *gdbarch, int regnum) + { + if (i386_mmx_regnum_p (current_gdbarch, regnum)) + return i386_mmx_names[regnum - I387_MM0_REGNUM]; +@@ -169,7 +169,7 @@ i386_register_name (int regnum) + number used by GDB. */ + + static int +-i386_dbx_reg_to_regnum (int reg) ++i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* This implements what GCC calls the "default" register map + (dbx_register_map[]). */ +@@ -209,7 +209,7 @@ i386_dbx_reg_to_regnum (int reg) + used by GDB. */ + + static int +-i386_svr4_reg_to_regnum (int reg) ++i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + /* This implements the GCC register map that tries to be compatible + with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]). */ +@@ -229,7 +229,7 @@ i386_svr4_reg_to_regnum (int reg) + else if (reg >= 21 && reg <= 36) + { + /* The SSE and MMX registers have the same numbers as with dbx. */ +- return i386_dbx_reg_to_regnum (reg); ++ return i386_dbx_reg_to_regnum (gdbarch, reg); + } + + switch (reg) +@@ -280,7 +280,7 @@ static const char *disassembly_flavor = + This function is 64-bit safe. */ + + static const gdb_byte * +-i386_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++i386_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static gdb_byte break_insn[] = { 0xcc }; /* int 3 */ + +@@ -832,7 +832,7 @@ i386_analyze_prologue (CORE_ADDR pc, COR + /* Return PC of first real instruction. */ + + static CORE_ADDR +-i386_skip_prologue (CORE_ADDR start_pc) ++i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + static gdb_byte pic_pat[6] = + { +@@ -1859,7 +1859,7 @@ i386_next_regnum (int regnum) + needs any special handling. */ + + static int +-i386_convert_register_p (int regnum, struct type *type) ++i386_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) + { + int len = TYPE_LENGTH (type); + +diff -urNp src-orig/gdb/i386-tdep.h src/gdb/i386-tdep.h +--- src-orig/gdb/i386-tdep.h 2007-06-28 03:23:18.982476129 +0200 ++++ src/gdb/i386-tdep.h 2007-06-28 01:54:00.824054899 +0200 +@@ -170,7 +170,7 @@ extern struct type *i386_sse_type (struc + extern CORE_ADDR i386_pe_skip_trampoline_code (CORE_ADDR pc, char *name); + + /* Return the name of register REGNUM. */ +-extern char const *i386_register_name (int regnum); ++extern char const *i386_register_name (struct gdbarch *gdbarch, int regnum); + + /* Return non-zero if REGNUM is a member of the specified group. */ + extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum, +diff -urNp src-orig/gdb/ia64-tdep.c src/gdb/ia64-tdep.c +--- src-orig/gdb/ia64-tdep.c 2007-06-28 03:23:18.992474689 +0200 ++++ src/gdb/ia64-tdep.c 2007-06-28 01:54:00.837053026 +0200 +@@ -303,7 +303,7 @@ ia64_register_reggroup_p (struct gdbarch + } + + static const char * +-ia64_register_name (int reg) ++ia64_register_name (struct gdbarch *gdbarch, int reg) + { + return ia64_register_names[reg]; + } +@@ -318,7 +318,7 @@ ia64_register_type (struct gdbarch *arch + } + + static int +-ia64_dwarf_reg_to_regnum (int reg) ++ia64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM) + return V32_REGNUM + (reg - IA64_GR32_REGNUM); +@@ -558,7 +558,8 @@ fetch_instruction (CORE_ADDR addr, instr + #define IA64_BREAKPOINT 0x00003333300LL + + static int +-ia64_memory_insert_breakpoint (struct bp_target_info *bp_tgt) ++ia64_memory_insert_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + CORE_ADDR addr = bp_tgt->placed_address; + char bundle[BUNDLE_LEN]; +@@ -593,7 +594,8 @@ ia64_memory_insert_breakpoint (struct bp + } + + static int +-ia64_memory_remove_breakpoint (struct bp_target_info *bp_tgt) ++ia64_memory_remove_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + CORE_ADDR addr = bp_tgt->placed_address; + char bundle[BUNDLE_LEN]; +@@ -625,7 +627,7 @@ ia64_memory_remove_breakpoint (struct bp + /* We don't really want to use this, but remote.c needs to call it in order + to figure out if Z-packets are supported or not. Oh, well. */ + const unsigned char * +-ia64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++ia64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char breakpoint[] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +@@ -923,7 +925,7 @@ ia64_pseudo_register_write (struct gdbar + and the special ia64 floating point register format. */ + + static int +-ia64_convert_register_p (int regno, struct type *type) ++ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type) + { + return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM); + } +@@ -1510,7 +1512,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADD + } + + CORE_ADDR +-ia64_skip_prologue (CORE_ADDR pc) ++ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + struct ia64_frame_cache cache; + cache.base = 0; +diff -urNp src-orig/gdb/iq2000-tdep.c src/gdb/iq2000-tdep.c +--- src-orig/gdb/iq2000-tdep.c 2007-06-28 03:23:18.997473969 +0200 ++++ src/gdb/iq2000-tdep.c 2007-06-28 01:54:00.843052162 +0200 +@@ -120,7 +120,7 @@ iq2000_address_to_pointer (struct type * + Returns the name of the iq2000 register number N. */ + + static const char * +-iq2000_register_name (int regnum) ++iq2000_register_name (struct gdbarch *gdbarch, int regnum) + { + static const char * names[E_NUM_REGS] = + { +@@ -333,7 +333,7 @@ iq2000_init_frame_cache (struct iq2000_f + stepped into a function call. */ + + static CORE_ADDR +-iq2000_skip_prologue (CORE_ADDR pc) ++iq2000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr = 0 , func_end = 0; + +@@ -491,7 +491,7 @@ static const struct frame_base iq2000_fr + }; + + static const unsigned char * +-iq2000_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++iq2000_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static const unsigned char big_breakpoint[] = { 0x00, 0x00, 0x00, 0x0d }; + static const unsigned char little_breakpoint[] = { 0x0d, 0x00, 0x00, 0x00 }; +diff -urNp src-orig/gdb/m32c-tdep.c src/gdb/m32c-tdep.c +--- src-orig/gdb/m32c-tdep.c 2007-06-28 03:23:19.006472672 +0200 ++++ src/gdb/m32c-tdep.c 2007-06-28 01:54:00.854050577 +0200 +@@ -229,7 +229,7 @@ make_types (struct gdbarch *arch) + /* Register set. */ + + static const char * +-m32c_register_name (int num) ++m32c_register_name (struct gdbarch *gdbarch, int num) + { + return gdbarch_tdep (current_gdbarch)->regs[num].name; + } +@@ -243,14 +243,14 @@ m32c_register_type (struct gdbarch *arch + + + static int +-m32c_register_sim_regno (int reg_nr) ++m32c_register_sim_regno (struct gdbarch *gdbarch, int reg_nr) + { + return gdbarch_tdep (current_gdbarch)->regs[reg_nr].sim_num; + } + + + static int +-m32c_debug_info_reg_to_regnum (int reg_nr) ++m32c_debug_info_reg_to_regnum (struct gdbarch *gdbarch, int reg_nr) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + if (0 <= reg_nr && reg_nr <= M32C_MAX_DWARF_REGNUM +@@ -978,7 +978,7 @@ make_regs (struct gdbarch *arch) + /* Breakpoints. */ + + static const unsigned char * +-m32c_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++m32c_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static unsigned char break_insn[] = { 0x00 }; /* brk */ + +@@ -1805,7 +1805,7 @@ m32c_analyze_prologue (struct gdbarch *a + + + static CORE_ADDR +-m32c_skip_prologue (CORE_ADDR ip) ++m32c_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip) + { + char *name; + CORE_ADDR func_addr, func_end, sal_end; +@@ -2527,7 +2527,8 @@ m32c_m16c_pointer_to_address (struct typ + } + + void +-m32c_virtual_frame_pointer (CORE_ADDR pc, ++m32c_virtual_frame_pointer (struct gdbarch *gdbarch, ++ CORE_ADDR pc, + int *frame_regnum, + LONGEST *frame_offset) + { +diff -urNp src-orig/gdb/m32r-tdep.c src/gdb/m32r-tdep.c +--- src-orig/gdb/m32r-tdep.c 2007-06-28 03:23:19.012471808 +0200 ++++ src/gdb/m32r-tdep.c 2007-06-28 01:54:00.861049568 +0200 +@@ -81,7 +81,8 @@ m32r_frame_align (struct gdbarch *gdbarc + The following functions take care of this behavior. */ + + static int +-m32r_memory_insert_breakpoint (struct bp_target_info *bp_tgt) ++m32r_memory_insert_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + CORE_ADDR addr = bp_tgt->placed_address; + int val; +@@ -138,7 +139,8 @@ m32r_memory_insert_breakpoint (struct bp + } + + static int +-m32r_memory_remove_breakpoint (struct bp_target_info *bp_tgt) ++m32r_memory_remove_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + CORE_ADDR addr = bp_tgt->placed_address; + int val; +@@ -168,7 +170,7 @@ m32r_memory_remove_breakpoint (struct bp + } + + static const gdb_byte * +-m32r_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++m32r_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static gdb_byte be_bp_entry[] = { 0x10, 0xf1, 0x70, 0x00 }; /* dpt -> nop */ + static gdb_byte le_bp_entry[] = { 0x00, 0x70, 0xf1, 0x10 }; /* dpt -> nop */ +@@ -214,7 +216,7 @@ char *m32r_register_names[] = { + }; + + static const char * +-m32r_register_name (int reg_nr) ++m32r_register_name (struct gdbarch *gdbarch, int reg_nr) + { + if (reg_nr < 0) + return NULL; +@@ -450,7 +452,7 @@ decode_prologue (CORE_ADDR start_pc, COR + #define DEFAULT_SEARCH_LIMIT 128 + + CORE_ADDR +-m32r_skip_prologue (CORE_ADDR pc) ++m32r_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end; + struct symtab_and_line sal; +diff -urNp src-orig/gdb/m68hc11-tdep.c src/gdb/m68hc11-tdep.c +--- src-orig/gdb/m68hc11-tdep.c 2007-06-28 03:23:19.019470800 +0200 ++++ src/gdb/m68hc11-tdep.c 2007-06-28 01:54:00.869048416 +0200 +@@ -367,7 +367,7 @@ m68hc11_pseudo_register_write (struct gd + } + + static const char * +-m68hc11_register_name (int reg_nr) ++m68hc11_register_name (struct gdbarch *gdbarch, int reg_nr) + { + if (reg_nr == M68HC12_HARD_PC_REGNUM && USE_PAGE_REGISTER) + return "pc"; +@@ -389,7 +389,7 @@ m68hc11_register_name (int reg_nr) + } + + static const unsigned char * +-m68hc11_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++m68hc11_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char breakpoint[] = {0x0}; + +@@ -740,7 +740,7 @@ m68hc11_scan_prologue (CORE_ADDR pc, COR + } + + static CORE_ADDR +-m68hc11_skip_prologue (CORE_ADDR pc) ++m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end; + struct symtab_and_line sal; +@@ -1398,13 +1398,14 @@ m68hc11_register_reggroup_p (struct gdba + || regnum == SOFT_TMP_REGNUM + || regnum == SOFT_ZS_REGNUM + || regnum == SOFT_XY_REGNUM) +- && m68hc11_register_name (regnum))); ++ && m68hc11_register_name (gdbarch, regnum))); + } + + /* Group to identify gcc soft registers (d1..dN). */ + if (group == m68hc11_soft_reggroup) + { +- return regnum >= SOFT_D1_REGNUM && m68hc11_register_name (regnum); ++ return regnum >= SOFT_D1_REGNUM ++ && m68hc11_register_name (gdbarch, regnum); + } + + if (group == m68hc11_hard_reggroup) +diff -urNp src-orig/gdb/m68k-tdep.c src/gdb/m68k-tdep.c +--- src-orig/gdb/m68k-tdep.c 2007-06-28 03:23:19.025469936 +0200 ++++ src/gdb/m68k-tdep.c 2007-06-28 01:54:00.876047407 +0200 +@@ -63,7 +63,8 @@ + #endif + + static const gdb_byte * +-m68k_local_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++m68k_local_breakpoint_from_pc (struct gdbarch *gdbarch, ++ CORE_ADDR *pcptr, int *lenptr) + { + static gdb_byte break_insn[] = {0x4e, (0x40 | BPT_VECTOR)}; + *lenptr = sizeof (break_insn); +@@ -127,7 +128,7 @@ static const char *m68k_register_names[] + Returns the name of the standard m68k register regnum. */ + + static const char * +-m68k_register_name (int regnum) ++m68k_register_name (struct gdbarch *gdbarch, int regnum) + { + if (regnum < 0 || regnum >= ARRAY_SIZE (m68k_register_names)) + internal_error (__FILE__, __LINE__, +@@ -140,7 +141,7 @@ m68k_register_name (int regnum) + needs any special handling. */ + + static int +-m68k_convert_register_p (int regnum, struct type *type) ++m68k_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) + { + if (!gdbarch_tdep (current_gdbarch)->fpregs_present) + return 0; +@@ -498,7 +499,7 @@ m68k_push_dummy_call (struct gdbarch *gd + /* Convert a dwarf or dwarf2 regnumber to a GDB regnum. */ + + static int +-m68k_dwarf_reg_to_regnum (int num) ++m68k_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int num) + { + if (num < 8) + /* d0..7 */ +@@ -784,7 +785,7 @@ m68k_analyze_prologue (CORE_ADDR pc, COR + /* Return PC of first real instruction. */ + + static CORE_ADDR +-m68k_skip_prologue (CORE_ADDR start_pc) ++m68k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + struct m68k_frame_cache cache; + CORE_ADDR pc; +diff -urNp src-orig/gdb/m88k-tdep.c src/gdb/m88k-tdep.c +--- src-orig/gdb/m88k-tdep.c 2007-06-28 03:23:19.030469216 +0200 ++++ src/gdb/m88k-tdep.c 2007-06-28 01:54:00.883046399 +0200 +@@ -51,7 +51,7 @@ m88k_fetch_instruction (CORE_ADDR pc) + /* Return the name of register REGNUM. */ + + static const char * +-m88k_register_name (int regnum) ++m88k_register_name (struct gdbarch *gdbarch, int regnum) + { + static char *register_names[] = + { +@@ -103,7 +103,7 @@ m88k_addr_bits_remove (CORE_ADDR addr) + location for inserting the breakpoint. */ + + static const gdb_byte * +-m88k_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++m88k_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + /* tb 0,r0,511 */ + static gdb_byte break_insn[] = { 0xf0, 0x00, 0xd1, 0xff }; +@@ -628,7 +628,7 @@ const int m88k_max_prologue_size = 128 * + starting at PC. */ + + static CORE_ADDR +-m88k_skip_prologue (CORE_ADDR pc) ++m88k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; +diff -urNp src-orig/gdb/mem-break.c src/gdb/mem-break.c +--- src-orig/gdb/mem-break.c 2007-06-28 03:23:19.035468496 +0200 ++++ src/gdb/mem-break.c 2007-06-28 01:54:00.887045823 +0200 +@@ -43,7 +43,8 @@ + BREAKPOINT_MAX). */ + + int +-default_memory_insert_breakpoint (struct bp_target_info *bp_tgt) ++default_memory_insert_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + int val; + const unsigned char *bp; +@@ -70,7 +71,8 @@ default_memory_insert_breakpoint (struct + + + int +-default_memory_remove_breakpoint (struct bp_target_info *bp_tgt) ++default_memory_remove_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents, + bp_tgt->placed_size); +diff -urNp src-orig/gdb/mep-tdep.c src/gdb/mep-tdep.c +--- src-orig/gdb/mep-tdep.c 2007-06-28 03:23:19.043467344 +0200 ++++ src/gdb/mep-tdep.c 2007-06-28 01:54:00.897044382 +0200 +@@ -787,7 +787,7 @@ mep_init_pseudoregister_maps (void) + + + static int +-mep_debug_reg_to_regnum (int debug_reg) ++mep_debug_reg_to_regnum (struct gdbarch *gdbarch, int debug_reg) + { + /* The debug info uses the raw register numbers. */ + return mep_raw_to_pseudo[debug_reg]; +@@ -930,7 +930,7 @@ current_ccr_names () + + + static const char * +-mep_register_name (int regnr) ++mep_register_name (struct gdbarch *gdbarch, int regnr) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + +@@ -1033,7 +1033,7 @@ mep_register_reggroup_p (struct gdbarch + { + /* Filter reserved or unused register numbers. */ + { +- const char *name = mep_register_name (regnum); ++ const char *name = mep_register_name (gdbarch, regnum); + + if (! name || name[0] == '\0') + return 0; +@@ -1868,7 +1868,7 @@ mep_analyze_prologue (CORE_ADDR start_pc + + + static CORE_ADDR +-mep_skip_prologue (CORE_ADDR pc) ++mep_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + char *name; + CORE_ADDR func_addr, func_end; +@@ -1887,7 +1887,7 @@ mep_skip_prologue (CORE_ADDR pc) + /* Breakpoints. */ + + static const unsigned char * +-mep_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) ++mep_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char breakpoint[] = { 0x70, 0x32 }; + *lenptr = sizeof (breakpoint); +diff -urNp src-orig/gdb/mipsnbsd-tdep.c src/gdb/mipsnbsd-tdep.c +--- src-orig/gdb/mipsnbsd-tdep.c 2007-06-28 03:23:19.048466624 +0200 ++++ src/gdb/mipsnbsd-tdep.c 2007-06-28 01:54:00.902043662 +0200 +@@ -308,14 +308,14 @@ mipsnbsd_get_longjmp_target (struct fram + } + + static int +-mipsnbsd_cannot_fetch_register (int regno) ++mipsnbsd_cannot_fetch_register (struct gdbarch *gdbarch, int regno) + { + return (regno == MIPS_ZERO_REGNUM + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); + } + + static int +-mipsnbsd_cannot_store_register (int regno) ++mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno) + { + return (regno == MIPS_ZERO_REGNUM + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision); +diff -urNp src-orig/gdb/mips-tdep.c src/gdb/mips-tdep.c +--- src-orig/gdb/mips-tdep.c 2007-06-28 03:23:19.062464608 +0200 ++++ src/gdb/mips-tdep.c 2007-06-28 01:54:00.920041068 +0200 +@@ -490,7 +490,7 @@ static const char *mips_irix_reg_names[N + + /* Return the name of the register corresponding to REGNO. */ + static const char * +-mips_register_name (int regno) ++mips_register_name (struct gdbarch *gdbarch, int regno) + { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + /* GPR names for all ABIs other than n32/n64. */ +@@ -528,7 +528,7 @@ mips_register_name (int regno) + return mips_gpr_names[rawnum]; + } + else if (tdesc_has_registers (gdbarch_target_desc (current_gdbarch))) +- return tdesc_register_name (rawnum); ++ return tdesc_register_name (gdbarch, rawnum); + else if (32 <= rawnum && rawnum < gdbarch_num_regs (current_gdbarch)) + { + gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS); +@@ -689,7 +689,7 @@ set_mips64_transfers_32bit_regs (char *a + /* Convert to/from a register and the corresponding memory value. */ + + static int +-mips_convert_register_p (int regnum, struct type *type) ++mips_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) + { + return (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG + && register_size (current_gdbarch, regnum) == 4 +@@ -4290,7 +4290,7 @@ mips_single_step_through_delay (struct g + delay slot of a non-prologue instruction). */ + + static CORE_ADDR +-mips_skip_prologue (CORE_ADDR pc) ++mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR limit_pc; + CORE_ADDR func_addr; +@@ -4501,7 +4501,7 @@ gdb_print_insn_mips (bfd_vma memaddr, st + should be inserted. */ + + static const gdb_byte * +-mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++mips_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) + { +@@ -4662,7 +4662,7 @@ mips_skip_trampoline_code (struct frame_ + [1 * gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM. */ + + static int +-mips_stab_reg_to_regnum (int num) ++mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) + { + int regnum; + if (num >= 0 && num < 32) +@@ -4686,7 +4686,7 @@ mips_stab_reg_to_regnum (int num) + gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM. */ + + static int +-mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num) ++mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num) + { + int regnum; + if (num >= 0 && num < 32) +@@ -4706,7 +4706,7 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (i + } + + static int +-mips_register_sim_regno (int regnum) ++mips_register_sim_regno (struct gdbarch *gdbarch, int regnum) + { + /* Only makes sense to supply raw registers. */ + gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch)); +diff -urNp src-orig/gdb/mn10300-tdep.c src/gdb/mn10300-tdep.c +--- src-orig/gdb/mn10300-tdep.c 2007-06-28 03:23:19.069463600 +0200 ++++ src/gdb/mn10300-tdep.c 2007-06-28 01:54:00.928039916 +0200 +@@ -221,7 +221,7 @@ register_name (int reg, char **regs, lon + } + + static const char * +-mn10300_generic_register_name (int reg) ++mn10300_generic_register_name (struct gdbarch *gdbarch, int reg) + { + static char *regs[] = + { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", +@@ -234,7 +234,7 @@ mn10300_generic_register_name (int reg) + + + static const char * +-am33_register_name (int reg) ++am33_register_name (struct gdbarch *gdbarch, int reg) + { + static char *regs[] = + { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", +@@ -246,7 +246,7 @@ am33_register_name (int reg) + } + + static const char * +-am33_2_register_name (int reg) ++am33_2_register_name (struct gdbarch *gdbarch, int reg) + { + static char *regs[] = + { +@@ -290,7 +290,8 @@ mn10300_write_pc (struct regcache *regca + one, so we defined it ourselves. */ + + const static unsigned char * +-mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) ++mn10300_breakpoint_from_pc (struct gdbarch *gdbarch, ++ CORE_ADDR *bp_addr, int *bp_size) + { + static char breakpoint[] = {0xff}; + *bp_size = 1; +@@ -827,7 +828,7 @@ mn10300_analyze_prologue (struct frame_i + Return the address of the first inst past the prologue of the function. */ + + static CORE_ADDR +-mn10300_skip_prologue (CORE_ADDR pc) ++mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + return mn10300_analyze_prologue (NULL, NULL, pc); + } +@@ -1078,7 +1079,7 @@ mn10300_push_dummy_call (struct gdbarch + to work with the existing GDB, neither of them can change. So we + just have to cope. */ + static int +-mn10300_dwarf2_reg_to_regnum (int dwarf2) ++mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2) + { + /* This table is supposed to be shaped like the gdbarch_register_name + initializer in gcc/config/mn10300/mn10300.h. Registers which +diff -urNp src-orig/gdb/mt-tdep.c src/gdb/mt-tdep.c +--- src-orig/gdb/mt-tdep.c 2007-06-28 03:23:19.075462735 +0200 ++++ src/gdb/mt-tdep.c 2007-06-28 01:54:00.935038907 +0200 +@@ -142,7 +142,7 @@ enum mt_gdb_regnums + /* Return name of register number specified by REGNUM. */ + + static const char * +-mt_register_name (int regnum) ++mt_register_name (struct gdbarch *gdbarch, int regnum) + { + static const char *const register_names[] = { + /* CPU regs. */ +@@ -313,7 +313,7 @@ mt_register_reggroup_p (struct gdbarch * + if (group == all_reggroup) + return (regnum >= 0 + && regnum < MT_NUM_REGS + MT_NUM_PSEUDO_REGS +- && mt_register_name (regnum)[0] != '\0'); ++ && mt_register_name (gdbarch, regnum)[0] != '\0'); + + if (group == general_reggroup) + return (regnum >= MT_R0_REGNUM && regnum <= MT_R15_REGNUM); +@@ -400,7 +400,7 @@ mt_return_value (struct gdbarch *gdbarch + call. */ + + static CORE_ADDR +-mt_skip_prologue (CORE_ADDR pc) ++mt_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr = 0, func_end = 0; + char *func_name; +@@ -453,7 +453,7 @@ mt_skip_prologue (CORE_ADDR pc) + The BP for ms2 is defined as 0x69000000 (illegal) */ + + static const gdb_byte * +-mt_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) ++mt_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr, int *bp_size) + { + static gdb_byte ms1_breakpoint[] = { 0x68, 0, 0, 0 }; + static gdb_byte ms2_breakpoint[] = { 0x69, 0, 0, 0 }; +diff -urNp src-orig/gdb/objfiles.c src/gdb/objfiles.c +--- src-orig/gdb/objfiles.c 2007-06-28 03:23:19.080462015 +0200 ++++ src/gdb/objfiles.c 2007-06-28 01:54:00.942037899 +0200 +@@ -49,6 +49,7 @@ + #include "block.h" + #include "dictionary.h" + #include "source.h" ++#include "arch-utils.h" + + /* Prototypes for local functions */ + +@@ -188,6 +189,8 @@ allocate_objfile (bfd *abfd, int flags) + } + if (abfd != NULL) + { ++ objfile->gdbarch = gdbarch_from_bfd (abfd); ++ + objfile->name = xstrdup (bfd_get_filename (abfd)); + objfile->mtime = bfd_get_mtime (abfd); + +diff -urNp src-orig/gdb/objfiles.h src/gdb/objfiles.h +--- src-orig/gdb/objfiles.h 2007-06-28 03:23:19.085461295 +0200 ++++ src/gdb/objfiles.h 2007-06-28 01:54:00.948037035 +0200 +@@ -231,6 +231,10 @@ struct objfile + + bfd *obfd; + ++ /* The gdbarch associated with the BFD. */ ++ ++ struct gdbarch *gdbarch; ++ + /* The modification timestamp of the object file, as of the last time + we read its symbols. */ + +diff -urNp src-orig/gdb/ppc-linux-nat.c src/gdb/ppc-linux-nat.c +--- src-orig/gdb/ppc-linux-nat.c 2007-06-28 03:23:19.093460143 +0200 ++++ src/gdb/ppc-linux-nat.c 2007-06-28 01:54:00.957035738 +0200 +@@ -171,10 +171,10 @@ PT_NIP, PT_MSR, PT_CCR, PT_LNK, PT_CTR, + /* *INDENT_ON * */ + + static int +-ppc_register_u_addr (int regno) ++ppc_register_u_addr (struct gdbarch *gdbarch, int regno) + { + int u_addr = -1; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace + interface, and not the wordsize of the program's ABI. */ + int wordsize = sizeof (long); +@@ -193,7 +193,7 @@ ppc_register_u_addr (int regno) + u_addr = (PT_FPR0 * wordsize) + ((regno - tdep->ppc_fp0_regnum) * 8); + + /* UISA special purpose registers: 1 slot each */ +- if (regno == gdbarch_pc_regnum (current_gdbarch)) ++ if (regno == gdbarch_pc_regnum (gdbarch)) + u_addr = PT_NIP * wordsize; + if (regno == tdep->ppc_lr_regnum) + u_addr = PT_LNK * wordsize; +@@ -238,8 +238,9 @@ fetch_altivec_register (struct regcache + int ret; + int offset = 0; + gdb_vrregset_t regs; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); +- int vrregsize = register_size (current_gdbarch, tdep->ppc_vr0_regnum); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum); + + ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); + if (ret < 0) +@@ -257,7 +258,7 @@ fetch_altivec_register (struct regcache + vector. VRSAVE is at the end of the array in a 4 bytes slot, so + there is no need to define an offset for it. */ + if (regno == (tdep->ppc_vrsave_regnum - 1)) +- offset = vrregsize - register_size (current_gdbarch, tdep->ppc_vrsave_regnum); ++ offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum); + + regcache_raw_supply (regcache, regno, + regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset); +@@ -300,15 +301,16 @@ get_spe_registers (int tid, struct gdb_e + static void + fetch_spe_register (struct regcache *regcache, int tid, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct gdb_evrregset_t evrregs; + + gdb_assert (sizeof (evrregs.evr[0]) +- == register_size (current_gdbarch, tdep->ppc_ev0_upper_regnum)); ++ == register_size (gdbarch, tdep->ppc_ev0_upper_regnum)); + gdb_assert (sizeof (evrregs.acc) +- == register_size (current_gdbarch, tdep->ppc_acc_regnum)); ++ == register_size (gdbarch, tdep->ppc_acc_regnum)); + gdb_assert (sizeof (evrregs.spefscr) +- == register_size (current_gdbarch, tdep->ppc_spefscr_regnum)); ++ == register_size (gdbarch, tdep->ppc_spefscr_regnum)); + + get_spe_registers (tid, &evrregs); + +@@ -338,14 +340,15 @@ fetch_spe_register (struct regcache *reg + static void + fetch_register (struct regcache *regcache, int tid, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* This isn't really an address. But ptrace thinks of it as one. */ +- CORE_ADDR regaddr = ppc_register_u_addr (regno); ++ CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno); + int bytes_transferred; + unsigned int offset; /* Offset of registers within the u area. */ + char buf[MAX_REGISTER_SIZE]; + +- if (altivec_register_p (regno)) ++ if (altivec_register_p (gdbarch, regno)) + { + /* If this is the first time through, or if it is not the first + time through, and we have comfirmed that there is kernel +@@ -360,7 +363,7 @@ fetch_register (struct regcache *regcach + AltiVec registers, fall through and return zeroes, because + regaddr will be -1 in this case. */ + } +- else if (spe_register_p (regno)) ++ else if (spe_register_p (gdbarch, regno)) + { + fetch_spe_register (regcache, tid, regno); + return; +@@ -368,7 +371,7 @@ fetch_register (struct regcache *regcach + + if (regaddr == -1) + { +- memset (buf, '\0', register_size (current_gdbarch, regno)); /* Supply zeroes */ ++ memset (buf, '\0', register_size (gdbarch, regno)); /* Supply zeroes */ + regcache_raw_supply (regcache, regno, buf); + return; + } +@@ -377,7 +380,7 @@ fetch_register (struct regcache *regcach + 32-bit platform, 64-bit floating-point registers will require two + transfers. */ + for (bytes_transferred = 0; +- bytes_transferred < register_size (current_gdbarch, regno); ++ bytes_transferred < register_size (gdbarch, regno); + bytes_transferred += sizeof (long)) + { + errno = 0; +@@ -388,7 +391,7 @@ fetch_register (struct regcache *regcach + { + char message[128]; + sprintf (message, "reading register %s (#%d)", +- gdbarch_register_name (current_gdbarch, regno), regno); ++ gdbarch_register_name (gdbarch, regno), regno); + perror_with_name (message); + } + } +@@ -396,34 +399,34 @@ fetch_register (struct regcache *regcach + /* Now supply the register. Keep in mind that the regcache's idea + of the register's size may not be a multiple of sizeof + (long). */ +- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) + { + /* Little-endian values are always found at the left end of the + bytes transferred. */ + regcache_raw_supply (regcache, regno, buf); + } +- else if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ++ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Big-endian values are found at the right end of the bytes + transferred. */ +- size_t padding = (bytes_transferred +- - register_size (current_gdbarch, regno)); ++ size_t padding = bytes_transferred - register_size (gdbarch, regno); + regcache_raw_supply (regcache, regno, buf + padding); + } + else + internal_error (__FILE__, __LINE__, + _("fetch_register: unexpected byte order: %d"), +- gdbarch_byte_order (current_gdbarch)); ++ gdbarch_byte_order (gdbarch)); + } + + static void + supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp) + { + int i; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1; +- int vrregsize = register_size (current_gdbarch, tdep->ppc_vr0_regnum); +- int offset = vrregsize - register_size (current_gdbarch, tdep->ppc_vrsave_regnum); ++ int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum); ++ int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum); + + for (i = 0; i < num_of_vrregs; i++) + { +@@ -463,14 +466,15 @@ static void + fetch_ppc_registers (struct regcache *regcache, int tid) + { + int i; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + for (i = 0; i < ppc_num_gprs; i++) + fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i); + if (tdep->ppc_fp0_regnum >= 0) + for (i = 0; i < ppc_num_fprs; i++) + fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i); +- fetch_register (regcache, tid, gdbarch_pc_regnum (current_gdbarch)); ++ fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch)); + if (tdep->ppc_ps_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_ps_regnum); + if (tdep->ppc_cr_regnum != -1) +@@ -520,8 +524,9 @@ store_altivec_register (const struct reg + int ret; + int offset = 0; + gdb_vrregset_t regs; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); +- int vrregsize = register_size (current_gdbarch, tdep->ppc_vr0_regnum); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum); + + ret = ptrace (PTRACE_GETVRREGS, tid, 0, ®s); + if (ret < 0) +@@ -537,7 +542,7 @@ store_altivec_register (const struct reg + /* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes + long on the hardware. */ + if (regno == (tdep->ppc_vrsave_regnum - 1)) +- offset = vrregsize - register_size (current_gdbarch, tdep->ppc_vrsave_regnum); ++ offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum); + + regcache_raw_collect (regcache, regno, + regs + (regno - tdep->ppc_vr0_regnum) * vrregsize + offset); +@@ -582,15 +587,16 @@ set_spe_registers (int tid, struct gdb_e + static void + store_spe_register (const struct regcache *regcache, int tid, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + struct gdb_evrregset_t evrregs; + + gdb_assert (sizeof (evrregs.evr[0]) +- == register_size (current_gdbarch, tdep->ppc_ev0_upper_regnum)); ++ == register_size (gdbarch, tdep->ppc_ev0_upper_regnum)); + gdb_assert (sizeof (evrregs.acc) +- == register_size (current_gdbarch, tdep->ppc_acc_regnum)); ++ == register_size (gdbarch, tdep->ppc_acc_regnum)); + gdb_assert (sizeof (evrregs.spefscr) +- == register_size (current_gdbarch, tdep->ppc_spefscr_regnum)); ++ == register_size (gdbarch, tdep->ppc_spefscr_regnum)); + + if (regno == -1) + /* Since we're going to write out every register, the code below +@@ -636,19 +642,20 @@ store_spe_register (const struct regcach + static void + store_register (const struct regcache *regcache, int tid, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* This isn't really an address. But ptrace thinks of it as one. */ +- CORE_ADDR regaddr = ppc_register_u_addr (regno); ++ CORE_ADDR regaddr = ppc_register_u_addr (gdbarch, regno); + int i; + size_t bytes_to_transfer; + char buf[MAX_REGISTER_SIZE]; + +- if (altivec_register_p (regno)) ++ if (altivec_register_p (gdbarch, regno)) + { + store_altivec_register (regcache, tid, regno); + return; + } +- else if (spe_register_p (regno)) ++ else if (spe_register_p (gdbarch, regno)) + { + store_spe_register (regcache, tid, regno); + return; +@@ -661,18 +668,17 @@ store_register (const struct regcache *r + idea of the register's size may not be a multiple of sizeof + (long). */ + memset (buf, 0, sizeof buf); +- bytes_to_transfer = align_up (register_size (current_gdbarch, regno), ++ bytes_to_transfer = align_up (register_size (gdbarch, regno), + sizeof (long)); +- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE) ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) + { + /* Little-endian values always sit at the left end of the buffer. */ + regcache_raw_collect (regcache, regno, buf); + } +- else if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ++ else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + { + /* Big-endian values sit at the right end of the buffer. */ +- size_t padding = (bytes_to_transfer +- - register_size (current_gdbarch, regno)); ++ size_t padding = bytes_to_transfer - register_size (gdbarch, regno); + regcache_raw_collect (regcache, regno, buf + padding); + } + +@@ -694,7 +700,7 @@ store_register (const struct regcache *r + { + char message[128]; + sprintf (message, "writing register %s (#%d)", +- gdbarch_register_name (current_gdbarch, regno), regno); ++ gdbarch_register_name (gdbarch, regno), regno); + perror_with_name (message); + } + } +@@ -704,10 +710,11 @@ static void + fill_vrregset (const struct regcache *regcache, gdb_vrregset_t *vrregsetp) + { + int i; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1; +- int vrregsize = register_size (current_gdbarch, tdep->ppc_vr0_regnum); +- int offset = vrregsize - register_size (current_gdbarch, tdep->ppc_vrsave_regnum); ++ int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum); ++ int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum); + + for (i = 0; i < num_of_vrregs; i++) + { +@@ -749,14 +756,15 @@ static void + store_ppc_registers (const struct regcache *regcache, int tid) + { + int i; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + for (i = 0; i < ppc_num_gprs; i++) + store_register (regcache, tid, tdep->ppc_gp0_regnum + i); + if (tdep->ppc_fp0_regnum >= 0) + for (i = 0; i < ppc_num_fprs; i++) + store_register (regcache, tid, tdep->ppc_fp0_regnum + i); +- store_register (regcache, tid, gdbarch_pc_regnum (current_gdbarch)); ++ store_register (regcache, tid, gdbarch_pc_regnum (gdbarch)); + if (tdep->ppc_ps_regnum != -1) + store_register (regcache, tid, tdep->ppc_ps_regnum); + if (tdep->ppc_cr_regnum != -1) +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-06-28 03:23:19.099459279 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-06-28 03:23:09.376397097 +0200 +@@ -275,7 +275,8 @@ ppc_linux_skip_trampoline_code (struct f + regard to removing breakpoints in some potentially self modifying + code. */ + int +-ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt) ++ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt) + { + CORE_ADDR addr = bp_tgt->placed_address; + const unsigned char *bp; +@@ -284,7 +285,7 @@ ppc_linux_memory_remove_breakpoint (stru + gdb_byte old_contents[BREAKPOINT_MAX]; + + /* Determine appropriate breakpoint contents and size for this address. */ +- bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen); ++ bp = gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen); + if (bp == NULL) + error (_("Software breakpoints not implemented for this target.")); + +@@ -767,7 +768,7 @@ ppc_linux_sigtramp_cache (struct frame_i + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + base = frame_unwind_register_unsigned (next_frame, +- gdbarch_sp_regnum (current_gdbarch)); ++ gdbarch_sp_regnum (gdbarch)); + if (bias > 0 && frame_pc_unwind (next_frame) != func) + /* See below, some signal trampolines increment the stack as their + first instruction, need to compensate for that. */ +@@ -787,7 +788,7 @@ ppc_linux_sigtramp_cache (struct frame_i + trad_frame_set_reg_addr (this_cache, regnum, gpregs + i * tdep->wordsize); + } + trad_frame_set_reg_addr (this_cache, +- gdbarch_pc_regnum (current_gdbarch), ++ gdbarch_pc_regnum (gdbarch), + gpregs + 32 * tdep->wordsize); + trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, + gpregs + 35 * tdep->wordsize); +@@ -803,7 +804,7 @@ ppc_linux_sigtramp_cache (struct frame_i + /* Floating point registers. */ + for (i = 0; i < 32; i++) + { +- int regnum = i + gdbarch_fp0_regnum (current_gdbarch); ++ int regnum = i + gdbarch_fp0_regnum (gdbarch); + trad_frame_set_reg_addr (this_cache, regnum, + fpregs + i * tdep->wordsize); + } +diff -urNp src-orig/gdb/ppc-sysv-tdep.c src/gdb/ppc-sysv-tdep.c +--- src-orig/gdb/ppc-sysv-tdep.c 2007-06-28 03:23:19.106458271 +0200 ++++ src/gdb/ppc-sysv-tdep.c 2007-06-28 01:54:00.972033577 +0200 +@@ -50,13 +50,13 @@ ppc_sysv_abi_push_dummy_call (struct gdb + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ULONGEST saved_sp; + int argspace = 0; /* 0 is an initial wrong guess. */ + int write_pass; + + regcache_cooked_read_unsigned (regcache, +- gdbarch_sp_regnum (current_gdbarch), ++ gdbarch_sp_regnum (gdbarch), + &saved_sp); + + /* Go through the argument list twice. +@@ -107,7 +107,7 @@ ppc_sysv_abi_push_dummy_call (struct gdb + const bfd_byte *val = value_contents (arg); + + if (TYPE_CODE (type) == TYPE_CODE_FLT +- && ppc_floating_point_unit_p (current_gdbarch) && len <= 8) ++ && ppc_floating_point_unit_p (gdbarch) && len <= 8) + { + /* Floating point value converted to "double" then + passed in an FP register, when the registers run out, +@@ -144,7 +144,8 @@ ppc_sysv_abi_push_dummy_call (struct gdb + } + } + else if (len == 8 && (TYPE_CODE (type) == TYPE_CODE_INT /* long long */ +- || (!ppc_floating_point_unit_p (current_gdbarch) && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */ ++ || (!ppc_floating_point_unit_p (gdbarch) ++ && TYPE_CODE (type) == TYPE_CODE_FLT))) /* double */ + { + /* "long long" or "double" passed in an odd/even + register pair with the low addressed word in the odd +@@ -310,7 +311,7 @@ ppc_sysv_abi_push_dummy_call (struct gdb + + /* Update %sp. */ + regcache_cooked_write_signed (regcache, +- gdbarch_sp_regnum (current_gdbarch), sp); ++ gdbarch_sp_regnum (gdbarch), sp); + + /* Write the backchain (it occupies WORDSIZED bytes). */ + write_memory_signed_integer (sp, tdep->wordsize, saved_sp); +@@ -582,7 +583,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + int struct_return, CORE_ADDR struct_addr) + { + CORE_ADDR func_addr = find_function_addr (function, NULL); +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + ULONGEST back_chain; + /* See for-loop comment below. */ + int write_pass; +@@ -605,7 +606,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + zone size" + "struct return size". Fetch the stack-pointer from + before this and use that as the BACK_CHAIN. */ + regcache_cooked_read_unsigned (regcache, +- gdbarch_sp_regnum (current_gdbarch), ++ gdbarch_sp_regnum (gdbarch), + &back_chain); + + /* Go through the argument list twice. +@@ -682,7 +683,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + memory. */ + if (write_pass) + { +- if (ppc_floating_point_unit_p (current_gdbarch) ++ if (ppc_floating_point_unit_p (gdbarch) + && freg <= 13) + { + gdb_byte regval[MAX_REGISTER_SIZE]; +@@ -838,7 +839,7 @@ ppc64_sysv_abi_push_dummy_call (struct g + + /* Update %sp. */ + regcache_cooked_write_signed (regcache, +- gdbarch_sp_regnum (current_gdbarch), sp); ++ gdbarch_sp_regnum (gdbarch), sp); + + /* Write the backchain (it occupies WORDSIZED bytes). */ + write_memory_signed_integer (sp, tdep->wordsize, back_chain); +@@ -997,7 +998,7 @@ ppc64_sysv_abi_return_value (struct gdba + { + gdb_byte regval[MAX_REGISTER_SIZE]; + struct type *regtype = +- register_type (current_gdbarch, tdep->ppc_fp0_regnum); ++ register_type (gdbarch, tdep->ppc_fp0_regnum); + if (writebuf != NULL) + { + convert_typed_floating ((const bfd_byte *) writebuf + +diff -urNp src-orig/gdb/ppc-tdep.h src/gdb/ppc-tdep.h +--- src-orig/gdb/ppc-tdep.h 2007-06-28 03:23:19.110457695 +0200 ++++ src/gdb/ppc-tdep.h 2007-06-28 03:23:09.381396376 +0200 +@@ -56,7 +56,8 @@ CORE_ADDR ppc64_sysv_abi_push_dummy_call + CORE_ADDR struct_addr); + CORE_ADDR ppc64_sysv_abi_adjust_breakpoint_address (struct gdbarch *gdbarch, + CORE_ADDR bpaddr); +-int ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt); ++int ppc_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, ++ struct bp_target_info *bp_tgt); + struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void); + const struct regset *ppc_linux_gregset (struct gdbarch *); + const struct regset *ppc_linux_fpregset (struct gdbarch *); +@@ -68,8 +69,8 @@ enum return_value_convention ppc64_sysv_ + const gdb_byte *writebuf); + + /* From rs6000-tdep.c... */ +-int altivec_register_p (int regno); +-int spe_register_p (int regno); ++int altivec_register_p (struct gdbarch *gdbarch, int regno); ++int spe_register_p (struct gdbarch *gdbarch, int regno); + + /* Return non-zero if the architecture described by GDBARCH has + floating-point registers (f0 --- f31 and fpscr). */ +diff -urNp src-orig/gdb/regcache.c src/gdb/regcache.c +--- src-orig/gdb/regcache.c 2007-06-28 03:23:19.117456687 +0200 ++++ src/gdb/regcache.c 2007-06-28 01:54:00.986031560 +0200 +@@ -94,11 +94,10 @@ init_regcache_descr (struct gdbarch *gdb + /* Total size of the register space. The raw registers are mapped + directly onto the raw register cache while the pseudo's are + either mapped onto raw-registers or memory. */ +- descr->nr_cooked_registers = gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch); +- descr->sizeof_cooked_register_valid_p = gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs +- (current_gdbarch); ++ descr->nr_cooked_registers = gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch); ++ descr->sizeof_cooked_register_valid_p = gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch); + + /* Fill in a table of register types. */ + descr->register_type +@@ -108,7 +107,7 @@ init_regcache_descr (struct gdbarch *gdb + + /* Construct a strictly RAW register cache. Don't allow pseudo's + into the register cache. */ +- descr->nr_raw_registers = gdbarch_num_regs (current_gdbarch); ++ descr->nr_raw_registers = gdbarch_num_regs (gdbarch); + + /* FIXME: cagney/2002-08-13: Overallocate the register_valid_p + array. This pretects GDB from erant code that accesses elements +@@ -176,8 +175,8 @@ register_size (struct gdbarch *gdbarch, + struct regcache_descr *descr = regcache_descr (gdbarch); + int size; + gdb_assert (regnum >= 0 +- && regnum < (gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch))); ++ && regnum < (gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch))); + size = descr->sizeof_register[regnum]; + return size; + } +@@ -644,7 +643,7 @@ regcache_raw_write (struct regcache *reg + + /* On the sparc, writing %g0 is a no-op, so we don't even want to + change the registers array if something writes to this register. */ +- if (gdbarch_cannot_store_register (current_gdbarch, regnum)) ++ if (gdbarch_cannot_store_register (regcache->descr->gdbarch, regnum)) + return; + + /* If we have a valid copy of the register, and new value == old +@@ -839,13 +838,13 @@ read_pc_pid (ptid_t ptid) + if (gdbarch_read_pc_p (gdbarch)) + pc_val = gdbarch_read_pc (gdbarch, regcache); + /* Else use per-frame method on get_current_frame. */ +- else if (gdbarch_pc_regnum (current_gdbarch) >= 0) ++ else if (gdbarch_pc_regnum (gdbarch) >= 0) + { + ULONGEST raw_val; + regcache_cooked_read_unsigned (regcache, +- gdbarch_pc_regnum (current_gdbarch), ++ gdbarch_pc_regnum (gdbarch), + &raw_val); +- pc_val = gdbarch_addr_bits_remove (current_gdbarch, raw_val); ++ pc_val = gdbarch_addr_bits_remove (gdbarch, raw_val); + } + else + internal_error (__FILE__, __LINE__, _("read_pc_pid: Unable to find PC")); +@@ -867,9 +866,9 @@ write_pc_pid (CORE_ADDR pc, ptid_t ptid) + + if (gdbarch_write_pc_p (gdbarch)) + gdbarch_write_pc (gdbarch, regcache, pc); +- else if (gdbarch_pc_regnum (current_gdbarch) >= 0) ++ else if (gdbarch_pc_regnum (gdbarch) >= 0) + regcache_cooked_write_unsigned (regcache, +- gdbarch_pc_regnum (current_gdbarch), pc); ++ gdbarch_pc_regnum (gdbarch), pc); + else + internal_error (__FILE__, __LINE__, + _("write_pc_pid: Unable to update PC")); +@@ -940,14 +939,14 @@ regcache_dump (struct regcache *regcache + fprintf_unfiltered (file, "sizeof_raw_register_valid_p %ld\n", + regcache->descr->sizeof_raw_register_valid_p); + fprintf_unfiltered (file, "gdbarch_num_regs %d\n", +- gdbarch_num_regs (current_gdbarch)); ++ gdbarch_num_regs (gdbarch)); + fprintf_unfiltered (file, "gdbarch_num_pseudo_regs %d\n", +- gdbarch_num_pseudo_regs (current_gdbarch)); ++ gdbarch_num_pseudo_regs (gdbarch)); + #endif + + gdb_assert (regcache->descr->nr_cooked_registers +- == (gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch))); ++ == (gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch))); + + for (regnum = -1; regnum < regcache->descr->nr_cooked_registers; regnum++) + { +@@ -956,7 +955,7 @@ regcache_dump (struct regcache *regcache + fprintf_unfiltered (file, " %-10s", "Name"); + else + { +- const char *p = gdbarch_register_name (current_gdbarch, regnum); ++ const char *p = gdbarch_register_name (gdbarch, regnum); + if (p == NULL) + p = ""; + else if (p[0] == '\0') +@@ -973,11 +972,11 @@ regcache_dump (struct regcache *regcache + /* Relative number. */ + if (regnum < 0) + fprintf_unfiltered (file, " %4s", "Rel"); +- else if (regnum < gdbarch_num_regs (current_gdbarch)) ++ else if (regnum < gdbarch_num_regs (gdbarch)) + fprintf_unfiltered (file, " %4d", regnum); + else + fprintf_unfiltered (file, " %4d", +- (regnum - gdbarch_num_regs (current_gdbarch))); ++ (regnum - gdbarch_num_regs (gdbarch))); + + /* Offset. */ + if (regnum < 0) +@@ -1052,7 +1051,7 @@ regcache_dump (struct regcache *regcache + regcache_raw_read (regcache, regnum, buf); + fprintf_unfiltered (file, "0x"); + dump_endian_bytes (file, +- gdbarch_byte_order (current_gdbarch), buf, ++ gdbarch_byte_order (gdbarch), buf, + regcache->descr->sizeof_register[regnum]); + } + } +@@ -1067,7 +1066,7 @@ regcache_dump (struct regcache *regcache + regcache_cooked_read (regcache, regnum, buf); + fprintf_unfiltered (file, "0x"); + dump_endian_bytes (file, +- gdbarch_byte_order (current_gdbarch), buf, ++ gdbarch_byte_order (gdbarch), buf, + regcache->descr->sizeof_register[regnum]); + } + } +diff -urNp src-orig/gdb/rs6000-tdep.c src/gdb/rs6000-tdep.c +--- src-orig/gdb/rs6000-tdep.c 2007-06-28 03:23:19.131454671 +0200 ++++ src/gdb/rs6000-tdep.c 2007-06-28 01:54:01.002029255 +0200 +@@ -120,14 +120,14 @@ CORE_ADDR (*rs6000_find_toc_address_hook + + static CORE_ADDR branch_dest (struct frame_info *frame, int opcode, + int instr, CORE_ADDR pc, CORE_ADDR safety); +-static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR, ++static CORE_ADDR skip_prologue (struct gdbarch *, CORE_ADDR, CORE_ADDR, + struct rs6000_framedata *); + + /* Is REGNO an AltiVec register? Return 1 if so, 0 otherwise. */ + int +-altivec_register_p (int regno) ++altivec_register_p (struct gdbarch *gdbarch, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0) + return 0; + else +@@ -137,9 +137,9 @@ altivec_register_p (int regno) + + /* Return true if REGNO is an SPE register, false otherwise. */ + int +-spe_register_p (int regno) ++spe_register_p (struct gdbarch *gdbarch, int regno) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Is it a reference to EV0 -- EV31, and do we have those? */ + if (tdep->ppc_ev0_regnum >= 0 +@@ -284,14 +284,14 @@ init_sim_regno_table (struct gdbarch *ar + /* Given a GDB register number REG, return the corresponding SIM + register number. */ + static int +-rs6000_register_sim_regno (int reg) ++rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int sim_regno; + + gdb_assert (0 <= reg +- && reg <= gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch)); ++ && reg <= gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch)); + sim_regno = tdep->sim_regno[reg]; + + if (sim_regno >= 0) +@@ -342,8 +342,8 @@ ppc_supply_gregset (const struct regset + ppc_supply_reg (regcache, i, gregs, offset); + } + +- if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch)) +- ppc_supply_reg (regcache, gdbarch_pc_regnum (current_gdbarch), ++ if (regnum == -1 || regnum == gdbarch_pc_regnum (gdbarch)) ++ ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch), + gregs, offsets->pc_offset); + if (regnum == -1 || regnum == tdep->ppc_ps_regnum) + ppc_supply_reg (regcache, tdep->ppc_ps_regnum, +@@ -422,8 +422,8 @@ ppc_collect_gregset (const struct regset + ppc_collect_reg (regcache, i, gregs, offset); + } + +- if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch)) +- ppc_collect_reg (regcache, gdbarch_pc_regnum (current_gdbarch), ++ if (regnum == -1 || regnum == gdbarch_pc_regnum (gdbarch)) ++ ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch), + gregs, offsets->pc_offset); + if (regnum == -1 || regnum == tdep->ppc_ps_regnum) + ppc_collect_reg (regcache, tdep->ppc_ps_regnum, +@@ -490,7 +490,7 @@ read_memory_addr (CORE_ADDR memaddr, int + } + + static CORE_ADDR +-rs6000_skip_prologue (CORE_ADDR pc) ++rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + struct rs6000_framedata frame; + CORE_ADDR limit_pc, func_addr; +@@ -515,7 +515,7 @@ rs6000_skip_prologue (CORE_ADDR pc) + if (limit_pc == 0) + limit_pc = pc + 100; /* Magic. */ + +- pc = skip_prologue (pc, limit_pc, &frame); ++ pc = skip_prologue (gdbarch, pc, limit_pc, &frame); + return pc; + } + +@@ -701,12 +701,13 @@ branch_dest (struct frame_info *frame, i + /* Sequence of bytes for breakpoint instruction. */ + + const static unsigned char * +-rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) ++rs6000_breakpoint_from_pc (struct gdbarch *gdbarch, ++ CORE_ADDR *bp_addr, int *bp_size) + { + static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; + static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; + *bp_size = 4; +- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ++ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + return big_breakpoint; + else + return little_breakpoint; +@@ -813,9 +814,6 @@ deal_with_atomic_sequence (struct frame_ + int + rs6000_software_single_step (struct frame_info *frame) + { +- CORE_ADDR dummy; +- int breakp_sz; +- const gdb_byte *breakp = rs6000_breakpoint_from_pc (&dummy, &breakp_sz); + int ii, insn; + CORE_ADDR loc; + CORE_ADDR breaks[2]; +@@ -828,7 +826,7 @@ rs6000_software_single_step (struct fram + if (deal_with_atomic_sequence (frame)) + return 1; + +- breaks[0] = loc + breakp_sz; ++ breaks[0] = loc + PPC_INSN_SIZE; + opcode = insn >> 26; + breaks[1] = branch_dest (frame, opcode, insn, loc, breaks[0]); + +@@ -985,7 +983,7 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int ins + } + + static CORE_ADDR +-skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) ++skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) + { + CORE_ADDR orig_pc = pc; + CORE_ADDR last_prologue_pc = pc; +@@ -1006,8 +1004,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l + int prev_insn_was_prologue_insn = 1; + int num_skip_non_prologue_insns = 0; + int r0_contains_arg = 0; +- const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch); +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + memset (fdata, 0, sizeof (struct rs6000_framedata)); + fdata->saved_gpr = -1; +@@ -1589,14 +1587,14 @@ rs6000_push_dummy_call (struct gdbarch * + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + int ii; + int len = 0; + int argno; /* current argument number */ + int argbytes; /* current argument byte */ + gdb_byte tmp_buffer[50]; + int f_argno = 0; /* current floating point argno */ +- int wordsize = gdbarch_tdep (current_gdbarch)->wordsize; ++ int wordsize = tdep->wordsize; + CORE_ADDR func_addr = find_function_addr (function, NULL); + + struct value *arg = 0; +@@ -1607,7 +1605,7 @@ rs6000_push_dummy_call (struct gdbarch * + /* The calling convention this function implements assumes the + processor has floating-point registers. We shouldn't be using it + on PPC variants that lack them. */ +- gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); ++ gdb_assert (ppc_floating_point_unit_p (gdbarch)); + + /* The first eight words of ther arguments are passed in registers. + Copy them appropriately. */ +@@ -1645,7 +1643,7 @@ rs6000_push_dummy_call (struct gdbarch * + + for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) + { +- int reg_size = register_size (current_gdbarch, ii + 3); ++ int reg_size = register_size (gdbarch, ii + 3); + + arg = args[argno]; + type = check_typedef (value_type (arg)); +@@ -1692,7 +1690,7 @@ rs6000_push_dummy_call (struct gdbarch * + else + { + /* Argument can fit in one register. No problem. */ +- int adj = gdbarch_byte_order (current_gdbarch) ++ int adj = gdbarch_byte_order (gdbarch) + == BFD_ENDIAN_BIG ? reg_size - len : 0; + gdb_byte word[MAX_REGISTER_SIZE]; + +@@ -1706,8 +1704,7 @@ rs6000_push_dummy_call (struct gdbarch * + ran_out_of_registers_for_arguments: + + regcache_cooked_read_unsigned (regcache, +- gdbarch_sp_regnum (current_gdbarch), +- &saved_sp); ++ gdbarch_sp_regnum (gdbarch), &saved_sp); + + /* Location for 8 parameters are always reserved. */ + sp -= wordsize * 8; +@@ -1749,8 +1746,7 @@ ran_out_of_registers_for_arguments: + to use this area. So, update %sp first before doing anything + else. */ + +- regcache_raw_write_signed (regcache, +- gdbarch_sp_regnum (current_gdbarch), sp); ++ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); + + /* If the last argument copied into the registers didn't fit there + completely, push the rest of it into stack. */ +@@ -1797,7 +1793,7 @@ ran_out_of_registers_for_arguments: + Not doing this can lead to conflicts with the kernel which thinks + that it still has control over this not-yet-allocated stack + region. */ +- regcache_raw_write_signed (regcache, gdbarch_sp_regnum (current_gdbarch), sp); ++ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); + + /* Set back chain properly. */ + store_unsigned_integer (tmp_buffer, wordsize, saved_sp); +@@ -1824,13 +1820,13 @@ rs6000_return_value (struct gdbarch *gdb + struct regcache *regcache, gdb_byte *readbuf, + const gdb_byte *writebuf) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_byte buf[8]; + + /* The calling convention this function implements assumes the + processor has floating-point registers. We shouldn't be using it + on PowerPC variants that lack them. */ +- gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); ++ gdb_assert (ppc_floating_point_unit_p (gdbarch)); + + /* AltiVec extension: Functions that declare a vector data type as a + return value place that return value in VR2. */ +@@ -1985,6 +1981,7 @@ rs6000_in_solib_return_trampoline (CORE_ + CORE_ADDR + rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) + { ++ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); + unsigned int ii, op; + int rel; + CORE_ADDR solib_target_pc; +@@ -2031,7 +2028,7 @@ rs6000_skip_trampoline_code (struct fram + return 0; + } + ii = get_frame_register_unsigned (frame, 11); /* r11 holds destination addr */ +- pc = read_memory_addr (ii, gdbarch_tdep (current_gdbarch)->wordsize); /* (r11) value */ ++ pc = read_memory_addr (ii, tdep->wordsize); /* (r11) value */ + return pc; + } + +@@ -2130,9 +2127,9 @@ regsize (const struct reg *reg, int word + in the current architecture. */ + + static const char * +-rs6000_register_name (int n) ++rs6000_register_name (struct gdbarch *gdbarch, int n) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const struct reg *reg = tdep->regs + n; + + if (!regsize (reg, tdep->wordsize)) +@@ -2186,8 +2183,8 @@ rs6000_register_reggroup_p (struct gdbar + int vector_p; + int general_p; + +- if (gdbarch_register_name (current_gdbarch, regnum) == NULL +- || *gdbarch_register_name (current_gdbarch, regnum) == '\0') ++ if (gdbarch_register_name (gdbarch, regnum) == NULL ++ || *gdbarch_register_name (gdbarch, regnum) == '\0') + return 0; + if (group == all_reggroup) + return 1; +@@ -2221,7 +2218,7 @@ rs6000_register_reggroup_p (struct gdbar + || regnum == tdep->ppc_lr_regnum + || regnum == tdep->ppc_ctr_regnum + || regnum == tdep->ppc_xer_regnum +- || regnum == gdbarch_pc_regnum (current_gdbarch)); ++ || regnum == gdbarch_pc_regnum (gdbarch)); + if (group == general_reggroup) + return general_p; + +@@ -2235,9 +2232,9 @@ rs6000_register_reggroup_p (struct gdbar + double, we need a conversion if the memory format is float. */ + + static int +-rs6000_convert_register_p (int regnum, struct type *type) ++rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) + { +- const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; ++ const struct reg *reg = gdbarch_tdep (gdbarch)->regs + regnum; + + return (reg->fpr + && TYPE_CODE (type) == TYPE_CODE_FLT +@@ -2250,7 +2247,8 @@ rs6000_register_to_value (struct frame_i + struct type *type, + gdb_byte *to) + { +- const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; ++ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); ++ const struct reg *reg = tdep->regs + regnum; + gdb_byte from[MAX_REGISTER_SIZE]; + + gdb_assert (reg->fpr); +@@ -2266,7 +2264,8 @@ rs6000_value_to_register (struct frame_i + struct type *type, + const gdb_byte *from) + { +- const struct reg *reg = gdbarch_tdep (current_gdbarch)->regs + regnum; ++ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame)); ++ const struct reg *reg = tdep->regs + regnum; + gdb_byte to[MAX_REGISTER_SIZE]; + + gdb_assert (reg->fpr); +@@ -2315,7 +2314,7 @@ e500_move_ev_register (void (*move) (str + + reg_index = ev_reg - tdep->ppc_ev0_regnum; + +- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) ++ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG) + { + move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer); + move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4); +@@ -2391,9 +2390,9 @@ e500_register_reggroup_p (struct gdbarch + + /* Convert a DBX STABS register number to a GDB register number. */ + static int +-rs6000_stab_reg_to_regnum (int num) ++rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (0 <= num && num <= 31) + return tdep->ppc_gp0_regnum + num; +@@ -2433,9 +2432,9 @@ rs6000_stab_reg_to_regnum (int num) + + /* Convert a Dwarf 2 register number to a GDB register number. */ + static int +-rs6000_dwarf2_reg_to_regnum (int num) ++rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (0 <= num && num <= 31) + return tdep->ppc_gp0_regnum + num; +@@ -3132,14 +3131,14 @@ static CORE_ADDR + rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) + { + return frame_unwind_register_unsigned (next_frame, +- gdbarch_pc_regnum (current_gdbarch)); ++ gdbarch_pc_regnum (gdbarch)); + } + + static struct frame_id + rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) + { + return frame_id_build (frame_unwind_register_unsigned +- (next_frame, gdbarch_sp_regnum (current_gdbarch)), ++ (next_frame, gdbarch_sp_regnum (gdbarch)), + frame_pc_unwind (next_frame)); + } + +@@ -3168,7 +3167,7 @@ rs6000_frame_cache (struct frame_info *n + + func = frame_func_unwind (next_frame, NORMAL_FRAME); + pc = frame_pc_unwind (next_frame); +- skip_prologue (func, pc, &fdata); ++ skip_prologue (gdbarch, func, pc, &fdata); + + /* Figure out the parent's stack pointer. */ + +@@ -3178,7 +3177,7 @@ rs6000_frame_cache (struct frame_info *n + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = frame_unwind_register_unsigned +- (next_frame, gdbarch_sp_regnum (current_gdbarch)); ++ (next_frame, gdbarch_sp_regnum (gdbarch)); + + /* If the function appears to be frameless, check a couple of likely + indicators that we have simply failed to find the frame setup. +@@ -3217,7 +3216,7 @@ rs6000_frame_cache (struct frame_info *n + cache->base = read_memory_addr (cache->base, wordsize); + + trad_frame_set_value (cache->saved_regs, +- gdbarch_sp_regnum (current_gdbarch), cache->base); ++ gdbarch_sp_regnum (gdbarch), cache->base); + + /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. + All fpr's from saved_fpr to fp31 are saved. */ +@@ -3296,7 +3295,7 @@ rs6000_frame_cache (struct frame_info *n + if (fdata.lr_offset != 0) + cache->saved_regs[tdep->ppc_lr_regnum].addr = cache->base + fdata.lr_offset; + /* The PC is found in the link register. */ +- cache->saved_regs[gdbarch_pc_regnum (current_gdbarch)] = ++ cache->saved_regs[gdbarch_pc_regnum (gdbarch)] = + cache->saved_regs[tdep->ppc_lr_regnum]; + + /* If != 0, fdata.vrsave_offset is the offset from the frame that +@@ -3308,7 +3307,7 @@ rs6000_frame_cache (struct frame_info *n + /* If no alloca register used, then fi->frame is the value of the + %sp for this frame, and it is good enough. */ + cache->initial_sp = frame_unwind_register_unsigned +- (next_frame, gdbarch_sp_regnum (current_gdbarch)); ++ (next_frame, gdbarch_sp_regnum (gdbarch)); + else + cache->initial_sp = frame_unwind_register_unsigned (next_frame, + fdata.alloca_reg); +@@ -3733,9 +3732,9 @@ rs6000_gdbarch_init (struct gdbarch_info + } + + static void +-rs6000_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) ++rs6000_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) + { +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep == NULL) + return; +diff -urNp src-orig/gdb/s390-tdep.c src/gdb/s390-tdep.c +--- src-orig/gdb/s390-tdep.c 2007-06-28 03:23:19.140453375 +0200 ++++ src/gdb/s390-tdep.c 2007-06-28 01:54:01.012027814 +0200 +@@ -67,7 +67,7 @@ struct gdbarch_tdep + + /* Return the name of register REGNUM. */ + static const char * +-s390_register_name (int regnum) ++s390_register_name (struct gdbarch *gdbarch, int regnum) + { + static const char *register_names[S390_NUM_TOTAL_REGS] = + { +@@ -149,7 +149,7 @@ static int s390_dwarf_regmap[] = + /* Convert DWARF register number REG to the appropriate register + number used by GDB. */ + static int +-s390_dwarf_reg_to_regnum (int reg) ++s390_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) + { + int regnum = -1; + +@@ -1095,7 +1095,7 @@ s390_analyze_prologue (struct gdbarch *g + /* Advance PC across any function entry prologue instructions to reach + some "real" code. */ + static CORE_ADDR +-s390_skip_prologue (CORE_ADDR pc) ++s390_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + struct s390_prologue_data data; + CORE_ADDR skip_pc; +@@ -2258,7 +2258,7 @@ s390_return_value (struct gdbarch *gdbar + /* Breakpoints. */ + + static const gdb_byte * +-s390_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++s390_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static const gdb_byte breakpoint[] = { 0x0, 0x1 }; + +diff -urNp src-orig/gdb/score-tdep.c src/gdb/score-tdep.c +--- src-orig/gdb/score-tdep.c 2007-06-28 03:23:19.146452510 +0200 ++++ src/gdb/score-tdep.c 2007-06-28 01:54:01.019026806 +0200 +@@ -286,7 +286,7 @@ score_unwind_sp (struct gdbarch *gdbarch + } + + static const char * +-score_register_name (int regnum) ++score_register_name (struct gdbarch *gdbarch, int regnum) + { + const char *score_register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -307,7 +307,7 @@ score_register_name (int regnum) + } + + static int +-score_register_sim_regno (int regnum) ++score_register_sim_regno (struct gdbarch *gdbarch, int regnum) + { + gdb_assert (regnum >= 0 && regnum < SCORE_NUM_REGS); + return regnum; +@@ -323,7 +323,7 @@ score_print_insn (bfd_vma memaddr, struc + } + + static const gdb_byte * +-score_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++score_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + gdb_byte buf[SCORE_INSTLEN] = { 0 }; + int ret; +@@ -681,7 +681,7 @@ score_fetch_inst (CORE_ADDR addr, char * + } + + static CORE_ADDR +-score_skip_prologue (CORE_ADDR pc) ++score_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR cpc = pc; + int iscan = 32, stack_sub = 0; +diff -urNp src-orig/gdb/sh64-tdep.c src/gdb/sh64-tdep.c +--- src-orig/gdb/sh64-tdep.c 2007-06-28 03:23:19.154451358 +0200 ++++ src/gdb/sh64-tdep.c 2007-06-28 01:54:01.030025221 +0200 +@@ -126,7 +126,7 @@ enum + }; + + static const char * +-sh64_register_name (int reg_nr) ++sh64_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = + { +@@ -254,7 +254,7 @@ pc_is_isa32 (bfd_vma memaddr) + } + + static const unsigned char * +-sh64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++sh64_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + /* The BRK instruction for shmedia is + 01101111 11110101 11111111 11110000 +@@ -653,7 +653,7 @@ sh64_skip_prologue_hard_way (CORE_ADDR s + } + + static CORE_ADDR +-sh64_skip_prologue (CORE_ADDR pc) ++sh64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR post_prologue_pc; + +diff -urNp src-orig/gdb/sh-tdep.c src/gdb/sh-tdep.c +--- src-orig/gdb/sh-tdep.c 2007-06-28 03:23:19.164449918 +0200 ++++ src/gdb/sh-tdep.c 2007-06-28 01:54:01.042023492 +0200 +@@ -76,7 +76,7 @@ struct sh_frame_cache + }; + + static const char * +-sh_sh_register_name (int reg_nr) ++sh_sh_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -98,7 +98,7 @@ sh_sh_register_name (int reg_nr) + } + + static const char * +-sh_sh3_register_name (int reg_nr) ++sh_sh3_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -120,7 +120,7 @@ sh_sh3_register_name (int reg_nr) + } + + static const char * +-sh_sh3e_register_name (int reg_nr) ++sh_sh3e_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -142,7 +142,7 @@ sh_sh3e_register_name (int reg_nr) + } + + static const char * +-sh_sh2e_register_name (int reg_nr) ++sh_sh2e_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -164,7 +164,7 @@ sh_sh2e_register_name (int reg_nr) + } + + static const char * +-sh_sh2a_register_name (int reg_nr) ++sh_sh2a_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + /* general registers 0-15 */ +@@ -204,7 +204,7 @@ sh_sh2a_register_name (int reg_nr) + } + + static const char * +-sh_sh2a_nofpu_register_name (int reg_nr) ++sh_sh2a_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + /* general registers 0-15 */ +@@ -244,7 +244,7 @@ sh_sh2a_nofpu_register_name (int reg_nr) + } + + static const char * +-sh_sh_dsp_register_name (int reg_nr) ++sh_sh_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -266,7 +266,7 @@ sh_sh_dsp_register_name (int reg_nr) + } + + static const char * +-sh_sh3_dsp_register_name (int reg_nr) ++sh_sh3_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -289,7 +289,7 @@ sh_sh3_dsp_register_name (int reg_nr) + } + + static const char * +-sh_sh4_register_name (int reg_nr) ++sh_sh4_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + /* general registers 0-15 */ +@@ -326,7 +326,7 @@ sh_sh4_register_name (int reg_nr) + } + + static const char * +-sh_sh4_nofpu_register_name (int reg_nr) ++sh_sh4_nofpu_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + /* general registers 0-15 */ +@@ -361,7 +361,7 @@ sh_sh4_nofpu_register_name (int reg_nr) + } + + static const char * +-sh_sh4al_dsp_register_name (int reg_nr) ++sh_sh4al_dsp_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -384,7 +384,7 @@ sh_sh4al_dsp_register_name (int reg_nr) + } + + static const unsigned char * +-sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */ + static unsigned char breakpoint[] = { 0xc3, 0xc3 }; +@@ -712,7 +712,7 @@ after_prologue (CORE_ADDR pc) + } + + static CORE_ADDR +-sh_skip_prologue (CORE_ADDR start_pc) ++sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + CORE_ADDR pc; + struct sh_frame_cache cache; +@@ -2276,10 +2276,10 @@ sh_pseudo_register_write (struct gdbarch + } + + static int +-sh_dsp_register_sim_regno (int nr) ++sh_dsp_register_sim_regno (struct gdbarch *gdbarch, int nr) + { +- if (legacy_register_sim_regno (nr) < 0) +- return legacy_register_sim_regno (nr); ++ if (legacy_register_sim_regno (gdbarch, nr) < 0) ++ return legacy_register_sim_regno (gdbarch, nr); + if (nr >= DSR_REGNUM && nr <= Y1_REGNUM) + return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM; + if (nr == MOD_REGNUM) +@@ -2294,7 +2294,7 @@ sh_dsp_register_sim_regno (int nr) + } + + static int +-sh_sh2a_register_sim_regno (int nr) ++sh_sh2a_register_sim_regno (struct gdbarch *gdbarch, int nr) + { + switch (nr) + { +@@ -2319,7 +2319,7 @@ sh_sh2a_register_sim_regno (int nr) + default: + break; + } +- return legacy_register_sim_regno (nr); ++ return legacy_register_sim_regno (gdbarch, nr); + } + + /* Set up the register unwinding such that call-clobbered registers are +diff -urNp src-orig/gdb/sparc64-tdep.c src/gdb/sparc64-tdep.c +--- src-orig/gdb/sparc64-tdep.c 2007-06-28 03:23:19.171448910 +0200 ++++ src/gdb/sparc64-tdep.c 2007-06-28 01:54:01.050022340 +0200 +@@ -227,7 +227,7 @@ static const char *sparc64_pseudo_regist + /* Return the name of register REGNUM. */ + + static const char * +-sparc64_register_name (int regnum) ++sparc64_register_name (struct gdbarch *gdbarch, int regnum) + { + if (regnum >= 0 && regnum < SPARC64_NUM_REGS) + return sparc64_register_names[regnum]; +@@ -412,7 +412,7 @@ sparc64_pseudo_register_write (struct gd + START_PC. */ + + static CORE_ADDR +-sparc64_skip_prologue (CORE_ADDR start_pc) ++sparc64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; +diff -urNp src-orig/gdb/sparc-tdep.c src/gdb/sparc-tdep.c +--- src-orig/gdb/sparc-tdep.c 2007-06-28 03:23:19.178447902 +0200 ++++ src/gdb/sparc-tdep.c 2007-06-28 01:54:01.058021187 +0200 +@@ -273,7 +273,7 @@ static const char *sparc32_pseudo_regist + /* Return the name of register REGNUM. */ + + static const char * +-sparc32_register_name (int regnum) ++sparc32_register_name (struct gdbarch *gdbarch, int regnum) + { + if (regnum >= 0 && regnum < SPARC32_NUM_REGS) + return sparc32_register_names[regnum]; +@@ -530,7 +530,7 @@ sparc32_push_dummy_call (struct gdbarch + location for inserting the breakpoint. */ + + static const gdb_byte * +-sparc_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++sparc_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static const gdb_byte break_insn[] = { 0x91, 0xd0, 0x20, 0x01 }; + +@@ -779,7 +779,7 @@ sparc_unwind_pc (struct gdbarch *gdbarch + START_PC. */ + + static CORE_ADDR +-sparc32_skip_prologue (CORE_ADDR start_pc) ++sparc32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; +diff -urNp src-orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src-orig/gdb/spu-tdep.c 2007-06-28 03:23:19.186446750 +0200 ++++ src/gdb/spu-tdep.c 2007-06-28 03:23:09.392394792 +0200 +@@ -105,7 +105,7 @@ static struct cmd_list_element *infospuc + /* Registers. */ + + static const char * +-spu_register_name (int reg_nr) ++spu_register_name (struct gdbarch *gdbarch, int reg_nr) + { + static char *register_names[] = + { +@@ -757,7 +757,7 @@ spu_analyze_prologue (CORE_ADDR start_pc + + /* Return the first instruction after the prologue starting at PC. */ + static CORE_ADDR +-spu_skip_prologue (CORE_ADDR pc) ++spu_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + struct spu_prologue_data data; + return spu_analyze_prologue (pc, (CORE_ADDR)-1, &data); +@@ -765,7 +765,8 @@ spu_skip_prologue (CORE_ADDR pc) + + /* Return the frame pointer in use at address PC. */ + static void +-spu_virtual_frame_pointer (CORE_ADDR pc, int *reg, LONGEST *offset) ++spu_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, ++ int *reg, LONGEST *offset) + { + struct spu_prologue_data data; + spu_analyze_prologue (pc, (CORE_ADDR)-1, &data); +@@ -1314,7 +1315,7 @@ spu_return_value (struct gdbarch *gdbarc + /* Breakpoints. */ + + static const gdb_byte * +-spu_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr) ++spu_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static const gdb_byte breakpoint[] = { 0x00, 0x00, 0x3f, 0xff }; + +diff -urNp src-orig/gdb/target.c src/gdb/target.c +--- src-orig/gdb/target.c 2007-06-28 03:20:01.870963786 +0200 ++++ src/gdb/target.c 2007-06-28 02:03:50.097597602 +0200 +@@ -822,10 +822,11 @@ pop_target (void) + CORE_ADDR + target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset) + { ++ struct gdbarch *gdbarch = objfile->gdbarch; + volatile CORE_ADDR addr = 0; + + if (target_get_thread_local_address_p () +- && gdbarch_fetch_tls_load_module_address_p (current_gdbarch)) ++ && gdbarch_fetch_tls_load_module_address_p (gdbarch)) + { + ptid_t ptid = inferior_ptid; + volatile struct gdb_exception ex; +@@ -835,7 +836,7 @@ target_translate_tls_address (struct obj + CORE_ADDR lm_addr; + + /* Fetch the load module address for this objfile. */ +- lm_addr = gdbarch_fetch_tls_load_module_address (current_gdbarch, ++ lm_addr = gdbarch_fetch_tls_load_module_address (gdbarch, + objfile); + /* If it's 0, throw the appropriate exception. */ + if (lm_addr == 0) +@@ -2157,18 +2158,20 @@ static void + debug_print_register (const char * func, + struct regcache *regcache, int regno) + { ++ struct gdbarch *gdbarch = get_regcache_arch (regcache); ++ + fprintf_unfiltered (gdb_stdlog, "%s ", func); +- if (regno >= 0 && regno < gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch) +- && gdbarch_register_name (current_gdbarch, regno) != NULL +- && gdbarch_register_name (current_gdbarch, regno)[0] != '\0') ++ if (regno >= 0 && regno < gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch) ++ && gdbarch_register_name (gdbarch, regno) != NULL ++ && gdbarch_register_name (gdbarch, regno)[0] != '\0') + fprintf_unfiltered (gdb_stdlog, "(%s)", gdbarch_register_name +- (current_gdbarch, regno)); ++ (gdbarch, regno)); + else + fprintf_unfiltered (gdb_stdlog, "(%d)", regno); + if (regno >= 0) + { +- int i, size = register_size (current_gdbarch, regno); ++ int i, size = register_size (gdbarch, regno); + unsigned char buf[MAX_REGISTER_SIZE]; + regcache_cooked_read (regcache, regno, buf); + fprintf_unfiltered (gdb_stdlog, " = "); +diff -urNp src-orig/gdb/target-descriptions.c src/gdb/target-descriptions.c +--- src-orig/gdb/target-descriptions.c 2007-06-28 03:23:19.191446030 +0200 ++++ src/gdb/target-descriptions.c 2007-06-28 01:54:01.075018738 +0200 +@@ -490,7 +490,7 @@ tdesc_find_register (struct gdbarch *gdb + from an architecture-provided pseudo_register_name method. */ + + const char * +-tdesc_register_name (int regno) ++tdesc_register_name (struct gdbarch *gdbarch, int regno) + { + struct tdesc_reg *reg = tdesc_find_register (current_gdbarch, regno); + int num_regs = gdbarch_num_regs (current_gdbarch); +@@ -504,7 +504,7 @@ tdesc_register_name (int regno) + struct tdesc_arch_data *data = gdbarch_data (current_gdbarch, + tdesc_data); + gdb_assert (data->pseudo_register_name != NULL); +- return data->pseudo_register_name (regno); ++ return data->pseudo_register_name (gdbarch, regno); + } + + return ""; +diff -urNp src-orig/gdb/target-descriptions.h src/gdb/target-descriptions.h +--- src-orig/gdb/target-descriptions.h 2007-06-28 03:23:19.196445310 +0200 ++++ src/gdb/target-descriptions.h 2007-06-28 01:54:01.079018162 +0200 +@@ -143,7 +143,7 @@ struct type *tdesc_named_type (const str + /* Return the name of register REGNO, from the target description or + from an architecture-provided pseudo_register_name method. */ + +-const char *tdesc_register_name (int regno); ++const char *tdesc_register_name (struct gdbarch *gdbarch, int regno); + + /* Check whether REGNUM is a member of REGGROUP using the target + description. Return -1 if the target description does not +diff -urNp src-orig/gdb/target.h src/gdb/target.h +--- src-orig/gdb/target.h 2007-06-28 03:23:19.201444590 +0200 ++++ src/gdb/target.h 2007-06-28 01:54:01.086017153 +0200 +@@ -1201,9 +1201,11 @@ extern int memory_remove_breakpoint (str + + extern int memory_insert_breakpoint (struct bp_target_info *); + +-extern int default_memory_remove_breakpoint (struct bp_target_info *); ++extern int default_memory_remove_breakpoint (struct gdbarch *, ++ struct bp_target_info *); + +-extern int default_memory_insert_breakpoint (struct bp_target_info *); ++extern int default_memory_insert_breakpoint (struct gdbarch *, ++ struct bp_target_info *); + + + /* From target.c */ +diff -urNp src-orig/gdb/trad-frame.c src/gdb/trad-frame.c +--- src-orig/gdb/trad-frame.c 2007-06-28 03:23:19.206443870 +0200 ++++ src/gdb/trad-frame.c 2007-06-28 01:54:01.091016433 +0200 +@@ -53,8 +53,8 @@ trad_frame_alloc_saved_regs (struct fram + { + int regnum; + struct gdbarch *gdbarch = get_frame_arch (next_frame); +- int numregs = gdbarch_num_regs (current_gdbarch) +- + gdbarch_num_pseudo_regs (current_gdbarch); ++ int numregs = gdbarch_num_regs (gdbarch) ++ + gdbarch_num_pseudo_regs (gdbarch); + struct trad_frame_saved_reg *this_saved_regs + = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg); + for (regnum = 0; regnum < numregs; regnum++) +diff -urNp src-orig/gdb/v850-tdep.c src/gdb/v850-tdep.c +--- src-orig/gdb/v850-tdep.c 2007-06-28 03:23:19.211443149 +0200 ++++ src/gdb/v850-tdep.c 2007-06-28 01:54:01.097015569 +0200 +@@ -141,7 +141,7 @@ struct pifsr /* Info about one saved re + }; + + static const char * +-v850_register_name (int regnum) ++v850_register_name (struct gdbarch *gdbarch, int regnum) + { + static const char *v850_reg_names[] = + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -160,7 +160,7 @@ v850_register_name (int regnum) + } + + static const char * +-v850e_register_name (int regnum) ++v850e_register_name (struct gdbarch *gdbarch, int regnum) + { + static const char *v850e_reg_names[] = + { +@@ -623,7 +623,7 @@ v850_analyze_prologue (CORE_ADDR func_ad + /* Return the address of the first code past the prologue of the function. */ + + static CORE_ADDR +-v850_skip_prologue (CORE_ADDR pc) ++v850_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr, func_end; + +@@ -806,7 +806,7 @@ v850_return_value (struct gdbarch *gdbar + } + + const static unsigned char * +-v850_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++v850_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char breakpoint[] = { 0x85, 0x05 }; + *lenptr = sizeof (breakpoint); +diff -urNp src-orig/gdb/vax-tdep.c src/gdb/vax-tdep.c +--- src-orig/gdb/vax-tdep.c 2007-06-28 03:23:19.216442429 +0200 ++++ src/gdb/vax-tdep.c 2007-06-28 01:54:01.103014704 +0200 +@@ -42,7 +42,7 @@ + /* Return the name of register REGNUM. */ + + static const char * +-vax_register_name (int regnum) ++vax_register_name (struct gdbarch *gdbarch, int regnum) + { + static char *register_names[] = + { +@@ -257,7 +257,7 @@ vax_return_value (struct gdbarch *gdbarc + location for inserting the breakpoint. */ + + static const gdb_byte * +-vax_breakpoint_from_pc (CORE_ADDR *pc, int *len) ++vax_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) + { + static gdb_byte break_insn[] = { 3 }; + +@@ -269,7 +269,7 @@ vax_breakpoint_from_pc (CORE_ADDR *pc, i + to reach some "real" code. */ + + static CORE_ADDR +-vax_skip_prologue (CORE_ADDR pc) ++vax_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + gdb_byte op = read_memory_unsigned_integer (pc, 1); + +diff -urNp src-orig/gdb/xstormy16-tdep.c src/gdb/xstormy16-tdep.c +--- src-orig/gdb/xstormy16-tdep.c 2007-06-28 03:23:19.221441709 +0200 ++++ src/gdb/xstormy16-tdep.c 2007-06-28 01:54:01.109013840 +0200 +@@ -106,7 +106,7 @@ enum + Returns the name of the standard Xstormy16 register N. */ + + static const char * +-xstormy16_register_name (int regnum) ++xstormy16_register_name (struct gdbarch *gdbarch, int regnum) + { + static char *register_names[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -406,7 +406,7 @@ xstormy16_analyze_prologue (CORE_ADDR st + stepped into a function call. */ + + static CORE_ADDR +-xstormy16_skip_prologue (CORE_ADDR pc) ++xstormy16_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) + { + CORE_ADDR func_addr = 0, func_end = 0; + char *func_name; +@@ -492,7 +492,8 @@ xstormy16_in_function_epilogue_p (struct + } + + const static unsigned char * +-xstormy16_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++xstormy16_breakpoint_from_pc (struct gdbarch *gdbarch, ++ CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char breakpoint[] = { 0x06, 0x0 }; + *lenptr = sizeof (breakpoint); +diff -urNp src-orig/gdb/xtensa-tdep.c src/gdb/xtensa-tdep.c +--- src-orig/gdb/xtensa-tdep.c 2007-06-28 03:23:19.228440701 +0200 ++++ src/gdb/xtensa-tdep.c 2007-06-28 01:54:01.118012543 +0200 +@@ -179,7 +179,7 @@ extract_call_winsize (CORE_ADDR pc) + /* Returns the name of a register. */ + + static const char * +-xtensa_register_name (int regnum) ++xtensa_register_name (struct gdbarch *gdbarch, int regnum) + { + /* Return the name stored in the register map. */ + if (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch) +@@ -285,7 +285,7 @@ xtensa_register_type (struct gdbarch *gd + to n for An. So, we only have to add the base number for A0. */ + + static int +-xtensa_reg_to_regnum (int regnum) ++xtensa_reg_to_regnum (struct gdbarch *gdbarch, int regnum) + { + int i; + +@@ -493,7 +493,7 @@ xtensa_pseudo_register_read (struct gdba + gdb_byte *buffer) + { + DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n", +- regnum, xtensa_register_name (regnum)); ++ regnum, xtensa_register_name (gdbarch, regnum)); + + /* Check if it is FP (renumber it in this case -> A0...A15). */ + if (regnum == FP_ALIAS) +@@ -527,7 +527,7 @@ xtensa_pseudo_register_read (struct gdba + if ((flags & xtTargetFlagsNonVisibleRegs) == 0) + { + warning (_("cannot read register %s"), +- xtensa_register_name (regnum)); ++ xtensa_register_name (gdbarch, regnum)); + return; + } + } +@@ -576,7 +576,7 @@ xtensa_pseudo_register_write (struct gdb + const gdb_byte *buffer) + { + DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n", +- regnum, xtensa_register_name (regnum)); ++ regnum, xtensa_register_name (gdbarch, regnum)); + + /* Check if this is FP. */ + if (regnum == FP_ALIAS) +@@ -613,7 +613,7 @@ xtensa_pseudo_register_write (struct gdb + if ((flags & xtTargetFlagsNonVisibleRegs) == 0) + { + warning (_("cannot write register %s"), +- xtensa_register_name (regnum)); ++ xtensa_register_name (gdbarch, regnum)); + return; + } + } +@@ -1056,7 +1056,7 @@ xtensa_frame_prev_register (struct frame + "*this %p, regnum %d (%s), ...)\n", + next_frame, + *this_cache ? *this_cache : 0, regnum, +- xtensa_register_name (regnum)); ++ xtensa_register_name (current_gdbarch, regnum)); + + if (regnum == WS_REGNUM) + { +@@ -1523,7 +1523,7 @@ xtensa_push_dummy_call (struct gdbarch * + #define DENSITY_LITTLE_BREAKPOINT { 0x2d, 0xf0 } + + const unsigned char * +-xtensa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) ++xtensa_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) + { + static unsigned char big_breakpoint[] = BIG_BREAKPOINT; + static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT; +@@ -1581,7 +1581,7 @@ xtensa_breakpoint_from_pc (CORE_ADDR *pc + If there is no debug info, we need to analyze the code. */ + + CORE_ADDR +-xtensa_skip_prologue (CORE_ADDR start_pc) ++xtensa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) + { + DEBUGTRACE ("xtensa_skip_prologue (start_pc = 0x%08x)\n", (int) start_pc); + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-solib-auxv +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-solib-auxv @@ -0,0 +1,328 @@ +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-25 21:43:46.973322273 +0200 ++++ src/gdb/Makefile.in 2007-06-25 21:44:39.391623649 +0200 +@@ -2595,7 +2595,7 @@ solib-svr4.o: solib-svr4.c $(defs_h) $(e + $(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ + $(gdbcore_h) $(target_h) $(inferior_h) $(gdb_assert_h) \ + $(solist_h) $(solib_h) $(solib_svr4_h) $(bfd_target_h) $(elf_bfd_h) \ +- $(exec_h) ++ $(exec_h) $(auxv_h) + sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \ + $(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) \ + $(solib_h) $(symfile_h) $(observer_h) $(gdb_string_h) $(gregset_h) +diff -urNp src-orig/gdb/solib-svr4.c src/gdb/solib-svr4.c +--- src-orig/gdb/solib-svr4.c 2007-06-25 21:43:47.024314934 +0200 ++++ src/gdb/solib-svr4.c 2007-06-25 21:44:39.435617318 +0200 +@@ -43,6 +43,7 @@ + #include "bfd-target.h" + #include "elf-bfd.h" + #include "exec.h" ++#include "auxv.h" + + static struct link_map_offsets *svr4_fetch_link_map_offsets (void); + static int svr4_have_link_map_offsets (void); +@@ -345,6 +346,139 @@ bfd_lookup_symbol (bfd *abfd, char *symn + return symaddr; + } + ++ ++/* Read program header TYPE from inferior memory. The header is found ++ by scanning the OS auxillary vector. ++ ++ Return a pointer to allocated memory holding the program header contents, ++ or NULL on failure. If sucessful, and unless P_SECT_SIZE is NULL, the ++ size of those contents is returned to P_SECT_SIZE. Likewise, the target ++ architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE. */ ++ ++static gdb_byte * ++read_program_header (int type, int *p_sect_size, int *p_arch_size) ++{ ++ CORE_ADDR at_phdr, at_phent, at_phnum; ++ int arch_size, sect_size; ++ CORE_ADDR sect_addr; ++ gdb_byte *buf; ++ ++ /* Get required auxv elements from target. */ ++ if (target_auxv_search (¤t_target, AT_PHDR, &at_phdr) <= 0) ++ return 0; ++ if (target_auxv_search (¤t_target, AT_PHENT, &at_phent) <= 0) ++ return 0; ++ if (target_auxv_search (¤t_target, AT_PHNUM, &at_phnum) <= 0) ++ return 0; ++ if (!at_phdr || !at_phnum) ++ return 0; ++ ++ /* Determine ELF architecture type. */ ++ if (at_phent == sizeof (Elf32_External_Phdr)) ++ arch_size = 32; ++ else if (at_phent == sizeof (Elf64_External_Phdr)) ++ arch_size = 64; ++ else ++ return 0; ++ ++ /* Find .dynamic section via the PT_DYNAMIC PHDR. */ ++ if (arch_size == 32) ++ { ++ Elf32_External_Phdr phdr; ++ int i; ++ ++ /* Search for requested PHDR. */ ++ for (i = 0; i < at_phnum; i++) ++ { ++ if (target_read_memory (at_phdr + i * sizeof (phdr), ++ (gdb_byte *)&phdr, sizeof (phdr))) ++ return 0; ++ ++ if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, 4) ++ == type) ++ break; ++ } ++ ++ if (i == at_phnum) ++ return 0; ++ ++ /* Retrieve address and size. */ ++ sect_addr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr, 4); ++ sect_size = extract_unsigned_integer ((gdb_byte *)phdr.p_memsz, 4); ++ } ++ else ++ { ++ Elf64_External_Phdr phdr; ++ int i; ++ ++ /* Search for requested PHDR. */ ++ for (i = 0; i < at_phnum; i++) ++ { ++ if (target_read_memory (at_phdr + i * sizeof (phdr), ++ (gdb_byte *)&phdr, sizeof (phdr))) ++ return 0; ++ ++ if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, 4) ++ == type) ++ break; ++ } ++ ++ if (i == at_phnum) ++ return 0; ++ ++ /* Retrieve address and size. */ ++ sect_addr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr, 8); ++ sect_size = extract_unsigned_integer ((gdb_byte *)phdr.p_memsz, 8); ++ } ++ ++ /* Read in requested program header. */ ++ buf = xmalloc (sect_size); ++ if (target_read_memory (sect_addr, buf, sect_size)) ++ { ++ xfree (buf); ++ return NULL; ++ } ++ ++ if (p_arch_size) ++ *p_arch_size = arch_size; ++ if (p_sect_size) ++ *p_sect_size = sect_size; ++ ++ return buf; ++} ++ ++ ++/* Return program interpreter string. */ ++static gdb_byte * ++find_program_interpreter (void) ++{ ++ gdb_byte *buf = NULL; ++ ++ /* If we have an exec_bfd, use its section table. */ ++ if (exec_bfd ++ && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) ++ { ++ struct bfd_section *interp_sect; ++ ++ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); ++ if (interp_sect != NULL) ++ { ++ CORE_ADDR sect_addr = bfd_section_vma (exec_bfd, interp_sect); ++ int sect_size = bfd_section_size (exec_bfd, interp_sect); ++ ++ buf = xmalloc (sect_size); ++ bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, sect_size); ++ } ++ } ++ ++ /* If we didn't find it, use the target auxillary vector. */ ++ if (!buf) ++ buf = read_program_header (PT_INTERP, NULL, NULL); ++ ++ return buf; ++} ++ ++ + /* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is + returned and the corresponding PTR is set. */ + +@@ -414,6 +548,55 @@ scan_dyntag (int dyntag, bfd *abfd, CORE + return 0; + } + ++/* Scan for DYNTAG in .dynamic section of the target's main executable, ++ found by consulting the OS auxillary vector. If DYNTAG is found 1 is ++ returned and the corresponding PTR is set. */ ++ ++static int ++scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr) ++{ ++ int sect_size, arch_size, step; ++ long dyn_tag; ++ CORE_ADDR dyn_ptr; ++ gdb_byte *bufend, *buf; ++ ++ /* Read in .dynamic section. */ ++ buf = read_program_header (PT_DYNAMIC, §_size, &arch_size); ++ if (!buf) ++ return 0; ++ ++ /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ ++ step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) ++ : sizeof (Elf64_External_Dyn); ++ for (bufend = buf + sect_size; ++ buf < bufend; ++ buf += step) ++ { ++ if (arch_size == 32) ++ { ++ Elf32_External_Dyn *dynp = (Elf32_External_Dyn *) buf; ++ dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag, 4); ++ dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr, 4); ++ } ++ else ++ { ++ Elf64_External_Dyn *dynp = (Elf64_External_Dyn *) buf; ++ dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag, 8); ++ dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr, 8); ++ } ++ if (dyn_tag == DT_NULL) ++ return 0; ++ if (dyn_tag == dyntag) ++ { ++ if (ptr) ++ *ptr = dyn_ptr; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ + + /* + +@@ -446,11 +629,13 @@ elf_locate_base (void) + CORE_ADDR dyn_ptr; + + /* Find DT_DEBUG. */ +- if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)) ++ if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr) ++ || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr)) + return dyn_ptr; + + /* Find DT_MIPS_RLD_MAP. */ +- if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)) ++ if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr) ++ || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr)) + { + gdb_byte *pbuf; + int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); +@@ -956,7 +1141,7 @@ enable_break (void) + + struct minimal_symbol *msymbol; + char **bkpt_namep; +- asection *interp_sect; ++ gdb_byte *interp_name; + + /* First, remove all the solib event breakpoints. Their addresses + may have changed since the last time we ran the program. */ +@@ -965,13 +1150,11 @@ enable_break (void) + interp_text_sect_low = interp_text_sect_high = 0; + interp_plt_sect_low = interp_plt_sect_high = 0; + +- /* Find the .interp section; if not found, warn the user and drop ++ /* Find the program interpreter; if not found, warn the user and drop + into the old breakpoint at symbol code. */ +- interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); +- if (interp_sect) ++ interp_name = find_program_interpreter (); ++ if (interp_name) + { +- unsigned int interp_sect_size; +- char *buf; + CORE_ADDR load_addr = 0; + int load_addr_found = 0; + struct so_list *so; +@@ -980,13 +1163,7 @@ enable_break (void) + int tmp_fd = -1; + char *tmp_pathname = NULL; + CORE_ADDR sym_addr = 0; +- +- /* Read the contents of the .interp section into a local buffer; +- the contents specify the dynamic linker this program uses. */ +- interp_sect_size = bfd_section_size (exec_bfd, interp_sect); +- buf = alloca (interp_sect_size); +- bfd_get_section_contents (exec_bfd, interp_sect, +- buf, 0, interp_sect_size); ++ asection *interp_sect; + + /* Now we need to figure out where the dynamic linker was + loaded so that we can load its symbols and place a breakpoint +@@ -1002,7 +1179,7 @@ enable_break (void) + the AT_BASE auxilliary entry, which GDB now knows how to + access, to find the base address. */ + +- tmp_fd = solib_open (buf, &tmp_pathname); ++ tmp_fd = solib_open (interp_name, &tmp_pathname); + if (tmp_fd >= 0) + tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd); + +@@ -1012,7 +1189,8 @@ enable_break (void) + /* Make sure the dynamic linker's really a useful object. */ + if (!bfd_check_format (tmp_bfd, bfd_object)) + { +- warning (_("Unable to grok dynamic linker %s as an object file"), buf); ++ warning (_("Unable to grok dynamic linker %s as an object file"), ++ interp_name); + bfd_close (tmp_bfd); + goto bkpt_at_symbol; + } +@@ -1028,7 +1206,7 @@ enable_break (void) + so = master_so_list (); + while (so) + { +- if (strcmp (buf, so->so_original_name) == 0) ++ if (strcmp (interp_name, so->so_original_name) == 0) + { + load_addr_found = 1; + load_addr = LM_ADDR_CHECK (so, tmp_bfd); +@@ -1044,7 +1222,7 @@ enable_break (void) + { + load_addr = (read_pc () + - exec_entry_point (tmp_bfd, tmp_bfd_target)); +- debug_loader_name = xstrdup (buf); ++ debug_loader_name = xstrdup (interp_name); + debug_loader_offset_p = 1; + debug_loader_offset = load_addr; + solib_add (NULL, 0, ¤t_target, auto_solib_add); +@@ -1092,12 +1270,14 @@ enable_break (void) + if (sym_addr != 0) + { + create_solib_event_breakpoint (load_addr + sym_addr); ++ xfree (interp_name); + return 1; + } + + /* For whatever reason we couldn't set a breakpoint in the dynamic + linker. Warn and drop into the old code. */ + bkpt_at_symbol: ++ xfree (interp_name); + warning (_("Unable to find dynamic linker breakpoint function.\n" + "GDB will be unable to debug shared library initializers\n" + "and track explicitly loaded dynamic code.")); --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-corewrite +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-corewrite @@ -0,0 +1,512 @@ +diff -urNp src-orig/gdb/ppc-linux-nat.c src/gdb/ppc-linux-nat.c +--- src-orig/gdb/ppc-linux-nat.c 2007-06-18 19:45:26.000000000 +0200 ++++ src/gdb/ppc-linux-nat.c 2007-06-25 21:40:07.784493033 +0200 +@@ -903,103 +903,70 @@ ppc_linux_store_inferior_registers (stru + store_ppc_registers (regcache, tid); + } + ++ ++/* Functions for transferring registers between a gregset_t or fpregset_t ++ (see sys/ucontext.h) and gdb's regcache. The word size is that used ++ by the ptrace interface, not the current program's ABI. eg. If a ++ powerpc64-linux gdb is being used to debug a powerpc32-linux app, we ++ read or write 64-bit gregsets. This is to suit the host libthread_db. ++ ++ Note that the fill_gregset and fill_fpregset functions allow for ++ writing just one register into a gregset_t or fpregset_t buffer. ++ If it so happens that the field in the buffer is larger than gdb's ++ idea of the register size, then the high order bits of the field ++ will not be written. Currently, we always write the whole regset. */ ++ + void + supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp) + { +- /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace +- interface, and not the wordsize of the program's ABI. */ +- int wordsize = sizeof (long); +- ppc_linux_supply_gregset (regcache, -1, gregsetp, +- sizeof (gdb_gregset_t), wordsize); +-} ++ const struct regset *regset; ++ regset = ppc_linux_gregset (get_regcache_arch (regcache)); + +-static void +-right_fill_reg (const struct regcache *regcache, int regnum, void *reg) +-{ +- /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace +- interface, and not the wordsize of the program's ABI. */ +- int wordsize = sizeof (long); +- /* Right fill the register. */ +- regcache_raw_collect (regcache, regnum, +- ((bfd_byte *) reg +- + wordsize +- - register_size (current_gdbarch, regnum))); ++ ppc_supply_gregset (regset, regcache, -1, ++ gregsetp, sizeof (*gregsetp)); + } + + void + fill_gregset (const struct regcache *regcache, + gdb_gregset_t *gregsetp, int regno) + { +- int regi; +- elf_greg_t *regp = (elf_greg_t *) gregsetp; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); +- const int elf_ngreg = 48; +- +- +- /* Start with zeros. */ +- memset (regp, 0, elf_ngreg * sizeof (*regp)); +- +- for (regi = 0; regi < ppc_num_gprs; regi++) +- { +- if ((regno == -1) || regno == tdep->ppc_gp0_regnum + regi) +- right_fill_reg (regcache, tdep->ppc_gp0_regnum + regi, +- (regp + PT_R0 + regi)); +- } +- +- if ((regno == -1) || regno == gdbarch_pc_regnum (current_gdbarch)) +- right_fill_reg (regcache, gdbarch_pc_regnum (current_gdbarch), +- regp + PT_NIP); +- if ((regno == -1) || regno == tdep->ppc_lr_regnum) +- right_fill_reg (regcache, tdep->ppc_lr_regnum, regp + PT_LNK); +- if ((regno == -1) || regno == tdep->ppc_cr_regnum) +- regcache_raw_collect (regcache, tdep->ppc_cr_regnum, +- regp + PT_CCR); +- if ((regno == -1) || regno == tdep->ppc_xer_regnum) +- regcache_raw_collect (regcache, tdep->ppc_xer_regnum, +- regp + PT_XER); +- if ((regno == -1) || regno == tdep->ppc_ctr_regnum) +- right_fill_reg (regcache, tdep->ppc_ctr_regnum, regp + PT_CTR); +-#ifdef PT_MQ +- if (((regno == -1) || regno == tdep->ppc_mq_regnum) +- && (tdep->ppc_mq_regnum != -1)) +- right_fill_reg (regcache, tdep->ppc_mq_regnum, regp + PT_MQ); +-#endif +- if ((regno == -1) || regno == tdep->ppc_ps_regnum) +- right_fill_reg (regcache, tdep->ppc_ps_regnum, regp + PT_MSR); ++ const struct regset *regset; ++ regset = ppc_linux_gregset (get_regcache_arch (regcache)); ++ ++ gdb_assert (regno == -1); ++ if (regno == -1) ++ memset (gregsetp, 0, sizeof (*gregsetp)); ++ ++ ppc_collect_gregset (regset, regcache, regno, ++ gregsetp, sizeof (*gregsetp)); + } + + void +-supply_fpregset (struct regcache *regcache, const gdb_fpregset_t * fpregsetp) ++supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp) + { +- ppc_linux_supply_fpregset (NULL, regcache, -1, fpregsetp, +- sizeof (gdb_fpregset_t)); ++ const struct regset *regset; ++ regset = ppc_linux_gregset (get_regcache_arch (regcache)); ++ ++ ppc_supply_fpregset (regset, regcache, -1, ++ fpregsetp, sizeof (*fpregsetp)); + } + +-/* Given a pointer to a floating point register set in /proc format +- (fpregset_t *), update the register specified by REGNO from gdb's +- idea of the current floating point register set. If REGNO is -1, +- update them all. */ + void + fill_fpregset (const struct regcache *regcache, + gdb_fpregset_t *fpregsetp, int regno) + { +- int regi; +- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); +- bfd_byte *fpp = (void *) fpregsetp; +- +- if (ppc_floating_point_unit_p (current_gdbarch)) +- { +- for (regi = 0; regi < ppc_num_fprs; regi++) +- { +- if ((regno == -1) || (regno == tdep->ppc_fp0_regnum + regi)) +- regcache_raw_collect (regcache, tdep->ppc_fp0_regnum + regi, +- fpp + 8 * regi); +- } +- if (regno == -1 || regno == tdep->ppc_fpscr_regnum) +- right_fill_reg (regcache, tdep->ppc_fpscr_regnum, (fpp + 8 * 32)); +- } ++ const struct regset *regset; ++ regset = ppc_linux_gregset (get_regcache_arch (regcache)); ++ ++ gdb_assert (regno == -1); ++ if (regno == -1) ++ memset (fpregsetp, 0, sizeof (*fpregsetp)); ++ ++ ppc_collect_fpregset (regset, regcache, regno, ++ fpregsetp, sizeof (*fpregsetp)); + } + ++ + void _initialize_ppc_linux_nat (void); + + void +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-06-25 21:39:56.402403458 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-06-25 21:40:07.831486270 +0200 +@@ -40,51 +40,6 @@ + #include "frame-unwind.h" + #include "tramp-frame.h" + +-/* From , values for PT_NIP, PT_R1, and PT_LNK */ +-#define PPC_LINUX_PT_R0 0 +-#define PPC_LINUX_PT_R1 1 +-#define PPC_LINUX_PT_R2 2 +-#define PPC_LINUX_PT_R3 3 +-#define PPC_LINUX_PT_R4 4 +-#define PPC_LINUX_PT_R5 5 +-#define PPC_LINUX_PT_R6 6 +-#define PPC_LINUX_PT_R7 7 +-#define PPC_LINUX_PT_R8 8 +-#define PPC_LINUX_PT_R9 9 +-#define PPC_LINUX_PT_R10 10 +-#define PPC_LINUX_PT_R11 11 +-#define PPC_LINUX_PT_R12 12 +-#define PPC_LINUX_PT_R13 13 +-#define PPC_LINUX_PT_R14 14 +-#define PPC_LINUX_PT_R15 15 +-#define PPC_LINUX_PT_R16 16 +-#define PPC_LINUX_PT_R17 17 +-#define PPC_LINUX_PT_R18 18 +-#define PPC_LINUX_PT_R19 19 +-#define PPC_LINUX_PT_R20 20 +-#define PPC_LINUX_PT_R21 21 +-#define PPC_LINUX_PT_R22 22 +-#define PPC_LINUX_PT_R23 23 +-#define PPC_LINUX_PT_R24 24 +-#define PPC_LINUX_PT_R25 25 +-#define PPC_LINUX_PT_R26 26 +-#define PPC_LINUX_PT_R27 27 +-#define PPC_LINUX_PT_R28 28 +-#define PPC_LINUX_PT_R29 29 +-#define PPC_LINUX_PT_R30 30 +-#define PPC_LINUX_PT_R31 31 +-#define PPC_LINUX_PT_NIP 32 +-#define PPC_LINUX_PT_MSR 33 +-#define PPC_LINUX_PT_CTR 35 +-#define PPC_LINUX_PT_LNK 36 +-#define PPC_LINUX_PT_XER 37 +-#define PPC_LINUX_PT_CCR 38 +-#define PPC_LINUX_PT_MQ 39 +-#define PPC_LINUX_PT_FPR0 48 /* each FP reg occupies 2 slots in this space */ +-#define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31) +-#define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1) +- +- + static CORE_ADDR + ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) + { +@@ -662,99 +617,120 @@ ppc_linux_convert_from_func_ptr_addr (st + return addr; + } + +-static void +-right_supply_register (struct regcache *regcache, int wordsize, int regnum, +- const bfd_byte *buf) +-{ +- regcache_raw_supply (regcache, regnum, +- (buf + wordsize - register_size (current_gdbarch, regnum))); +-} +- +-/* Extract the register values found in the WORDSIZED ABI GREGSET, +- storing their values in REGCACHE. Note that some are left-aligned, +- while others are right aligned. */ ++/* Regset descriptions. */ ++static const struct ppc_reg_offsets ppc32_linux_reg_offsets = ++ { ++ /* General-purpose registers. */ ++ /* .r0_offset = */ 0, ++ /* .gpr_size = */ 4, ++ /* .pc_offset = */ 128, ++ /* .ps_offset = */ 132, ++ /* .cr_offset = */ 152, ++ /* .lr_offset = */ 144, ++ /* .ctr_offset = */ 140, ++ /* .xer_offset = */ 148, ++ /* .mq_offset = */ 156, ++ ++ /* Floating-point registers. */ ++ /* .f0_offset = */ 0, ++ /* .fpscr_offset = */ 256 + 4, ++ ++ /* AltiVec registers. */ ++ /* .vr0_offset = */ 0, ++ /* .vrsave_offset = */ 512, ++ /* .vscr_offset = */ 512 + 12 ++ }; + +-void +-ppc_linux_supply_gregset (struct regcache *regcache, +- int regnum, const void *gregs, size_t size, +- int wordsize) +-{ +- int regi; +- struct gdbarch *regcache_arch = get_regcache_arch (regcache); +- struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch); +- const bfd_byte *buf = gregs; +- +- for (regi = 0; regi < ppc_num_gprs; regi++) +- right_supply_register (regcache, wordsize, +- regcache_tdep->ppc_gp0_regnum + regi, +- buf + wordsize * regi); +- +- right_supply_register (regcache, wordsize, gdbarch_pc_regnum (regcache_arch), +- buf + wordsize * PPC_LINUX_PT_NIP); +- right_supply_register (regcache, wordsize, regcache_tdep->ppc_lr_regnum, +- buf + wordsize * PPC_LINUX_PT_LNK); +- regcache_raw_supply (regcache, regcache_tdep->ppc_cr_regnum, +- buf + wordsize * PPC_LINUX_PT_CCR); +- regcache_raw_supply (regcache, regcache_tdep->ppc_xer_regnum, +- buf + wordsize * PPC_LINUX_PT_XER); +- regcache_raw_supply (regcache, regcache_tdep->ppc_ctr_regnum, +- buf + wordsize * PPC_LINUX_PT_CTR); +- if (regcache_tdep->ppc_mq_regnum != -1) +- right_supply_register (regcache, wordsize, regcache_tdep->ppc_mq_regnum, +- buf + wordsize * PPC_LINUX_PT_MQ); +- right_supply_register (regcache, wordsize, regcache_tdep->ppc_ps_regnum, +- buf + wordsize * PPC_LINUX_PT_MSR); +-} ++static const struct ppc_reg_offsets ppc64_linux_reg_offsets = ++ { ++ /* General-purpose registers. */ ++ /* .r0_offset = */ 0, ++ /* .gpr_size = */ 8, ++ /* .pc_offset = */ 256, ++ /* .ps_offset = */ 264, ++ /* .cr_offset = */ 304 + 4, ++ /* .lr_offset = */ 288, ++ /* .ctr_offset = */ 280, ++ /* .xer_offset = */ 296 + 4, ++ /* .mq_offset = */ 312 + 4, ++ ++ /* Floating-point registers. */ ++ /* .f0_offset = */ 0, ++ /* .fpscr_offset = */ 256 + 4, ++ ++ /* AltiVec registers. */ ++ /* .vr0_offset = */ 0, ++ /* .vrsave_offset = */ 528, ++ /* .vscr_offset = */ 512 + 12 ++ }; + +-static void +-ppc32_linux_supply_gregset (const struct regset *regset, +- struct regcache *regcache, +- int regnum, const void *gregs, size_t size) +-{ +- ppc_linux_supply_gregset (regcache, regnum, gregs, size, 4); +-} ++static const struct ppc_reg_offsets ppc64_32_linux_reg_offsets = ++ { ++ /* General-purpose registers. */ ++ /* .r0_offset = */ 0 + 4, ++ /* .gpr_size = */ 8, ++ /* .pc_offset = */ 256 + 4, ++ /* .ps_offset = */ 264 + 4, ++ /* .cr_offset = */ 304 + 4, ++ /* .lr_offset = */ 288 + 4, ++ /* .ctr_offset = */ 280 + 4, ++ /* .xer_offset = */ 296 + 4, ++ /* .mq_offset = */ 312 + 4, ++ ++ /* Floating-point registers. */ ++ /* .f0_offset = */ 0, ++ /* .fpscr_offset = */ 256 + 4, ++ ++ /* AltiVec registers. */ ++ /* .vr0_offset = */ 0, ++ /* .vrsave_offset = */ 528, ++ /* .vscr_offset = */ 512 + 12 ++ }; + + static struct regset ppc32_linux_gregset = { +- NULL, ppc32_linux_supply_gregset ++ &ppc32_linux_reg_offsets, ++ ppc_supply_gregset, ++ ppc_collect_gregset, ++ NULL + }; + +-static void +-ppc64_linux_supply_gregset (const struct regset *regset, +- struct regcache * regcache, +- int regnum, const void *gregs, size_t size) +-{ +- ppc_linux_supply_gregset (regcache, regnum, gregs, size, 8); +-} +- + static struct regset ppc64_linux_gregset = { +- NULL, ppc64_linux_supply_gregset ++ &ppc64_linux_reg_offsets, ++ ppc_supply_gregset, ++ ppc_collect_gregset, ++ NULL + }; + +-void +-ppc_linux_supply_fpregset (const struct regset *regset, +- struct regcache * regcache, +- int regnum, const void *fpset, size_t size) +-{ +- int regi; +- struct gdbarch *regcache_arch = get_regcache_arch (regcache); +- struct gdbarch_tdep *regcache_tdep = gdbarch_tdep (regcache_arch); +- const bfd_byte *buf = fpset; +- +- if (! ppc_floating_point_unit_p (regcache_arch)) +- return; +- +- for (regi = 0; regi < ppc_num_fprs; regi++) +- regcache_raw_supply (regcache, +- regcache_tdep->ppc_fp0_regnum + regi, +- buf + 8 * regi); +- +- /* The FPSCR is stored in the low order word of the last +- doubleword in the fpregset. */ +- regcache_raw_supply (regcache, regcache_tdep->ppc_fpscr_regnum, +- buf + 8 * 32 + 4); ++static struct regset ppc64_32_linux_gregset = { ++ &ppc64_32_linux_reg_offsets, ++ ppc_supply_gregset, ++ ppc_collect_gregset, ++ NULL ++}; ++ ++static struct regset ppc32_linux_fpregset = { ++ &ppc32_linux_reg_offsets, ++ ppc_supply_fpregset, ++ ppc_collect_fpregset, ++ NULL ++}; ++ ++const struct regset * ++ppc_linux_gregset (struct gdbarch *gdbarch) ++{ ++ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); ++ if (tdep->wordsize == 8) ++ return &ppc64_linux_gregset; ++ if (sizeof (long) == 8) ++ return &ppc64_32_linux_gregset; ++ return &ppc32_linux_gregset; + } + +-static struct regset ppc_linux_fpregset = { NULL, ppc_linux_supply_fpregset }; ++const struct regset * ++ppc_linux_fpregset (struct gdbarch *gdbarch) ++{ ++ return &ppc32_linux_fpregset; ++} + + static const struct regset * + ppc_linux_regset_from_core_section (struct gdbarch *core_arch, +@@ -769,7 +745,7 @@ ppc_linux_regset_from_core_section (stru + return &ppc64_linux_gregset; + } + if (strcmp (sect_name, ".reg2") == 0) +- return &ppc_linux_fpregset; ++ return &ppc32_linux_fpregset; + return NULL; + } + +diff -urNp src-orig/gdb/ppcnbsd-tdep.c src/gdb/ppcnbsd-tdep.c +--- src-orig/gdb/ppcnbsd-tdep.c 2007-06-18 19:45:26.000000000 +0200 ++++ src/gdb/ppcnbsd-tdep.c 2007-06-25 21:40:07.835485695 +0200 +@@ -215,6 +215,7 @@ _initialize_ppcnbsd_tdep (void) + { + /* General-purpose registers. */ + ppcnbsd_reg_offsets.r0_offset = 0; ++ ppcnbsd_reg_offsets.gpr_size = 4; + ppcnbsd_reg_offsets.lr_offset = 128; + ppcnbsd_reg_offsets.cr_offset = 132; + ppcnbsd_reg_offsets.xer_offset = 136; +diff -urNp src-orig/gdb/ppcobsd-tdep.c src/gdb/ppcobsd-tdep.c +--- src-orig/gdb/ppcobsd-tdep.c 2007-06-18 19:45:26.000000000 +0200 ++++ src/gdb/ppcobsd-tdep.c 2007-06-25 21:40:07.840484975 +0200 +@@ -333,6 +333,7 @@ _initialize_ppcobsd_tdep (void) + { + /* General-purpose registers. */ + ppcobsd_reg_offsets.r0_offset = 0; ++ ppcobsd_reg_offsets.gpr_size = 4; + ppcobsd_reg_offsets.pc_offset = 384; + ppcobsd_reg_offsets.ps_offset = 388; + ppcobsd_reg_offsets.cr_offset = 392; +diff -urNp src-orig/gdb/ppc-tdep.h src/gdb/ppc-tdep.h +--- src-orig/gdb/ppc-tdep.h 2007-06-16 19:25:59.000000000 +0200 ++++ src/gdb/ppc-tdep.h 2007-06-25 21:40:07.845484256 +0200 +@@ -58,12 +58,8 @@ CORE_ADDR ppc64_sysv_abi_adjust_breakpoi + CORE_ADDR bpaddr); + int ppc_linux_memory_remove_breakpoint (struct bp_target_info *bp_tgt); + struct link_map_offsets *ppc_linux_svr4_fetch_link_map_offsets (void); +-void ppc_linux_supply_gregset (struct regcache *regcache, +- int regnum, const void *gregs, size_t size, +- int wordsize); +-void ppc_linux_supply_fpregset (const struct regset *regset, +- struct regcache *regcache, +- int regnum, const void *gregs, size_t size); ++const struct regset *ppc_linux_gregset (struct gdbarch *); ++const struct regset *ppc_linux_fpregset (struct gdbarch *); + + enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, + struct type *valtype, +@@ -85,6 +81,7 @@ struct ppc_reg_offsets + { + /* General-purpose registers. */ + int r0_offset; ++ int gpr_size; + int pc_offset; + int ps_offset; + int cr_offset; +diff -urNp src-orig/gdb/rs6000-tdep.c src/gdb/rs6000-tdep.c +--- src-orig/gdb/rs6000-tdep.c 2007-06-18 19:45:26.000000000 +0200 ++++ src/gdb/rs6000-tdep.c 2007-06-25 21:40:07.855482817 +0200 +@@ -336,7 +336,7 @@ ppc_supply_gregset (const struct regset + + for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset; + i < tdep->ppc_gp0_regnum + ppc_num_gprs; +- i++, offset += 4) ++ i++, offset += offsets->gpr_size) + { + if (regnum == -1 || regnum == i) + ppc_supply_reg (regcache, i, gregs, offset); +@@ -359,7 +359,7 @@ ppc_supply_gregset (const struct regset + gregs, offsets->ctr_offset); + if (regnum == -1 || regnum == tdep->ppc_xer_regnum) + ppc_supply_reg (regcache, tdep->ppc_xer_regnum, +- gregs, offsets->cr_offset); ++ gregs, offsets->xer_offset); + if (regnum == -1 || regnum == tdep->ppc_mq_regnum) + ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset); + } +@@ -395,7 +395,7 @@ ppc_supply_fpregset (const struct regset + } + + /* Collect register REGNUM in the general-purpose register set +- REGSET. from register cache REGCACHE into the buffer specified by ++ REGSET from register cache REGCACHE into the buffer specified by + GREGS and LEN. If REGNUM is -1, do this for all registers in + REGSET. */ + +@@ -413,7 +413,7 @@ ppc_collect_gregset (const struct regset + offset = offsets->r0_offset; + for (i = tdep->ppc_gp0_regnum; + i < tdep->ppc_gp0_regnum + ppc_num_gprs; +- i++, offset += 4) ++ i++, offset += offsets->gpr_size) + { + if (regnum == -1 || regnum == i) + ppc_collect_reg (regcache, i, gregs, offset); +@@ -443,7 +443,7 @@ ppc_collect_gregset (const struct regset + } + + /* Collect register REGNUM in the floating-point register set +- REGSET. from register cache REGCACHE into the buffer specified by ++ REGSET from register cache REGCACHE into the buffer specified by + FPREGS and LEN. If REGNUM is -1, do this for all registers in + REGSET. */ + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-ppc-morefixes +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-ppc-morefixes @@ -0,0 +1,25 @@ +diff -urNp src-orig/gdb/rs6000-tdep.c src/gdb/rs6000-tdep.c +--- src-orig/gdb/rs6000-tdep.c 2007-06-25 21:41:12.629001428 +0200 ++++ src/gdb/rs6000-tdep.c 2007-06-25 21:41:21.433062953 +0200 +@@ -3322,6 +3322,9 @@ rs6000_frame_this_id (struct frame_info + { + struct rs6000_frame_cache *info = rs6000_frame_cache (next_frame, + this_cache); ++ if (info->base == 0) ++ return; ++ + (*this_id) = frame_id_build (info->base, + frame_func_unwind (next_frame, NORMAL_FRAME)); + } +@@ -3405,6 +3408,11 @@ rs6000_gdbarch_init (struct gdbarch_info + + sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour; + ++ /* Linux always uses the SysV ABI; handle it even if we haven't got ++ a BFD to look at. */ ++ if (info.osabi == GDB_OSABI_LINUX) ++ sysv_abi = 1; ++ + /* Check word size. If INFO is from a binary file, infer it from + that, else choose a likely default. */ + if (from_xcoff_exec) --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-ppc-fptrfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-ppc-fptrfix @@ -0,0 +1,355 @@ +diff -urNp src-orig/gdb/gdbserver/remote-utils.c src/gdb/gdbserver/remote-utils.c +--- src-orig/gdb/gdbserver/remote-utils.c 2007-06-12 16:38:32.000000000 +0200 ++++ src/gdb/gdbserver/remote-utils.c 2007-06-25 21:38:03.096556783 +0200 +@@ -1109,15 +1109,34 @@ look_up_one_symbol (const char *name, CO + if (len < 0) + return -1; + ++ /* We ought to handle pretty much any packet at this point while we ++ wait for the qSymbol "response". That requires re-entering the ++ main loop. For now, this is an adequate approximation; allow ++ GDB to read from memory while it figures out the address of the ++ packet. */ ++ while (own_buf[0] == 'm') ++ { ++ CORE_ADDR mem_addr; ++ unsigned char *mem_buf; ++ unsigned int mem_len; ++ ++ decode_m_packet (&own_buf[1], &mem_addr, &mem_len); ++ mem_buf = malloc (mem_len); ++ if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0) ++ convert_int_to_ascii (mem_buf, own_buf, mem_len); ++ else ++ write_enn (own_buf); ++ free (mem_buf); ++ if (putpkt (own_buf) < 0) ++ return -1; ++ len = getpkt (own_buf); ++ if (len < 0) ++ return -1; ++ } ++ + if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0) + { +- /* Malformed response. */ +- if (remote_debug) +- { +- fprintf (stderr, "Malformed response to qSymbol, ignoring.\n"); +- fflush (stderr); +- } +- ++ warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf); + return -1; + } + +diff -urNp src-orig/gdb/infcall.c src/gdb/infcall.c +--- src-orig/gdb/infcall.c 2007-06-18 20:23:08.000000000 +0200 ++++ src/gdb/infcall.c 2007-06-25 21:38:03.140550452 +0200 +@@ -222,8 +222,24 @@ find_function_addr (struct value *functi + if (TYPE_LENGTH (ftype) == 1) + funaddr = value_as_address (value_addr (function)); + else +- /* Handle integer used as address of a function. */ +- funaddr = (CORE_ADDR) value_as_long (function); ++ { ++ /* Handle function descriptors lacking debug info. */ ++ int found_descriptor = 0; ++ if (VALUE_LVAL (function) == lval_memory) ++ { ++ CORE_ADDR nfunaddr; ++ funaddr = value_as_address (value_addr (function)); ++ nfunaddr = funaddr; ++ funaddr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, ++ funaddr, ++ ¤t_target); ++ if (funaddr != nfunaddr) ++ found_descriptor = 1; ++ } ++ if (!found_descriptor) ++ /* Handle integer used as address of a function. */ ++ funaddr = (CORE_ADDR) value_as_long (function); ++ } + + value_type = builtin_type_int; + } +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-06-18 19:45:26.000000000 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-06-25 21:38:03.185543977 +0200 +@@ -591,39 +591,73 @@ ppc64_skip_trampoline_code (struct frame + } + + +-/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG) on PPC64 ++/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC + GNU/Linux. + + Usually a function pointer's representation is simply the address +- of the function. On GNU/Linux on the 64-bit PowerPC however, a +- function pointer is represented by a pointer to a TOC entry. This +- TOC entry contains three words, the first word is the address of +- the function, the second word is the TOC pointer (r2), and the +- third word is the static chain value. Throughout GDB it is +- currently assumed that a function pointer contains the address of +- the function, which is not easy to fix. In addition, the ++ of the function. On GNU/Linux on the PowerPC however, a function ++ pointer may be a pointer to a function descriptor. ++ ++ For PPC64, a function descriptor is a TOC entry, in a data section, ++ which contains three words: the first word is the address of the ++ function, the second word is the TOC pointer (r2), and the third word ++ is the static chain value. ++ ++ For PPC32, there are two kinds of function pointers: non-secure and ++ secure. Non-secure function pointers point directly to the ++ function in a code section and thus need no translation. Secure ++ ones (from GCC's -msecure-plt option) are in a data section and ++ contain one word: the address of the function. ++ ++ Throughout GDB it is currently assumed that a function pointer contains ++ the address of the function, which is not easy to fix. In addition, the + conversion of a function address to a function pointer would + require allocation of a TOC entry in the inferior's memory space, + with all its drawbacks. To be able to call C++ virtual methods in + the inferior (which are called via function pointers), + find_function_addr uses this function to get the function address +- from a function pointer. */ ++ from a function pointer. + +-/* If ADDR points at what is clearly a function descriptor, transform +- it into the address of the corresponding function. Be +- conservative, otherwize GDB will do the transformation on any +- random addresses such as occures when there is no symbol table. */ ++ If ADDR points at what is clearly a function descriptor, transform ++ it into the address of the corresponding function, if needed. Be ++ conservative, otherwise GDB will do the transformation on any ++ random addresses such as occur when there is no symbol table. */ + + static CORE_ADDR +-ppc64_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch, +- CORE_ADDR addr, +- struct target_ops *targ) ++ppc_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch, ++ CORE_ADDR addr, ++ struct target_ops *targ) + { ++ struct gdbarch_tdep *tdep; + struct section_table *s = target_section_by_addr (targ, addr); ++ char *sect_name = NULL; ++ ++ if (!s) ++ return addr; ++ ++ tdep = gdbarch_tdep (gdbarch); ++ ++ switch (tdep->wordsize) ++ { ++ case 4: ++ sect_name = ".plt"; ++ break; ++ case 8: ++ sect_name = ".opd"; ++ break; ++ default: ++ internal_error (__FILE__, __LINE__, ++ _("failed internal consistency check")); ++ } + + /* Check if ADDR points to a function descriptor. */ +- if (s && strcmp (s->the_bfd_section->name, ".opd") == 0) +- return get_target_memory_unsigned (targ, addr, 8); ++ ++ /* NOTE: this depends on the coincidence that the address of a functions ++ entry point is contained in the first word of its function descriptor ++ for both PPC-64 and for PPC-32 with secure PLTs. */ ++ if ((strcmp (s->the_bfd_section->name, sect_name) == 0) ++ && s->the_bfd_section->flags & SEC_DATA) ++ return get_target_memory_unsigned (targ, addr, tdep->wordsize); + + return addr; + } +@@ -907,6 +941,11 @@ ppc_linux_init_abi (struct gdbarch_info + /* NOTE: cagney/2005-01-25: True for both 32- and 64-bit. */ + set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); + ++ /* Handle PPC GNU/Linux 64-bit function pointers (which are really ++ function descriptors) and 32-bit secure PLT entries. */ ++ set_gdbarch_convert_from_func_ptr_addr ++ (gdbarch, ppc_linux_convert_from_func_ptr_addr); ++ + if (tdep->wordsize == 4) + { + /* Until November 2001, gcc did not comply with the 32 bit SysV +@@ -934,13 +973,8 @@ ppc_linux_init_abi (struct gdbarch_info + + if (tdep->wordsize == 8) + { +- /* Handle PPC64 GNU/Linux function pointers (which are really +- function descriptors). */ +- set_gdbarch_convert_from_func_ptr_addr +- (gdbarch, ppc64_linux_convert_from_func_ptr_addr); +- set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); +- + /* Shared library handling. */ ++ set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); + +diff -urNp src-orig/gdb/remote.c src/gdb/remote.c +--- src-orig/gdb/remote.c 2007-06-22 14:36:00.000000000 +0200 ++++ src/gdb/remote.c 2007-06-25 21:38:03.200541819 +0200 +@@ -2258,9 +2258,19 @@ remote_check_symbols (struct objfile *ob + if (sym == NULL) + xsnprintf (msg, get_remote_packet_size (), "qSymbol::%s", &reply[8]); + else +- xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s", +- paddr_nz (SYMBOL_VALUE_ADDRESS (sym)), +- &reply[8]); ++ { ++ CORE_ADDR sym_addr = SYMBOL_VALUE_ADDRESS (sym); ++ ++ /* If this is a function address, return the start of code ++ instead of any data function descriptor. */ ++ sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, ++ sym_addr, ++ ¤t_target); ++ ++ xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s", ++ paddr_nz (sym_addr), &reply[8]); ++ } ++ + putpkt (msg); + getpkt (&rs->buf, &rs->buf_size, 0); + reply = rs->buf; +diff -urNp src-orig/gdb/solib-svr4.c src/gdb/solib-svr4.c +--- src-orig/gdb/solib-svr4.c 2007-06-13 19:30:01.000000000 +0200 ++++ src/gdb/solib-svr4.c 2007-06-25 21:38:03.242535776 +0200 +@@ -84,16 +84,6 @@ static char *solib_break_names[] = + "rtld_db_dlactivity", + "_rtld_debug_state", + +- /* On the 64-bit PowerPC, the linker symbol with the same name as +- the C function points to a function descriptor, not to the entry +- point. The linker symbol whose name is the C function name +- prefixed with a '.' points to the function's entry point. So +- when we look through this table, we ignore symbols that point +- into the data section (thus skipping the descriptor's symbol), +- and eventually try this one, giving us the real entry point +- address. */ +- "._dl_debug_state", +- + NULL + }; + +@@ -263,7 +253,7 @@ static char *debug_loader_name; + + static int match_main (char *); + +-static CORE_ADDR bfd_lookup_symbol (bfd *, char *, flagword); ++static CORE_ADDR bfd_lookup_symbol (bfd *, char *); + + /* + +@@ -273,24 +263,25 @@ static CORE_ADDR bfd_lookup_symbol (bfd + + SYNOPSIS + +- CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) ++ CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) + + DESCRIPTION + + An expensive way to lookup the value of a single symbol for + bfd's that are only temporary anyway. This is used by the + shared library support to find the address of the debugger +- interface structures in the shared library. ++ notification routine in the shared library. + +- If SECT_FLAGS is non-zero, only match symbols in sections whose +- flags include all those in SECT_FLAGS. ++ The returned symbol may be in a code or data section; functions ++ will normally be in a code section, but may be in a data section ++ if this architecture uses function descriptors. + + Note that 0 is specifically allowed as an error return (no + such symbol). + */ + + static CORE_ADDR +-bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) ++bfd_lookup_symbol (bfd *abfd, char *symname) + { + long storage_needed; + asymbol *sym; +@@ -312,9 +303,9 @@ bfd_lookup_symbol (bfd *abfd, char *symn + { + sym = *symbol_table++; + if (strcmp (sym->name, symname) == 0 +- && (sym->section->flags & sect_flags) == sect_flags) ++ && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0) + { +- /* Bfd symbols are section relative. */ ++ /* BFD symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + break; + } +@@ -341,9 +332,9 @@ bfd_lookup_symbol (bfd *abfd, char *symn + sym = *symbol_table++; + + if (strcmp (sym->name, symname) == 0 +- && (sym->section->flags & sect_flags) == sect_flags) ++ && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0) + { +- /* Bfd symbols are section relative. */ ++ /* BFD symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + break; + } +@@ -1046,7 +1037,7 @@ enable_break (void) + + /* On a running target, we can get the dynamic linker's base + address from the shared library table. */ +- solib_add (NULL, 0, NULL, auto_solib_add); ++ solib_add (NULL, 0, ¤t_target, auto_solib_add); + so = master_so_list (); + while (so) + { +@@ -1069,7 +1060,7 @@ enable_break (void) + debug_loader_name = xstrdup (buf); + debug_loader_offset_p = 1; + debug_loader_offset = load_addr; +- solib_add (NULL, 0, NULL, auto_solib_add); ++ solib_add (NULL, 0, ¤t_target, auto_solib_add); + } + + /* Record the relocated start and end address of the dynamic linker +@@ -1094,20 +1085,19 @@ enable_break (void) + /* Now try to set a breakpoint in the dynamic linker. */ + for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) + { +- /* On ABI's that use function descriptors, there are usually +- two linker symbols associated with each C function: one +- pointing at the actual entry point of the machine code, +- and one pointing at the function's descriptor. The +- latter symbol has the same name as the C function. +- +- What we're looking for here is the machine code entry +- point, so we are only interested in symbols in code +- sections. */ +- sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep, SEC_CODE); ++ sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep); + if (sym_addr != 0) + break; + } + ++ if (sym_addr != 0) ++ /* Convert 'sym_addr' from a function pointer to an address. ++ Because we pass tmp_bfd_target instead of the current ++ target, this will always produce an unrelocated value. */ ++ sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, ++ sym_addr, ++ tmp_bfd_target); ++ + /* We're done with both the temporary bfd and target. Remember, + closing the target closes the underlying bfd. */ + target_close (tmp_bfd_target, 0); --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-gdbserver +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-gdbserver @@ -0,0 +1,359 @@ +diff -urNp src-orig/gdb/gdbserver/linux-low.c src/gdb/gdbserver/linux-low.c +--- src-orig/gdb/gdbserver/linux-low.c 2007-06-20 20:54:21.000000000 +0200 ++++ src/gdb/gdbserver/linux-low.c 2007-06-25 21:48:10.397298580 +0200 +@@ -36,6 +36,13 @@ + #include + #include + #include ++#include ++#include ++#include ++ ++#ifndef SPUFS_MAGIC ++#define SPUFS_MAGIC 0x23c9b64e ++#endif + + #ifndef PTRACE_GETSIGINFO + # define PTRACE_GETSIGINFO 0x4202 +@@ -1667,6 +1674,102 @@ linux_arch_string (void) + return the_low_target.arch_string; + } + ++ ++/* Enumerate spufs IDs for process PID. */ ++static int ++spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len) ++{ ++ int pos = 0; ++ int written = 0; ++ char path[128]; ++ DIR *dir; ++ struct dirent *entry; ++ ++ sprintf (path, "/proc/%ld/fd", pid); ++ dir = opendir (path); ++ if (!dir) ++ return -1; ++ ++ rewinddir (dir); ++ while ((entry = readdir (dir)) != NULL) ++ { ++ struct stat st; ++ struct statfs stfs; ++ int fd; ++ ++ fd = atoi (entry->d_name); ++ if (!fd) ++ continue; ++ ++ sprintf (path, "/proc/%ld/fd/%d", pid, fd); ++ if (stat (path, &st) != 0) ++ continue; ++ if (!S_ISDIR (st.st_mode)) ++ continue; ++ ++ if (statfs (path, &stfs) != 0) ++ continue; ++ if (stfs.f_type != SPUFS_MAGIC) ++ continue; ++ ++ if (pos >= offset && pos + 4 <= offset + len) ++ { ++ *(unsigned int *)(buf + pos - offset) = fd; ++ written += 4; ++ } ++ pos += 4; ++ } ++ ++ closedir (dir); ++ return written; ++} ++ ++/* Implements the to_xfer_partial interface for the TARGET_OBJECT_SPU ++ object type, using the /proc file system */ ++static int ++linux_spu_qxfer_partial (const char *annex, unsigned char *readbuf, ++ unsigned const char *writebuf, ++ CORE_ADDR offset, int len) ++{ ++ char buf[128]; ++ int fd = 0; ++ int ret = 0; ++ ++ if (!writebuf && !readbuf) ++ return -1; ++ ++ if (!*annex) ++ { ++ if (!readbuf) ++ return -1; ++ else ++ return spu_enumerate_spu_ids (inferior_pid, readbuf, offset, len); ++ } ++ ++ sprintf (buf, "/proc/%ld/fd/%s", inferior_pid, annex); ++ if (debug_threads) ++ printf ("access [%s] |offset [%lld] | len [%d]\n", buf, offset, len); ++ ++ fd = open (buf, writebuf? O_WRONLY : O_RDONLY); ++ if (fd <= 0) ++ return -1; ++ ++ if (offset != 0 ++ && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) ++ { ++ close (fd); ++ return 0; ++ } ++ ++ if (writebuf) ++ ret = write (fd, writebuf, (size_t) len); ++ else ++ ret = read (fd, readbuf, (size_t) len); ++ ++ close (fd); ++ return ret; ++} ++ + static struct target_ops linux_target_ops = { + linux_create_inferior, + linux_attach, +@@ -1698,6 +1801,7 @@ static struct target_ops linux_target_op + NULL, + #endif + linux_arch_string, ++ linux_spu_qxfer_partial, + }; + + static void +diff -urNp src-orig/gdb/gdbserver/linux-ppc64-low.c src/gdb/gdbserver/linux-ppc64-low.c +--- src-orig/gdb/gdbserver/linux-ppc64-low.c 2007-06-25 21:41:12.554012220 +0200 ++++ src/gdb/gdbserver/linux-ppc64-low.c 2007-06-25 21:48:10.402297861 +0200 +@@ -70,21 +70,75 @@ ppc_cannot_fetch_register (int regno) + return 0; + } + ++ ++#define INSTR_SC 0x44000002 ++#define NR_spu_run 0x0116 ++ ++/* If the PPU thread is currently stopped on a spu_run system call, ++ return to FD and ADDR the file handle and NPC parameter address ++ used with the system call. Return non-zero if successful. */ ++static int ++parse_spufs_run (int *fd, CORE_ADDR *addr) ++{ ++ unsigned int insn; ++ unsigned long pc, r0, r3, r4; ++ collect_register_by_name ("pc", &pc); ++ ++ /* Fetch instruction preceding current NIP. */ ++ if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4) != 0) ++ return 0; ++ /* It should be a "sc" instruction. */ ++ if (insn != INSTR_SC) ++ return 0; ++ /* System call number should be NR_spu_run. */ ++ collect_register_by_name ("r0", &r0); ++ if (r0 != NR_spu_run) ++ return 0; ++ ++ /* Register 3 contains fd, register 4 the NPC param pointer. */ ++ collect_register_by_name ("orig_r3", &r3); ++ collect_register_by_name ("r4", &r4); ++ *fd = (int) r3; ++ *addr = (CORE_ADDR) r4; ++ return 1; ++} ++ + static CORE_ADDR + ppc_get_pc (void) + { +- unsigned long pc; ++ CORE_ADDR addr; ++ int fd; + +- collect_register_by_name ("pc", &pc); +- return (CORE_ADDR) pc; ++ if (parse_spufs_run (&fd, &addr)) ++ { ++ unsigned int pc; ++ (*the_target->read_memory) (addr, (unsigned char *) &pc, 4); ++ return ((CORE_ADDR)1 << 63) | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4); ++ } ++ else ++ { ++ unsigned long pc; ++ collect_register_by_name ("pc", &pc); ++ return (CORE_ADDR) pc; ++ } + } + + static void + ppc_set_pc (CORE_ADDR pc) + { +- unsigned long newpc = pc; ++ CORE_ADDR addr; ++ int fd; + +- supply_register_by_name ("pc", &newpc); ++ if (parse_spufs_run (&fd, &addr)) ++ { ++ unsigned int newpc = pc; ++ (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4); ++ } ++ else ++ { ++ unsigned long newpc = pc; ++ supply_register_by_name ("pc", &newpc); ++ } + } + + /* Correct in either endianness. +@@ -98,14 +152,28 @@ ppc_breakpoint_at (CORE_ADDR where) + { + unsigned int insn; + +- (*the_target->read_memory) (where, (unsigned char *) &insn, 4); +- if (insn == ppc_breakpoint) +- return 1; +- /* If necessary, recognize more trap instructions here. GDB only uses the +- one. */ ++ if (where & ((CORE_ADDR)1 << 63)) ++ { ++ char mem_annex[32]; ++ sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff)); ++ (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn, ++ NULL, where & 0xffffffff, 4); ++ if (insn == 0x3fff) ++ return 1; ++ } ++ else ++ { ++ (*the_target->read_memory) (where, (unsigned char *) &insn, 4); ++ if (insn == ppc_breakpoint) ++ return 1; ++ /* If necessary, recognize more trap instructions here. GDB only uses ++ the one. */ ++ } ++ + return 0; + } + ++ + /* Provide only a fill function for the general register set. ps_lgetregs + will use this for NPTL support. */ + +diff -urNp src-orig/gdb/gdbserver/linux-ppc-low.c src/gdb/gdbserver/linux-ppc-low.c +--- src-orig/gdb/gdbserver/linux-ppc-low.c 2007-06-25 21:41:12.558011645 +0200 ++++ src/gdb/gdbserver/linux-ppc-low.c 2007-06-25 21:48:10.406297285 +0200 +@@ -73,21 +73,74 @@ ppc_cannot_fetch_register (int regno) + return 0; + } + ++ ++#define INSTR_SC 0x44000002 ++#define NR_spu_run 0x0116 ++ ++/* If the PPU thread is currently stopped on a spu_run system call, ++ return to FD and ADDR the file handle and NPC parameter address ++ used with the system call. Return non-zero if successful. */ ++static int ++parse_spufs_run (int *fd, CORE_ADDR *addr) ++{ ++ unsigned long insn, pc, r0, r3, r4; ++ collect_register_by_name ("pc", &pc); ++ ++ /* Fetch instruction preceding current NIP. */ ++ if ((*the_target->read_memory) (pc - 4, (unsigned char *) &insn, 4) != 0) ++ return 0; ++ /* It should be a "sc" instruction. */ ++ if (insn != INSTR_SC) ++ return 0; ++ /* System call number should be NR_spu_run. */ ++ collect_register_by_name ("r0", &r0); ++ if (r0 != NR_spu_run) ++ return 0; ++ ++ /* Register 3 contains fd, register 4 the NPC param pointer. */ ++ collect_register_by_name ("orig_r3", &r3); ++ collect_register_by_name ("r4", &r4); ++ *fd = (int) r3; ++ *addr = (CORE_ADDR) r4; ++ return 1; ++} ++ + static CORE_ADDR + ppc_get_pc (void) + { +- unsigned long pc; ++ CORE_ADDR addr; ++ int fd; + +- collect_register_by_name ("pc", &pc); +- return (CORE_ADDR) pc; ++ if (parse_spufs_run (&fd, &addr)) ++ { ++ unsigned int pc; ++ (*the_target->read_memory) (addr, (unsigned char *) &pc, 4); ++ return ((CORE_ADDR)1 << 63) | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4); ++ } ++ else ++ { ++ unsigned long pc; ++ collect_register_by_name ("pc", &pc); ++ return (CORE_ADDR) pc; ++ } + } + + static void + ppc_set_pc (CORE_ADDR pc) + { +- unsigned long newpc = pc; ++ CORE_ADDR addr; ++ int fd; + +- supply_register_by_name ("pc", &newpc); ++ if (parse_spufs_run (&fd, &addr)) ++ { ++ unsigned int newpc = pc; ++ (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4); ++ } ++ else ++ { ++ unsigned long newpc = pc; ++ supply_register_by_name ("pc", &newpc); ++ } + } + + /* Correct in either endianness. Note that this file is +@@ -102,11 +155,24 @@ ppc_breakpoint_at (CORE_ADDR where) + { + unsigned long insn; + +- (*the_target->read_memory) (where, (unsigned char *) &insn, 4); +- if (insn == ppc_breakpoint) +- return 1; +- /* If necessary, recognize more trap instructions here. GDB only uses the +- one. */ ++ if (where & ((CORE_ADDR)1 << 63)) ++ { ++ char mem_annex[32]; ++ sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff)); ++ (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn, ++ NULL, where & 0xffffffff, 4); ++ if (insn == 0x3fff) ++ return 1; ++ } ++ else ++ { ++ (*the_target->read_memory) (where, (unsigned char *) &insn, 4); ++ if (insn == ppc_breakpoint) ++ return 1; ++ /* If necessary, recognize more trap instructions here. GDB only uses ++ the one. */ ++ } ++ + return 0; + } + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-ppcorigr3 +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-ppcorigr3 @@ -0,0 +1,247 @@ +diff -urNp src-orig/gdb/gdbserver/linux-ppc64-low.c src/gdb/gdbserver/linux-ppc64-low.c +--- src-orig/gdb/gdbserver/linux-ppc64-low.c 2007-01-09 18:59:08.000000000 +0100 ++++ src/gdb/gdbserver/linux-ppc64-low.c 2007-06-25 21:40:41.479829509 +0200 +@@ -25,7 +25,12 @@ + + #include + +-#define ppc_num_regs 71 ++/* This sometimes isn't defined. */ ++#ifndef PT_ORIG_R3 ++#define PT_ORIG_R3 34 ++#endif ++ ++#define ppc_num_regs 72 + + /* We use a constant for FPSCR instead of PT_FPSCR, because + many shipped PPC64 kernels had the wrong value in ptrace.h. */ +@@ -47,11 +52,15 @@ static int ppc_regmap[] = + PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216, + PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248, + PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8, +- PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256 }; ++ PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256, PT_ORIG_R3 * 8, }; + + static int + ppc_cannot_store_register (int regno) + { ++ /* We cannot store orig_r3. */ ++ if (regno == find_regno ("orig_r3")) ++ return 1; ++ + return 0; + } + +@@ -109,6 +118,8 @@ static void ppc_fill_gregset (void *buf) + + for (i = 64; i < 70; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); ++ ++ collect_register (71, (char *) buf + ppc_regmap[71]); + } + + struct regset_info target_regsets[] = { +diff -urNp src-orig/gdb/gdbserver/linux-ppc-low.c src/gdb/gdbserver/linux-ppc-low.c +--- src-orig/gdb/gdbserver/linux-ppc-low.c 2007-01-09 18:59:08.000000000 +0100 ++++ src/gdb/gdbserver/linux-ppc-low.c 2007-06-25 21:40:41.483828934 +0200 +@@ -25,7 +25,12 @@ + + #include + +-#define ppc_num_regs 71 ++/* This sometimes isn't defined. */ ++#ifndef PT_ORIG_R3 ++#define PT_ORIG_R3 34 ++#endif ++ ++#define ppc_num_regs 72 + + /* Currently, don't check/send MQ. */ + static int ppc_regmap[] = +@@ -46,7 +51,7 @@ static int ppc_regmap[] = + PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, + PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, + PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, +- PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, }; ++ PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, PT_ORIG_R3 * 4, }; + + static int + ppc_cannot_store_register (int regno) +@@ -55,6 +60,10 @@ ppc_cannot_store_register (int regno) + if (regno == find_regno ("fpscr")) + return 2; + ++ /* We cannot store orig_r3. */ ++ if (regno == find_regno ("orig_r3")) ++ return 1; ++ + return 0; + } + +@@ -113,6 +122,8 @@ static void ppc_fill_gregset (void *buf) + + for (i = 64; i < 70; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); ++ ++ collect_register (71, (char *) buf + ppc_regmap[71]); + } + + struct regset_info target_regsets[] = { +diff -urNp src-orig/gdb/ppc-linux-nat.c src/gdb/ppc-linux-nat.c +--- src-orig/gdb/ppc-linux-nat.c 2007-06-25 21:40:32.552784683 +0200 ++++ src/gdb/ppc-linux-nat.c 2007-06-25 21:40:41.488828214 +0200 +@@ -45,6 +45,11 @@ + #include "gregset.h" + #include "ppc-tdep.h" + ++/* This sometimes isn't defined. */ ++#ifndef PT_ORIG_R3 ++#define PT_ORIG_R3 34 ++#endif ++ + /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a + configure time check. Some older glibc's (for instance 2.2.1) + don't have a specific powerpc version of ptrace.h, and fall back on +@@ -204,6 +209,8 @@ ppc_register_u_addr (int regno) + #endif + if (regno == tdep->ppc_ps_regnum) + u_addr = PT_MSR * wordsize; ++ if (regno == tdep->ppc_orig_r3_regnum) ++ u_addr = PT_ORIG_R3 * wordsize; + if (tdep->ppc_fpscr_regnum >= 0 + && regno == tdep->ppc_fpscr_regnum) + { +@@ -476,6 +483,8 @@ fetch_ppc_registers (struct regcache *re + fetch_register (regcache, tid, tdep->ppc_xer_regnum); + if (tdep->ppc_mq_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_mq_regnum); ++ if (tdep->ppc_orig_r3_regnum != -1) ++ fetch_register (regcache, tid, tdep->ppc_orig_r3_regnum); + if (tdep->ppc_fpscr_regnum != -1) + fetch_register (regcache, tid, tdep->ppc_fpscr_regnum); + if (have_ptrace_getvrregs) +diff -urNp src-orig/gdb/ppc-linux-tdep.c src/gdb/ppc-linux-tdep.c +--- src-orig/gdb/ppc-linux-tdep.c 2007-06-25 21:40:32.559783676 +0200 ++++ src/gdb/ppc-linux-tdep.c 2007-06-25 21:40:41.533821739 +0200 +@@ -630,6 +630,7 @@ static const struct ppc_reg_offsets ppc3 + /* .ctr_offset = */ 140, + /* .xer_offset = */ 148, + /* .mq_offset = */ 156, ++ /* .orig_r3_offset = */ 136, + + /* Floating-point registers. */ + /* .f0_offset = */ 0, +@@ -653,6 +654,7 @@ static const struct ppc_reg_offsets ppc6 + /* .ctr_offset = */ 280, + /* .xer_offset = */ 296 + 4, + /* .mq_offset = */ 312 + 4, ++ /* .orig_r3_offset = */ 272, + + /* Floating-point registers. */ + /* .f0_offset = */ 0, +@@ -676,6 +678,7 @@ static const struct ppc_reg_offsets ppc6 + /* .ctr_offset = */ 280 + 4, + /* .xer_offset = */ 296 + 4, + /* .mq_offset = */ 312 + 4, ++ /* .orig_r3_offset = */ 272 + 4, + + /* Floating-point registers. */ + /* .f0_offset = */ 0, +diff -urNp src-orig/gdb/ppc-tdep.h src/gdb/ppc-tdep.h +--- src-orig/gdb/ppc-tdep.h 2007-06-25 21:40:32.573781662 +0200 ++++ src/gdb/ppc-tdep.h 2007-06-25 21:40:41.538821020 +0200 +@@ -89,6 +89,7 @@ struct ppc_reg_offsets + int ctr_offset; + int xer_offset; + int mq_offset; ++ int orig_r3_offset; + + /* Floating-point registers. */ + int f0_offset; +@@ -147,6 +148,7 @@ struct gdbarch_tdep + int ppc_lr_regnum; /* Link register */ + int ppc_ctr_regnum; /* Count register */ + int ppc_xer_regnum; /* Integer exception register */ ++ int ppc_orig_r3_regnum; /* Linux orig_r3 register */ + + /* Not all PPC and RS6000 variants will have the registers + represented below. A -1 is used to indicate that the register +diff -urNp src-orig/gdb/regformats/reg-ppc64.dat src/gdb/regformats/reg-ppc64.dat +--- src-orig/gdb/regformats/reg-ppc64.dat 2005-05-29 00:09:04.000000000 +0200 ++++ src/gdb/regformats/reg-ppc64.dat 2007-06-25 21:40:41.542820444 +0200 +@@ -74,3 +74,4 @@ expedite:r1,pc + 64:ctr + 32:xer + 32:fpscr ++64:orig_r3 +diff -urNp src-orig/gdb/regformats/reg-ppc.dat src/gdb/regformats/reg-ppc.dat +--- src-orig/gdb/regformats/reg-ppc.dat 2002-04-11 22:30:08.000000000 +0200 ++++ src/gdb/regformats/reg-ppc.dat 2007-06-25 21:40:41.545820013 +0200 +@@ -74,3 +74,4 @@ expedite:r1,pc + 32:ctr + 32:xer + 32:fpscr ++32:orig_r3 +diff -urNp src-orig/gdb/rs6000-tdep.c src/gdb/rs6000-tdep.c +--- src-orig/gdb/rs6000-tdep.c 2007-06-25 21:40:32.583780223 +0200 ++++ src/gdb/rs6000-tdep.c 2007-06-25 21:40:41.556818430 +0200 +@@ -362,6 +362,9 @@ ppc_supply_gregset (const struct regset + gregs, offsets->xer_offset); + if (regnum == -1 || regnum == tdep->ppc_mq_regnum) + ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset); ++ if (regnum == -1 || regnum == tdep->ppc_orig_r3_regnum) ++ ppc_supply_reg (regcache, tdep->ppc_orig_r3_regnum, ++ gregs, offsets->orig_r3_offset); + } + + /* Supply register REGNUM in the floating-point register set REGSET +@@ -440,6 +443,9 @@ ppc_collect_gregset (const struct regset + if (regnum == -1 || regnum == tdep->ppc_mq_regnum) + ppc_collect_reg (regcache, tdep->ppc_mq_regnum, + gregs, offsets->mq_offset); ++ if (regnum == -1 || regnum == tdep->ppc_orig_r3_regnum) ++ ppc_collect_reg (regcache, tdep->ppc_orig_r3_regnum, ++ gregs, offsets->orig_r3_offset); + } + + /* Collect register REGNUM in the floating-point register set +@@ -2760,6 +2766,7 @@ static const struct reg registers_powerp + { + COMMON_UISA_REGS, + PPC_UISA_SPRS, ++ R(orig_r3), + PPC_ALTIVEC_REGS + }; + +@@ -3506,6 +3513,7 @@ rs6000_gdbarch_init (struct gdbarch_info + tdep->ppc_mq_regnum = -1; + tdep->ppc_fp0_regnum = 32; + tdep->ppc_fpscr_regnum = (arch == bfd_arch_rs6000) ? 71 : 70; ++ tdep->ppc_orig_r3_regnum = -1; + tdep->ppc_sr0_regnum = 71; + tdep->ppc_vr0_regnum = -1; + tdep->ppc_vrsave_regnum = -1; +@@ -3542,8 +3550,9 @@ rs6000_gdbarch_init (struct gdbarch_info + { + case bfd_mach_ppc: + tdep->ppc_sr0_regnum = -1; +- tdep->ppc_vr0_regnum = 71; +- tdep->ppc_vrsave_regnum = 104; ++ tdep->ppc_orig_r3_regnum = 71; ++ tdep->ppc_vr0_regnum = 72; ++ tdep->ppc_vrsave_regnum = 105; + break; + case bfd_mach_ppc_7400: + tdep->ppc_vr0_regnum = 119; +@@ -3688,8 +3697,9 @@ rs6000_gdbarch_init (struct gdbarch_info + registers is implemented. */ + if ((v->arch == bfd_arch_powerpc) && ((v->mach)== bfd_mach_ppc64)) + { +- tdep->ppc_vr0_regnum = 71; +- tdep->ppc_vrsave_regnum = 104; ++ tdep->ppc_orig_r3_regnum = 71; ++ tdep->ppc_vr0_regnum = 72; ++ tdep->ppc_vrsave_regnum = 105; + } + /* Fall Thru */ + case GDB_OSABI_NETBSD_AOUT: --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb @@ -0,0 +1,1521 @@ +diff -urNp src-orig/gdb/config/powerpc/linux-cell.mt src/gdb/config/powerpc/linux-cell.mt +--- src-orig/gdb/config/powerpc/linux-cell.mt 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/config/powerpc/linux-cell.mt 2007-06-27 23:54:32.395046497 +0200 +@@ -0,0 +1,5 @@ ++# Target: Linux on Cell BE ++TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o solib.o \ ++ solib-svr4.o solib-legacy.o corelow.o symfile-mem.o \ ++ spu-tdep.o spu-thread.o solib-spu.o ++DEPRECATED_TM_FILE= tm-ppc-eabi.h +diff -urNp src-orig/gdb/configure.tgt src/gdb/configure.tgt +--- src-orig/gdb/configure.tgt 2007-06-28 01:24:58.943675643 +0200 ++++ src/gdb/configure.tgt 2007-06-27 23:54:32.400045776 +0200 +@@ -178,6 +178,16 @@ powerpc-*-linux*) gdb_target=linux + ;; + powerpc64-*-linux*) gdb_target=linux + build_gdbserver=yes ++ # If we were built with --enable-targets=spu, ++ # enable combined Cell BE debugging. ++ if test -n "$enable_targets" ; then ++ for targ in `echo $enable_targets | sed 's/,/ /g'` ++ do ++ case "$targ" in ++ all | spu*) gdb_target=linux-cell ;; ++ esac ++ done ++ fi + ;; + powerpc*-*-*) if test -f ../sim/ppc/Makefile; then + gdb_target=ppc-sim +diff -urNp src-orig/gdb/linux-nat.c src/gdb/linux-nat.c +--- src-orig/gdb/linux-nat.c 2007-06-28 01:24:58.955673914 +0200 ++++ src/gdb/linux-nat.c 2007-06-28 01:25:51.508076338 +0200 +@@ -48,6 +48,12 @@ + #include "gdbthread.h" /* for struct thread_info etc. */ + #include "gdb_stat.h" /* for struct stat */ + #include /* for O_RDONLY */ ++#include /* for struct statfs */ ++#include /* for DIR etc. */ ++ ++#ifndef SPUFS_MAGIC ++#define SPUFS_MAGIC 0x23c9b64e ++#endif + + #ifndef O_LARGEFILE + #define O_LARGEFILE 0 +@@ -3062,6 +3068,99 @@ linux_proc_xfer_partial (struct target_o + return ret; + } + ++ ++/* Enumerate spufs IDs for process PID. */ ++static LONGEST ++spu_enumerate_spu_ids (int pid, gdb_byte *buf, ULONGEST offset, LONGEST len) ++{ ++ LONGEST pos = 0; ++ LONGEST written = 0; ++ char path[128]; ++ DIR *dir; ++ struct dirent *entry; ++ ++ xsnprintf (path, sizeof path, "/proc/%d/fd", pid); ++ dir = opendir (path); ++ if (!dir) ++ return -1; ++ ++ rewinddir (dir); ++ while ((entry = readdir (dir)) != NULL) ++ { ++ struct stat st; ++ struct statfs stfs; ++ int fd; ++ ++ fd = atoi (entry->d_name); ++ if (!fd) ++ continue; ++ ++ xsnprintf (path, sizeof path, "/proc/%d/fd/%d", pid, fd); ++ if (stat (path, &st) != 0) ++ continue; ++ if (!S_ISDIR (st.st_mode)) ++ continue; ++ ++ if (statfs (path, &stfs) != 0) ++ continue; ++ if (stfs.f_type != SPUFS_MAGIC) ++ continue; ++ ++ if (pos >= offset && pos + 4 <= offset + len) ++ { ++ store_unsigned_integer (buf + pos - offset, 4, fd); ++ written += 4; ++ } ++ pos += 4; ++ } ++ ++ closedir (dir); ++ return written; ++} ++ ++/* Implement the to_xfer_partial interface for the TARGET_OBJECT_SPU ++ object type, using the /proc file system. */ ++static LONGEST ++linux_proc_xfer_spu (struct target_ops *ops, enum target_object object, ++ const char *annex, gdb_byte *readbuf, ++ const gdb_byte *writebuf, ++ ULONGEST offset, LONGEST len) ++{ ++ char buf[128]; ++ int fd = 0; ++ int ret = -1; ++ int pid = PIDGET (inferior_ptid); ++ ++ if (!annex) ++ { ++ if (!readbuf) ++ return -1; ++ else ++ return spu_enumerate_spu_ids (pid, readbuf, offset, len); ++ } ++ ++ xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex); ++ fd = open (buf, writebuf? O_WRONLY : O_RDONLY); ++ if (fd <= 0) ++ return -1; ++ ++ if (offset != 0 ++ && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) ++ { ++ close (fd); ++ return 0; ++ } ++ ++ if (writebuf) ++ ret = write (fd, writebuf, (size_t) len); ++ else if (readbuf) ++ ret = read (fd, readbuf, (size_t) len); ++ ++ close (fd); ++ return ret; ++} ++ ++ + /* Parse LINE as a signal set and add its set bits to SIGS. */ + + static void +@@ -3154,6 +3253,10 @@ linux_xfer_partial (struct target_ops *o + return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf, + offset, len); + ++ if (object == TARGET_OBJECT_SPU) ++ return linux_proc_xfer_spu (ops, object, annex, readbuf, writebuf, ++ offset, len); ++ + xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf, + offset, len); + if (xfer != 0) +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-28 01:24:58.969671897 +0200 ++++ src/gdb/Makefile.in 2007-06-28 01:25:46.992063076 +0200 +@@ -1494,7 +1494,7 @@ ALLDEPFILES = \ + sparc64-tdep.c sparc64fbsd-nat.c sparc64fbsd-tdep.c \ + sparc64nbsd-nat.c sparc64nbsd-tdep.c sparc64obsd-tdep.c \ + sparcnbsd-nat.c sparcnbsd-tdep.c sparcobsd-tdep.c \ +- spu-linux-nat.c spu-tdep.c \ ++ spu-linux-nat.c spu-tdep.c spu-thread.c \ + v850-tdep.c \ + vax-nat.c vax-tdep.c vaxbsd-nat.c vaxnbsd-tdep.c \ + win32-nat.c \ +@@ -2585,6 +2585,10 @@ solib-osf.o: solib-osf.c $(defs_h) $(gdb + solib-pa64.o: solib-pa64.c $(defs_h) $(symtab_h) $(bfd_h) $(symfile_h) \ + $(objfiles_h) $(gdbcore_h) $(target_h) $(inferior_h) $(hppa_tdep_h) \ + $(solist_h) $(solib_pa64_h) ++solib-spu.o: solib-spu.c $(defs_h) $(gdbcore_h) $(gdb_string_h) \ ++ $(gdb_assert_h) $(gdb_stat_h) $(arch_utils_h) $(bfd_h) $(symtab_h) \ ++ $(solib_h) $(solist_h) $(inferior_h) $(objfiles_h) $(observer_h) \ ++ $(spu_tdep_h) + solib-som.o: solib-som.c $(defs_h) $(som_h) $(symtab_h) $(bfd_h) \ + $(symfile_h) $(objfiles_h) $(gdbcore_h) $(target_h) $(inferior_h) \ + $(hppa_tdep_h) $(solist_h) +@@ -2683,7 +2687,11 @@ spu-tdep.o: spu-tdep.c $(defs_h) $(arch_ + $(frame_unwind_h) $(frame_base_h) $(trad_frame_h) $(symtab_h) \ + $(symfile_h) $(value_h) $(inferior_h) $(dis_asm_h) $(objfiles_h) \ + $(language_h) $(regcache_h) $(reggroups_h) $(floatformat_h) \ +- $(observer_h) $(spu_tdep_h) ++ $(block_h) $(observer_h) $(spu_tdep_h) ++spu-thread.o: spu-thread.c $(defs_h) $(gdbcore_h) $(gdbcmd_h) $(gdb_string_h) \ ++ $(gdb_assert_h) $(arch_utils_h) $(observer_h) $(inferior_h) \ ++ $(regcache_h) $(symfile_h) $(objfiles_h) $(block_h) $(exec_h) \ ++ $(ppc_tdep_h) $(spu_tdep_h) + stabsread.o: stabsread.c $(defs_h) $(gdb_string_h) $(bfd_h) $(gdb_obstack_h) \ + $(symtab_h) $(gdbtypes_h) $(expression_h) $(symfile_h) $(objfiles_h) \ + $(aout_stab_gnu_h) $(libaout_h) $(aout_aout64_h) $(gdb_stabs_h) \ +diff -urNp src-orig/gdb/solib-spu.c src/gdb/solib-spu.c +--- src-orig/gdb/solib-spu.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/solib-spu.c 2007-06-28 01:25:53.588042937 +0200 +@@ -0,0 +1,359 @@ ++/* Cell SPU GNU/Linux support -- shared library handling. ++ Copyright 2006 IBM Corp. ++ ++ Contributed by Ulrich Weigand . ++ ++ This file is part of GDB. ++ ++ 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. */ ++ ++#include "defs.h" ++#include "gdbcore.h" ++#include "gdb_string.h" ++#include "gdb_assert.h" ++#include "gdb_stat.h" ++#include "arch-utils.h" ++#include "bfd.h" ++#include "symtab.h" ++#include "solib.h" ++#include "solist.h" ++#include "inferior.h" ++#include "objfiles.h" ++#include "observer.h" ++ ++#include "spu-tdep.h" ++ ++/* Highest SPE id (file handle) the inferior may have. */ ++#define MAX_SPE_FD 1024 ++ ++/* This file handles SPE executable images as "shared libraries", ++ *in addition* to the regular shared libraries handled by the ++ SVR4 layer. This variable holds the callback functions for ++ that underlying layer. */ ++static struct target_so_ops super_so_ops; ++ ++ ++/* Build a list of `struct so_list' objects describing the shared ++ objects currently loaded in the inferior. */ ++static struct so_list * ++spu_current_sos (void) ++{ ++ struct so_list *head; ++ struct so_list **link_ptr; ++ ++ char buf[MAX_SPE_FD * 4]; ++ int i, size; ++ int prev_spu; ++ ++ /* First, retrieve the SVR4 shared library list. Switch to the ++ PPE architecture while doing so. This should not be strictly ++ necessary, but it is right now. */ ++ prev_spu = spu_switch_arch (0); ++ head = super_so_ops.current_sos (); ++ spu_switch_arch (prev_spu); ++ ++ /* Do not add stand-alone SPE executable context. */ ++ if (symfile_objfile && symfile_objfile->obfd ++ && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu) ++ return head; ++ ++ /* Append our libraries to the end of the list. */ ++ for (link_ptr = &head; *link_ptr; link_ptr = &(*link_ptr)->next) ++ ; ++ ++ /* Determine list of SPU ids. */ ++ size = target_read (¤t_target, TARGET_OBJECT_SPU, NULL, ++ buf, 0, sizeof buf); ++ ++ /* Create an so_list entry for each SPU id. */ ++ for (i = 0; i < size; i += 4) ++ { ++ int fd = extract_unsigned_integer (buf + i, 4); ++ struct so_list *new; ++ ++ unsigned long long addr; ++ char annex[32], id[100]; ++ int len; ++ ++ /* Read object ID. There's a race window where the inferior may have ++ already created the SPE context, but not installed the object-id ++ yet. Skip such entries; we'll be back for them later. */ ++ xsnprintf (annex, sizeof annex, "%d/object-id", fd); ++ len = target_read (¤t_target, TARGET_OBJECT_SPU, annex, ++ id, 0, sizeof id); ++ if (len <= 0 || len >= sizeof id) ++ continue; ++ id[len] = 0; ++ if (sscanf (id, "0x%llx", &addr) != 1 || !addr) ++ continue; ++ ++ /* Allocate so_list structure. */ ++ new = XZALLOC (struct so_list); ++ ++ /* Encode FD and object ID in path name. Choose the name so as not ++ to conflict with any (normal) SVR4 library path name. */ ++ xsnprintf (new->so_name, sizeof new->so_name, "@0x%llx <%d>", addr, fd); ++ strcpy (new->so_original_name, new->so_name); ++ ++ *link_ptr = new; ++ link_ptr = &new->next; ++ } ++ ++ return head; ++} ++ ++/* Free so_list information. */ ++static void ++spu_free_so (struct so_list *so) ++{ ++ if (so->so_original_name[0] != '@') ++ super_so_ops.free_so (so); ++} ++ ++/* Relocate section addresses. */ ++static void ++spu_relocate_section_addresses (struct so_list *so, ++ struct section_table *sec) ++{ ++ if (so->so_original_name[0] != '@') ++ super_so_ops.relocate_section_addresses (so, sec); ++ else ++ { ++ unsigned long long addr; ++ int fd; ++ ++ /* Decode object ID. */ ++ if (sscanf (so->so_original_name, "@0x%llx <%d>", &addr, &fd) != 2) ++ internal_error (__FILE__, __LINE__, "bad object ID"); ++ ++ sec->addr = SPUADDR (fd, sec->addr); ++ sec->endaddr = SPUADDR (fd, sec->endaddr); ++ } ++} ++ ++ ++/* Inferior memory should contain an SPE executable image at location ADDR. ++ Allocate a BFD representing that executable. Return NULL on error. */ ++ ++static void * ++spu_bfd_iovec_open (struct bfd *nbfd, void *open_closure) ++{ ++ return open_closure; ++} ++ ++static int ++spu_bfd_iovec_close (struct bfd *nbfd, void *stream) ++{ ++ xfree (stream); ++ return 1; ++} ++ ++static file_ptr ++spu_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf, ++ file_ptr nbytes, file_ptr offset) ++{ ++ CORE_ADDR addr = *(CORE_ADDR *)stream; ++ ++ if (target_read_memory (addr + offset, buf, nbytes) != 0) ++ { ++ bfd_set_error (bfd_error_invalid_operation); ++ return -1; ++ } ++ ++ return nbytes; ++} ++ ++static int ++spu_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb) ++{ ++ /* We don't have an easy way of finding the size of embedded spu ++ images. We could parse the in-memory ELF header and section ++ table to find the extent of the last section but that seems ++ pointless when the size is needed only for checks of other ++ parsed values in dbxread.c. */ ++ sb->st_size = INT_MAX; ++ return 0; ++} ++ ++static struct bfd * ++spu_bfd_open (char *name, CORE_ADDR addr) ++{ ++ struct bfd *nbfd; ++ ++ CORE_ADDR *open_closure = xmalloc (sizeof (CORE_ADDR)); ++ *open_closure = addr; ++ ++ nbfd = bfd_openr_iovec (xstrdup (name), "elf32-spu", ++ spu_bfd_iovec_open, open_closure, ++ spu_bfd_iovec_pread, spu_bfd_iovec_close, ++ spu_bfd_iovec_stat); ++ if (!nbfd) ++ return NULL; ++ ++ if (!bfd_check_format (nbfd, bfd_object)) ++ { ++ bfd_close (nbfd); ++ return NULL; ++ } ++ ++ return nbfd; ++} ++ ++/* Open shared library BFD. */ ++static struct bfd * ++spu_open_bfd (char *pathname, int already_resolved) ++{ ++ char *original_name = strrchr (pathname, '@'); ++ char name[64]; ++ struct bfd *abfd; ++ asection *spu_name; ++ unsigned long long addr; ++ int fd; ++ ++ if (!original_name) ++ { ++ if (super_so_ops.open_bfd) ++ return super_so_ops.open_bfd (pathname, already_resolved); ++ else ++ return solib_open_bfd (pathname, already_resolved); ++ } ++ ++ /* Decode object ID. */ ++ if (sscanf (original_name, "@0x%llx <%d>", &addr, &fd) != 2) ++ internal_error (__FILE__, __LINE__, "bad object ID"); ++ ++ /* Open BFD representing SPE executable. */ ++ abfd = spu_bfd_open (original_name, (CORE_ADDR) addr); ++ if (!abfd) ++ error (_("Cannot read SPE executable at %s"), original_name); ++ ++ /* Retrieve SPU name note. */ ++ spu_name = bfd_get_section_by_name (abfd, ".note.spu_name"); ++ if (spu_name) ++ { ++ int sect_size = bfd_section_size (abfd, spu_name); ++ if (sect_size > 20) ++ { ++ char *buf = alloca (sect_size - 20 + strlen (original_name) + 1); ++ bfd_get_section_contents (abfd, spu_name, buf, 20, sect_size - 20); ++ buf[sect_size - 20] = '\0'; ++ ++ strcat (buf, original_name); ++ ++ xfree ((char *)abfd->filename); ++ abfd->filename = xstrdup (buf); ++ } ++ } ++ ++ return abfd; ++} ++ ++/* Enable shared library breakpoint. */ ++static int ++spu_enable_break (struct objfile *objfile) ++{ ++ struct minimal_symbol *spe_event_sym = NULL; ++ ++ /* The libspe library will call __spe_context_update_event whenever any ++ SPE context is allocated or destroyed. */ ++ spe_event_sym = lookup_minimal_symbol ("__spe_context_update_event", ++ NULL, objfile); ++ ++ /* Some older libspe versions don't use the above call, so we hook an ++ internal routine do_spe_run instead. This way we'll at least make ++ sure we know about all new SPE contexts. */ ++ if (!spe_event_sym) ++ spe_event_sym = lookup_minimal_symbol ("do_spe_run", NULL, objfile); ++ ++ /* Place a solib_event breakpoint on the symbol. */ ++ if (spe_event_sym) ++ { ++ CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (spe_event_sym); ++ addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch, addr, ++ ¤t_target); ++ create_solib_event_breakpoint (addr); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* Create inferior hook. */ ++static void ++spu_solib_create_inferior_hook (void) ++{ ++ super_so_ops.solib_create_inferior_hook (); ++ ++ /* If the inferior is statically linked against libspe, the SVR4 version ++ of create_inferior_hook will have removed the SPE shared library event ++ breakpoint. Make sure to re-establish it. */ ++ spu_enable_break (NULL); ++} ++ ++/* Lookup global symbol in a SPE executable. */ ++static struct symbol * ++spu_lookup_lib_symbol (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, struct symtab **symtab) ++{ ++ if (bfd_get_arch (objfile->obfd) == bfd_arch_spu) ++ return lookup_global_symbol_from_objfile (objfile, name, linkage_name, ++ domain, symtab); ++ ++ if (super_so_ops.lookup_lib_global_symbol != NULL) ++ return super_so_ops.lookup_lib_global_symbol (objfile, ++ name, linkage_name, ++ domain, symtab); ++ return NULL; ++} ++ ++/* Install SPE "shared library" handling. */ ++static void ++spu_install_handlers (void) ++{ ++ /* Only the first time through. */ ++ if (super_so_ops.current_sos) ++ return; ++ ++ /* Remember the original vector for us to call. */ ++ super_so_ops = *current_target_so_ops; ++ ++ /* Install our own overrides. */ ++ current_target_so_ops->solib_create_inferior_hook = spu_solib_create_inferior_hook; ++ current_target_so_ops->relocate_section_addresses = spu_relocate_section_addresses; ++ current_target_so_ops->free_so = spu_free_so; ++ current_target_so_ops->current_sos = spu_current_sos; ++ current_target_so_ops->open_bfd = spu_open_bfd; ++ current_target_so_ops->lookup_lib_global_symbol = spu_lookup_lib_symbol; ++} ++ ++/* Callback for new objfiles. */ ++static void ++spu_new_objfile (struct objfile *objfile) ++{ ++ if (objfile && spu_enable_break (objfile)) ++ spu_install_handlers (); ++} ++ ++ ++void ++_initialize_spu_solib (void) ++{ ++ /* Add ourselves to objfile event chain. */ ++ observer_attach_new_objfile (spu_new_objfile); ++} ++ +diff -urNp src-orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src-orig/gdb/spu-tdep.c 2007-06-28 01:24:58.987669304 +0200 ++++ src/gdb/spu-tdep.c 2007-06-28 01:25:20.373778716 +0200 +@@ -42,11 +42,20 @@ + #include "regcache.h" + #include "reggroups.h" + #include "floatformat.h" ++#include "block.h" + #include "observer.h" + + #include "spu-tdep.h" + + ++/* The list of available "set spu " and "show spu " commands. */ ++static struct cmd_list_element *setspucmdlist = NULL; ++static struct cmd_list_element *showspucmdlist = NULL; ++ ++/* Whether to stop for new SPE contexts. */ ++static int spu_stop_on_load_p = 0; ++ ++ + /* The tdep structure. */ + struct gdbarch_tdep + { +@@ -324,6 +333,47 @@ spu_register_reggroup_p (struct gdbarch + return default_register_reggroup_p (gdbarch, regnum, group); + } + ++/* Address conversion. */ ++ ++static void ++spu_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr) ++{ ++ store_unsigned_integer (buf, TYPE_LENGTH (type), SPUADDR_ADDR (addr)); ++} ++ ++static CORE_ADDR ++spu_pointer_to_address (struct type *type, const gdb_byte *buf) ++{ ++ ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); ++ ULONGEST id = 0; ++ ++ if (target_has_registers && target_has_stack && target_has_memory) ++ { ++ struct frame_info *frame = get_selected_frame (NULL); ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ } ++ ++ return addr? SPUADDR (id, addr) : 0; ++} ++ ++static CORE_ADDR ++spu_integer_to_address (struct gdbarch *gdbarch, ++ struct type *type, const gdb_byte *buf) ++{ ++ ULONGEST addr = unpack_long (type, buf); ++ ULONGEST id = 0; ++ ++ if (target_has_registers && target_has_stack && target_has_memory ++ /* FIXME: Currently needed for dwarf2_read_address to work. */ ++ && type != builtin_type_uint32) ++ { ++ struct frame_info *frame = get_selected_frame (NULL); ++ id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); ++ } ++ ++ return SPUADDR (id, addr); ++} ++ + + /* Decoding SPU instructions. */ + +@@ -812,6 +862,7 @@ spu_frame_unwind_cache (struct frame_inf + { + struct spu_unwind_cache *info; + struct spu_prologue_data data; ++ CORE_ADDR id; + gdb_byte buf[16]; + + if (*this_prologue_cache) +@@ -823,6 +874,9 @@ spu_frame_unwind_cache (struct frame_inf + info->frame_base = 0; + info->local_base = 0; + ++ /* Unwind SPU ID. */ ++ id = frame_unwind_register_unsigned (next_frame, SPU_ID_REGNUM); ++ + /* Find the start of the current function, and analyze its prologue. */ + info->func = frame_func_unwind (next_frame, NORMAL_FRAME); + if (info->func == 0) +@@ -844,6 +898,7 @@ spu_frame_unwind_cache (struct frame_inf + /* Determine CFA via unwound CFA_REG plus CFA_OFFSET. */ + frame_unwind_register (next_frame, data.cfa_reg, buf); + cfa = extract_unsigned_integer (buf, 4) + data.cfa_offset; ++ cfa = SPUADDR (id, cfa); + + /* Call-saved register slots. */ + for (i = 0; i < SPU_NUM_GPRS; i++) +@@ -864,7 +919,7 @@ spu_frame_unwind_cache (struct frame_inf + + /* Get the backchain. */ + reg = frame_unwind_register_unsigned (next_frame, SPU_SP_REGNUM); +- backchain = read_memory_unsigned_integer (reg, 4); ++ backchain = read_memory_unsigned_integer (SPUADDR (id, reg), 4); + + /* A zero backchain terminates the frame chain. Also, sanity + check against the local store size limit. */ +@@ -872,16 +927,17 @@ spu_frame_unwind_cache (struct frame_inf + { + /* Assume the link register is saved into its slot. */ + if (backchain + 16 < SPU_LS_SIZE) +- info->saved_regs[SPU_LR_REGNUM].addr = backchain + 16; ++ info->saved_regs[SPU_LR_REGNUM].addr = SPUADDR (id, backchain + 16); + + /* Frame bases. */ +- info->frame_base = backchain; +- info->local_base = reg; ++ info->frame_base = SPUADDR (id, backchain); ++ info->local_base = SPUADDR (id, reg); + } + } + + /* The previous SP is equal to the CFA. */ +- trad_frame_set_value (info->saved_regs, SPU_SP_REGNUM, info->frame_base); ++ trad_frame_set_value (info->saved_regs, SPU_SP_REGNUM, ++ SPUADDR_ADDR (info->frame_base)); + + /* Read full contents of the unwound link register in order to + be able to determine the return address. */ +@@ -968,23 +1024,27 @@ static CORE_ADDR + spu_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) + { + CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, SPU_PC_REGNUM); ++ CORE_ADDR id = frame_unwind_register_unsigned (next_frame, SPU_ID_REGNUM); + /* Mask off interrupt enable bit. */ +- return pc & -4; ++ return SPUADDR (id, pc & -4); + } + + static CORE_ADDR + spu_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) + { +- return frame_unwind_register_unsigned (next_frame, SPU_SP_REGNUM); ++ CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, SPU_SP_REGNUM); ++ CORE_ADDR id = frame_unwind_register_unsigned (next_frame, SPU_ID_REGNUM); ++ return SPUADDR (id, sp); + } + + static CORE_ADDR + spu_read_pc (struct regcache *regcache) + { +- ULONGEST pc; ++ ULONGEST pc, id; + regcache_cooked_read_unsigned (regcache, SPU_PC_REGNUM, &pc); ++ regcache_cooked_read_unsigned (regcache, SPU_ID_REGNUM, &id); + /* Mask off interrupt enable bit. */ +- return pc & -4; ++ return SPUADDR (id, pc & -4); + } + + static void +@@ -994,7 +1054,7 @@ spu_write_pc (struct regcache *regcache, + ULONGEST old_pc; + regcache_cooked_read_unsigned (regcache, SPU_PC_REGNUM, &old_pc); + regcache_cooked_write_unsigned (regcache, SPU_PC_REGNUM, +- (pc & -4) | (old_pc & 3)); ++ (SPUADDR_ADDR (pc) & -4) | (old_pc & 3)); + } + + +@@ -1088,7 +1148,7 @@ spu_push_dummy_call (struct gdbarch *gdb + + /* Set the return address. */ + memset (buf, 0, sizeof buf); +- store_unsigned_integer (buf, 4, bp_addr); ++ store_unsigned_integer (buf, 4, SPUADDR_ADDR (bp_addr)); + regcache_cooked_write (regcache, SPU_LR_REGNUM, buf); + + /* If STRUCT_RETURN is true, then the struct return address (in +@@ -1097,7 +1157,7 @@ spu_push_dummy_call (struct gdbarch *gdb + if (struct_return) + { + memset (buf, 0, sizeof buf); +- store_unsigned_integer (buf, 4, struct_addr); ++ store_unsigned_integer (buf, 4, SPUADDR_ADDR (struct_addr)); + regcache_cooked_write (regcache, regnum++, buf); + } + +@@ -1249,18 +1309,18 @@ spu_software_single_step (struct frame_i + instruction is a PPE-assisted call, in which case it is at PC + 8. + Wrap around LS limit to be on the safe side. */ + if ((insn & 0xffffff00) == 0x00002100) +- next_pc = (pc + 8) & (SPU_LS_SIZE - 1); ++ next_pc = (SPUADDR_ADDR (pc) + 8) & (SPU_LS_SIZE - 1); + else +- next_pc = (pc + 4) & (SPU_LS_SIZE - 1); ++ next_pc = (SPUADDR_ADDR (pc) + 4) & (SPU_LS_SIZE - 1); + +- insert_single_step_breakpoint (next_pc); ++ insert_single_step_breakpoint (SPUADDR (SPUADDR_SPU (pc), next_pc)); + + if (is_branch (insn, &offset, ®)) + { + CORE_ADDR target = offset; + + if (reg == SPU_PC_REGNUM) +- target += pc; ++ target += SPUADDR_ADDR (pc); + else if (reg != -1) + { + get_frame_register_bytes (frame, reg, 0, 4, buf); +@@ -1269,7 +1329,7 @@ spu_software_single_step (struct frame_i + + target = target & (SPU_LS_SIZE - 1); + if (target != next_pc) +- insert_single_step_breakpoint (target); ++ insert_single_step_breakpoint (SPUADDR (SPUADDR_SPU (pc), target)); + } + + return 1; +@@ -1391,7 +1451,7 @@ static void + spu_overlay_update_osect (struct obj_section *osect) + { + struct spu_overlay_table *ovly_table; +- CORE_ADDR val; ++ CORE_ADDR addr, val; + + ovly_table = spu_get_overlay_table (osect->objfile); + if (!ovly_table) +@@ -1401,7 +1461,8 @@ spu_overlay_update_osect (struct obj_sec + if (ovly_table->mapped_ptr == 0) + return; + +- val = read_memory_unsigned_integer (ovly_table->mapped_ptr, 4); ++ addr = SPUADDR (SPUADDR_SPU (osect->addr), ovly_table->mapped_ptr); ++ val = read_memory_unsigned_integer (addr, 4); + osect->ovly_mapped = (val == ovly_table->mapped_val); + } + +@@ -1439,6 +1500,10 @@ spu_overlay_new_objfile (struct objfile + if (!objfile || objfile_data (objfile, spu_overlay_data) != NULL) + return; + ++ /* Consider only SPU objfiles. */ ++ if (bfd_get_arch (objfile->obfd) != bfd_arch_spu) ++ return; ++ + /* Check if this objfile has overlays. */ + ovly_table = spu_get_overlay_table (objfile); + if (!ovly_table) +@@ -1455,7 +1520,73 @@ spu_overlay_new_objfile (struct objfile + bfd_section_lma (obfd, bsect) = bfd_section_vma (obfd, bsect); + else + bfd_section_lma (obfd, bsect) = bsect->filepos + SPU_LS_SIZE; ++ ++ if (ovly_table[ndx].mapped_ptr != 0) ++ { ++ /* We have to relocate section VMAs and LMAs since common overlay ++ code ignores GDB's section relocations. */ ++ CORE_ADDR id = SPUADDR_SPU (osect->addr); ++ bfd_section_vma (obfd, bsect) = ++ SPUADDR (id, bfd_section_vma (obfd, bsect)); ++ bfd_section_lma (obfd, bsect) = ++ SPUADDR (id, bfd_section_lma (obfd, bsect)); ++ } ++ } ++} ++ ++ ++/* Insert temporary breakpoint on "main" function of newly loaded ++ SPE context OBJFILE. */ ++static void ++spu_catch_start (struct objfile *objfile) ++{ ++ struct minimal_symbol *minsym; ++ struct symtab *symtab; ++ CORE_ADDR pc; ++ char buf[32]; ++ ++ /* Do this only if requested by "set spu stop-on-load on". */ ++ if (!spu_stop_on_load_p) ++ return; ++ ++ /* Consider only SPU objfiles. */ ++ if (!objfile || bfd_get_arch (objfile->obfd) != bfd_arch_spu) ++ return; ++ ++ /* The main objfile is handled differently. */ ++ if (objfile == symfile_objfile) ++ return; ++ ++ /* There can be multiple symbols named "main". Search for the ++ "main" in *this* objfile. */ ++ minsym = lookup_minimal_symbol ("main", NULL, objfile); ++ if (!minsym) ++ return; ++ ++ /* If we have debugging information, try to use it -- this ++ will allow us to properly skip the prologue. */ ++ pc = SYMBOL_VALUE_ADDRESS (minsym); ++ symtab = find_pc_sect_symtab (pc, SYMBOL_BFD_SECTION (minsym)); ++ if (symtab != NULL) ++ { ++ struct blockvector *bv = BLOCKVECTOR (symtab); ++ struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ++ struct symbol *sym; ++ struct symtab_and_line sal; ++ ++ sym = lookup_block_symbol (block, "main", NULL, VAR_DOMAIN); ++ if (sym) ++ { ++ fixup_symbol_section (sym, objfile); ++ sal = find_function_start_sal (sym, 1); ++ pc = sal.pc; ++ } + } ++ ++ /* Use a numerical address for the tbreak command to avoid having ++ the breakpoint re-set incorrectly. */ ++ xsnprintf (buf, sizeof buf, "*%s", core_addr_to_string (pc)); ++ tbreak_command (buf, 0); + } + + +@@ -1473,6 +1604,9 @@ info_spu_event_command (char *args, int + LONGEST len; + int rc, id; + ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu) ++ error (_("\"info spu\" is only supported on the SPU architecture.")); ++ + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + + xsnprintf (annex, sizeof annex, "%d/event_status", id); +@@ -1523,6 +1657,9 @@ info_spu_signal_command (char *args, int + LONGEST len; + int rc, id; + ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu) ++ error (_("\"info spu\" is only supported on the SPU architecture.")); ++ + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + + xsnprintf (annex, sizeof annex, "%d/signal1", id); +@@ -1637,6 +1774,9 @@ info_spu_mailbox_command (char *args, in + LONGEST len; + int i, id; + ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu) ++ error (_("\"info spu\" is only supported on the SPU architecture.")); ++ + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + + chain = make_cleanup_ui_out_tuple_begin_end (uiout, "SPUInfoMailbox"); +@@ -1832,6 +1972,9 @@ info_spu_dma_command (char *args, int fr + LONGEST len; + int i, id; + ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu) ++ error (_("\"info spu\" is only supported on the SPU architecture.")); ++ + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + + xsnprintf (annex, sizeof annex, "%d/dma_info", id); +@@ -1901,6 +2044,9 @@ info_spu_proxydma_command (char *args, i + LONGEST len; + int i, id; + ++ if (gdbarch_bfd_arch_info (get_frame_arch (frame))->arch != bfd_arch_spu) ++ error (_("\"info spu\" is only supported on the SPU architecture.")); ++ + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); + + xsnprintf (annex, sizeof annex, "%d/proxydma_info", id); +@@ -1955,6 +2101,29 @@ info_spu_command (char *args, int from_t + } + + ++/* Root of all "set spu "/"show spu " commands. */ ++ ++static void ++show_spu_command (char *args, int from_tty) ++{ ++ help_list (showspucmdlist, "show spu ", all_commands, gdb_stdout); ++} ++ ++static void ++set_spu_command (char *args, int from_tty) ++{ ++ help_list (setspucmdlist, "set spu ", all_commands, gdb_stdout); ++} ++ ++static void ++show_spu_stop_on_load (struct ui_file *file, int from_tty, ++ struct cmd_list_element *c, const char *value) ++{ ++ fprintf_filtered (file, _("Stopping for new SPE threads is %s.\n"), ++ value); ++} ++ ++ + /* Set up gdbarch struct. */ + + static struct gdbarch * +@@ -2008,6 +2177,11 @@ spu_gdbarch_init (struct gdbarch_info in + set_gdbarch_double_format (gdbarch, floatformats_ieee_double); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); + ++ /* Address conversion. */ ++ set_gdbarch_address_to_pointer (gdbarch, spu_address_to_pointer); ++ set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address); ++ set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address); ++ + /* Inferior function calls. */ + set_gdbarch_call_dummy_location (gdbarch, ON_STACK); + set_gdbarch_frame_align (gdbarch, spu_frame_align); +@@ -2047,6 +2221,31 @@ _initialize_spu_tdep (void) + observer_attach_new_objfile (spu_overlay_new_objfile); + spu_overlay_data = register_objfile_data (); + ++ /* Install spu stop-on-load handler. */ ++ observer_attach_new_objfile (spu_catch_start); ++ ++ /* Add root prefix command for all "set spu"/"show spu" commands. */ ++ add_prefix_cmd ("spu", no_class, set_spu_command, ++ _("Various SPU specific commands."), ++ &setspucmdlist, "set spu ", 0, &setlist); ++ add_prefix_cmd ("spu", no_class, show_spu_command, ++ _("Various SPU specific commands."), ++ &showspucmdlist, "show spu ", 0, &showlist); ++ ++ /* Toggle whether or not to add a temporary breakpoint at the "main" ++ function of new SPE contexts. */ ++ add_setshow_boolean_cmd ("stop-on-load", class_support, ++ &spu_stop_on_load_p, _("\ ++Set whether to stop for new SPE threads."), ++ _("\ ++Show whether to stop for new SPE threads."), ++ _("\ ++Use \"on\" to give control to the user when a new SPE threads enters its \"main\" function.\n\ ++Use \"off\" to disable stopping for new SPE threads."), ++ NULL, ++ show_spu_stop_on_load, ++ &setspucmdlist, &showspucmdlist); ++ + /* Add root prefix command for all "info spu" commands. */ + add_prefix_cmd ("spu", class_info, info_spu_command, + _("Various SPU specific commands."), +diff -urNp src-orig/gdb/spu-tdep.h src/gdb/spu-tdep.h +--- src-orig/gdb/spu-tdep.h 2007-06-28 01:24:58.992668583 +0200 ++++ src/gdb/spu-tdep.h 2007-06-28 01:25:09.455754498 +0200 +@@ -52,4 +52,21 @@ enum spu_regnum + /* Local store. */ + #define SPU_LS_SIZE 0x40000 + ++/* Address conversions. */ ++#define SPUADDR(spu, addr) \ ++ ((spu) && !spu_standalone_p ()? \ ++ (((ULONGEST)1 << 63) | ((ULONGEST)(spu)) << 32 | (addr)) : (addr)) ++#define SPUADDR_SPU(addr) \ ++ (((addr) & ((ULONGEST)1 << 63))? (((ULONGEST)(addr) >> 32) & 0x7fffffff) : 0) ++#define SPUADDR_ADDR(addr) \ ++ (((addr) & ((ULONGEST)1 << 63))? ((ULONGEST)(addr) & 0xffffffff) : (addr)) ++ ++/* Stand-alone SPE executable? */ ++#define spu_standalone_p() \ ++ (symfile_objfile && symfile_objfile->obfd \ ++ && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu) ++ ++/* Routines from spu-thread.c. */ ++extern int spu_switch_arch (int spu); ++ + #endif +diff -urNp src-orig/gdb/spu-thread.c src/gdb/spu-thread.c +--- src-orig/gdb/spu-thread.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/spu-thread.c 2007-06-28 01:26:24.113300235 +0200 +@@ -0,0 +1,476 @@ ++/* Cell SPU GNU/Linux thread support. ++ Copyright 2005,2006 IBM Corp. ++ ++ Contributed by Ulrich Weigand . ++ ++ This file is part of GDB. ++ ++ 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. */ ++ ++#include "defs.h" ++#include "gdbcore.h" ++#include "gdbcmd.h" ++#include "gdb_string.h" ++#include "gdb_assert.h" ++#include "arch-utils.h" ++#include "observer.h" ++#include "inferior.h" ++#include "regcache.h" ++#include "symfile.h" ++#include "objfiles.h" ++#include "block.h" ++#include "exec.h" ++ ++#include "ppc-tdep.h" ++#include "spu-tdep.h" ++ ++/* This module's target vector. */ ++static struct target_ops spu_ops; ++ ++/* Cached SPU fd of stand-alone SPE executable context. */ ++static int standalone_spufs_fd = 0; ++ ++/* Master spu_run call parameters. */ ++static int spufs_fd = 0; ++static CORE_ADDR spufs_addr = 0; ++ ++/* Find gdbarch for SPU. */ ++static struct gdbarch * ++spu_gdbarch_spu (void) ++{ ++ struct gdbarch *new_gdbarch; ++ ++ struct gdbarch_info info; ++ gdbarch_info_init (&info); ++ info.bfd_arch_info = bfd_lookup_arch (bfd_arch_spu, bfd_mach_spu); ++ info.byte_order = BFD_ENDIAN_BIG; ++ info.osabi = GDB_OSABI_UNKNOWN; ++ new_gdbarch = gdbarch_find_by_info (info); ++ ++ if (!new_gdbarch) ++ internal_error (__FILE__, __LINE__, ++ "spu_gdbarch_spu: failed to select architecture"); ++ ++ return new_gdbarch; ++} ++ ++/* Find gdbarch for PPU. */ ++static struct gdbarch * ++spu_gdbarch_ppu (void) ++{ ++ struct gdbarch *new_gdbarch; ++ ++ if (exec_bfd && bfd_get_arch (exec_bfd) != bfd_arch_spu) ++ { ++ new_gdbarch = gdbarch_from_bfd (exec_bfd); ++ } ++ else if (core_bfd && bfd_get_arch (core_bfd) != bfd_arch_spu) ++ { ++ new_gdbarch = gdbarch_from_bfd (core_bfd); ++ } ++ else ++ { ++ /* We've got neither exec nor core file, or they are SPU. Assume ++ 32-bit Linux PPC for the stand-alone SPE executable loader. */ ++ ++ struct gdbarch_info info; ++ gdbarch_info_init (&info); ++ info.bfd_arch_info = bfd_lookup_arch (bfd_arch_powerpc, bfd_mach_ppc); ++ info.byte_order = BFD_ENDIAN_BIG; ++ info.osabi = GDB_OSABI_LINUX; ++ new_gdbarch = gdbarch_find_by_info (info); ++ } ++ ++ if (!new_gdbarch) ++ internal_error (__FILE__, __LINE__, ++ "spu_gdbarch_ppu: failed to select architecture"); ++ ++ return new_gdbarch; ++} ++ ++/* Switch to SPU or PPU architecture. */ ++int ++spu_switch_arch (int spu) ++{ ++ int prev_spu; ++ prev_spu = (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_spu); ++ ++ if ((spu == 0) == (prev_spu == 0)) ++ return prev_spu; ++ ++ if (spu) ++ current_gdbarch = spu_gdbarch_spu (); ++ else ++ current_gdbarch = spu_gdbarch_ppu (); ++ ++ return prev_spu; ++} ++ ++/* PPU side system calls. */ ++#define INSTR_SC 0x44000002 ++#define NR_spu_run 0x0116 ++ ++/* If the PPU thread is currently stopped on a spu_run system call, ++ return to FD and ADDR the file handle and NPC parameter address ++ used with the system call. Return non-zero if successful. */ ++static int ++spu_detect_arch (ptid_t ptid, int *fd, CORE_ADDR *addr) ++{ ++ struct gdbarch_tdep *tdep; ++ struct regcache *regcache; ++ char buf[4]; ++ CORE_ADDR pc; ++ ULONGEST regval; ++ ++ /* Reset FD and ADDR. */ ++ *fd = 0; ++ *addr = 0; ++ ++ /* Switch to PPC architecture. */ ++ spu_switch_arch (0); ++ registers_changed (); ++ regcache = get_thread_regcache (ptid); ++ tdep = gdbarch_tdep (get_regcache_arch (regcache)); ++ ++ /* Get instruction pointer. */ ++ pc = read_pc_pid (ptid); ++ ++ /* Fetch instruction preceding current NIP. */ ++ if (target_read_memory (pc-4, buf, 4) != 0) ++ return 0; ++ /* It should be a "sc" instruction. */ ++ if (extract_unsigned_integer (buf, 4) != INSTR_SC) ++ return 0; ++ /* System call number should be NR_spu_run. */ ++ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, ®val); ++ if (regval != NR_spu_run) ++ return 0; ++ ++ /* Register ORIG_R3 contains fd, register 4 the NPC param pointer. */ ++ regcache_cooked_read_unsigned (regcache, tdep->ppc_orig_r3_regnum, ®val); ++ *fd = (int) regval; ++ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, ®val); ++ *addr = (CORE_ADDR) regval; ++ ++ /* Switch to SPU architecture. */ ++ spu_switch_arch (1); ++ registers_changed (); ++ return 1; ++} ++ ++/* Override the to_wait routine to detect current architecture. */ ++static ptid_t ++spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ ++ /* Always switch to PPU while running the inferior. This allows ++ linux-thread-db.c code to work as expected. */ ++ spu_switch_arch (0); ++ ++ /* Run it. */ ++ ptid = ops_beneath->to_wait (ptid, ourstatus); ++ ++ /* Detect and switch to current architecture. */ ++ if (ourstatus->kind == TARGET_WAITKIND_STOPPED) ++ spu_detect_arch (ptid, &spufs_fd, &spufs_addr); ++ ++ /* Detect stand-alone SPE executable context if applicable. */ ++ if (spu_standalone_p ()) ++ { ++ gdb_byte buf[4]; ++ if (target_read (¤t_target, TARGET_OBJECT_SPU, NULL, ++ buf, 0, sizeof buf) == 4) ++ standalone_spufs_fd = extract_unsigned_integer (buf, 4); ++ else ++ standalone_spufs_fd = 0; ++ } ++ ++ return ptid; ++} ++ ++/* Override the to_wait routine to detect current architecture. */ ++static void ++spu_switch_to_thread (void) ++{ ++ spu_detect_arch (inferior_ptid, &spufs_fd, &spufs_addr); ++} ++ ++/* Observer for inferior_created. */ ++static void ++spu_inferior_created (struct target_ops *target, int from_tty) ++{ ++ spu_switch_to_thread (); ++ stop_pc = read_pc (); ++} ++ ++/* Called when the target process died or is detached. */ ++static void ++spu_detach_hook (void) ++{ ++ spufs_fd = 0; ++ spufs_addr = 0; ++ standalone_spufs_fd = 0; ++} ++ ++ ++/* Is ADDR to be handled using SPU methods? */ ++static int ++spu_addr_is_spu (CORE_ADDR addr) ++{ ++ if (spu_standalone_p ()) ++ return addr < SPU_LS_SIZE; ++ else ++ return SPUADDR_SPU (addr) != 0; ++} ++ ++/* Override the to_region_ok_for_hw_watchpoint routine. */ ++static int ++spu_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ ++ while (ops_beneath && !ops_beneath->to_region_ok_for_hw_watchpoint) ++ ops_beneath = find_target_beneath (ops_beneath); ++ ++ /* We cannot watch SPU local store. */ ++ if (spu_addr_is_spu (addr)) ++ return 0; ++ ++ if (ops_beneath) ++ return ops_beneath->to_region_ok_for_hw_watchpoint (addr, len); ++ ++ return 0; ++} ++ ++/* Override the to_insert_breakpoint routine. */ ++static int ++spu_insert_breakpoint (struct bp_target_info *bp) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ CORE_ADDR addr = bp->placed_address; ++ int prev_spu, ret; ++ ++ /* Ignore attempts to insert breakpoints in a standalone SPE ++ executable just after startup, before we know the FD. */ ++ if (spu_standalone_p () && !standalone_spufs_fd && addr < SPU_LS_SIZE) ++ return 0; ++ ++ while (ops_beneath && !ops_beneath->to_insert_breakpoint) ++ ops_beneath = find_target_beneath (ops_beneath); ++ gdb_assert (ops_beneath); ++ ++ prev_spu = spu_switch_arch (spu_addr_is_spu (addr)); ++ ret = ops_beneath->to_insert_breakpoint (bp); ++ spu_switch_arch (prev_spu); ++ ++ return ret; ++} ++ ++/* Override the to_remove_breakpoint routine. */ ++static int ++spu_remove_breakpoint (struct bp_target_info *bp) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ CORE_ADDR addr = bp->placed_address; ++ int prev_spu, ret; ++ ++ /* Ignore attempts to remove breakpoints in a standalone SPE ++ executable just after startup, before we know the FD. */ ++ if (spu_standalone_p () && !standalone_spufs_fd && addr < SPU_LS_SIZE) ++ return 0; ++ ++ while (ops_beneath && !ops_beneath->to_remove_breakpoint) ++ ops_beneath = find_target_beneath (ops_beneath); ++ gdb_assert (ops_beneath); ++ ++ prev_spu = spu_switch_arch (spu_addr_is_spu (addr)); ++ ret = ops_beneath->to_remove_breakpoint (bp); ++ spu_switch_arch (prev_spu); ++ ++ return ret; ++} ++ ++ ++/* Override the to_fetch_registers routine. */ ++static void ++spu_fetch_registers (struct regcache *regcache, int regno) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ ++ /* This version applies only if we're currently in spu_run. */ ++ if (gdbarch_bfd_arch_info (get_regcache_arch (regcache))->arch ++ != bfd_arch_spu) ++ { ++ while (ops_beneath && !ops_beneath->to_fetch_registers) ++ ops_beneath = find_target_beneath (ops_beneath); ++ ++ gdb_assert (ops_beneath); ++ ops_beneath->to_fetch_registers (regcache, regno); ++ return; ++ } ++ ++ /* The ID register holds the spufs file handle. */ ++ if (regno == -1 || regno == SPU_ID_REGNUM) ++ { ++ char buf[4]; ++ store_unsigned_integer (buf, 4, spufs_fd); ++ regcache_raw_supply (regcache, SPU_ID_REGNUM, buf); ++ } ++ ++ /* The NPC register is found in PPC memory at SPUFS_ADDR. */ ++ if (spufs_addr && (regno == -1 || regno == SPU_PC_REGNUM)) ++ { ++ LONGEST ret; ++ char buf[4]; ++ ++ /* Switch to PPC arch while accessing target memory. */ ++ spu_switch_arch (0); ++ ret = target_read (ops_beneath, TARGET_OBJECT_MEMORY, NULL, ++ buf, spufs_addr, sizeof buf); ++ /* Switch back to SPU arch. */ ++ spu_switch_arch (1); ++ ++ if (ret == sizeof buf) ++ regcache_raw_supply (regcache, SPU_PC_REGNUM, buf); ++ } ++ ++ /* The GPRs are found in the "regs" spufs file. */ ++ if (spufs_fd && (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))) ++ { ++ char buf[16 * SPU_NUM_GPRS], annex[32]; ++ int i; ++ ++ xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd); ++ if (target_read (ops_beneath, TARGET_OBJECT_SPU, annex, ++ buf, 0, sizeof buf) == sizeof buf) ++ for (i = 0; i < SPU_NUM_GPRS; i++) ++ regcache_raw_supply (regcache, i, buf + i*16); ++ } ++} ++ ++/* Override the to_store_registers routine. */ ++static void ++spu_store_registers (struct regcache *regcache, int regno) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (&spu_ops); ++ ++ /* This version applies only if we're currently in spu_run. */ ++ if (gdbarch_bfd_arch_info (get_regcache_arch (regcache))->arch ++ != bfd_arch_spu) ++ { ++ while (ops_beneath && !ops_beneath->to_fetch_registers) ++ ops_beneath = find_target_beneath (ops_beneath); ++ ++ gdb_assert (ops_beneath); ++ ops_beneath->to_store_registers (regcache, regno); ++ return; ++ } ++ ++ /* The NPC register is found in PPC memory at SPUFS_ADDR. */ ++ if (spufs_addr && (regno == -1 || regno == SPU_PC_REGNUM)) ++ { ++ char buf[4]; ++ regcache_raw_collect (regcache, SPU_PC_REGNUM, buf); ++ ++ /* Switch to PPC arch while accessing target memory. */ ++ spu_switch_arch (0); ++ target_write (ops_beneath, TARGET_OBJECT_MEMORY, NULL, ++ buf, spufs_addr, sizeof buf); ++ /* Switch back to SPU arch. */ ++ spu_switch_arch (1); ++ } ++ ++ /* The GPRs are found in the "regs" spufs file. */ ++ if (spufs_fd && (regno == -1 || (regno >= 0 && regno < SPU_NUM_GPRS))) ++ { ++ char buf[16 * SPU_NUM_GPRS], annex[32]; ++ int i; ++ ++ for (i = 0; i < SPU_NUM_GPRS; i++) ++ regcache_raw_collect (regcache, i, buf + i*16); ++ ++ xsnprintf (annex, sizeof annex, "%d/regs", spufs_fd); ++ target_write (ops_beneath, TARGET_OBJECT_SPU, annex, ++ buf, 0, sizeof buf); ++ } ++} ++ ++/* Override the to_xfer_partial routine. */ ++static LONGEST ++spu_xfer_partial (struct target_ops *ops, enum target_object object, ++ const char *annex, gdb_byte *readbuf, ++ const gdb_byte *writebuf, ULONGEST offset, LONGEST len) ++{ ++ struct target_ops *ops_beneath = find_target_beneath (ops); ++ ++ /* Use the "mem" spufs file to access SPU local store. */ ++ if (object == TARGET_OBJECT_MEMORY) ++ { ++ int fd = spu_standalone_p ()? standalone_spufs_fd : SPUADDR_SPU (offset); ++ CORE_ADDR addr = SPUADDR_ADDR (offset); ++ char mem_annex[32]; ++ ++ if (!fd || addr >= SPU_LS_SIZE) ++ return 0; ++ ++ xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd); ++ return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU, ++ mem_annex, readbuf, writebuf, ++ addr, len); ++ } ++ ++ return ops_beneath->to_xfer_partial (ops_beneath, object, annex, ++ readbuf, writebuf, offset, len); ++} ++ ++ ++/* Initialize the SPU thread target. */ ++ ++static void ++init_spu_ops (void) ++{ ++ spu_ops.to_shortname = "spu"; ++ spu_ops.to_longname = "spu thread."; ++ spu_ops.to_doc = "SPU thread support."; ++ spu_ops.to_fetch_registers = spu_fetch_registers; ++ spu_ops.to_store_registers = spu_store_registers; ++ spu_ops.to_xfer_partial = spu_xfer_partial; ++ spu_ops.to_insert_breakpoint = spu_insert_breakpoint; ++ spu_ops.to_remove_breakpoint = spu_remove_breakpoint; ++ spu_ops.to_region_ok_for_hw_watchpoint = spu_region_ok_for_hw_watchpoint; ++ spu_ops.to_wait = spu_wait; ++ spu_ops.to_switch_to_thread = spu_switch_to_thread; ++ spu_ops.to_stratum = arch_stratum; ++ spu_ops.to_magic = OPS_MAGIC; ++} ++ ++ ++void ++_initialize_spu_nat (void) ++{ ++ /* Install ourselves on the target stack. */ ++ init_spu_ops (); ++ add_target (&spu_ops); ++ push_target (&spu_ops); ++ ++ /* Attach to inferior_created observer. */ ++ observer_attach_inferior_created (spu_inferior_created); ++ ++ /* FIXME: Add ourselves to detach hook. */ ++ deprecated_detach_hook = spu_detach_hook; ++} ++ +diff -urNp src-orig/gdb/target.h src/gdb/target.h +--- src-orig/gdb/target.h 2007-06-28 01:24:59.006666566 +0200 ++++ src/gdb/target.h 2007-06-28 01:25:17.045730503 +0200 +@@ -65,7 +65,8 @@ enum strata + core_stratum, /* Core dump files */ + download_stratum, /* Downloading of remote targets */ + process_stratum, /* Executing processes */ +- thread_stratum /* Executing threads */ ++ thread_stratum, /* Executing threads */ ++ arch_stratum /* Architecture overrides */ + }; + + enum thread_control_capabilities --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-pr36764 +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-pr36764 @@ -0,0 +1,55 @@ +diff -urNp src-orig/gdb/solib-spu.c src/gdb/solib-spu.c +--- src-orig/gdb/solib-spu.c 2007-07-24 15:07:45.715362000 +0200 ++++ src/gdb/solib-spu.c 2007-07-24 20:19:56.633857221 +0200 +@@ -169,8 +169,17 @@ spu_bfd_iovec_pread (struct bfd *abfd, v + file_ptr nbytes, file_ptr offset) + { + CORE_ADDR addr = *(CORE_ADDR *)stream; ++ struct gdbarch *prev_gdbarch; ++ int ret; + +- if (target_read_memory (addr + offset, buf, nbytes) != 0) ++ /* Switch to the PPE architecture while reading target memory. ++ This should not be necessary, but it is right now. */ ++ prev_gdbarch = current_gdbarch; ++ current_gdbarch = spu_gdbarch_ppu (); ++ ret = target_read_memory (addr + offset, buf, nbytes); ++ current_gdbarch = prev_gdbarch; ++ ++ if (ret != 0) + { + bfd_set_error (bfd_error_invalid_operation); + return -1; +diff -urNp src-orig/gdb/spu-tdep.h src/gdb/spu-tdep.h +--- src-orig/gdb/spu-tdep.h 2007-07-24 15:07:46.574369000 +0200 ++++ src/gdb/spu-tdep.h 2007-07-24 20:19:16.410666826 +0200 +@@ -68,6 +68,8 @@ enum spu_regnum + + /* Routines from spu-thread.c. */ + extern int spu_switch_arch (int spu); ++struct gdbarch *spu_gdbarch_spu (void); ++struct gdbarch *spu_gdbarch_ppu (void); + + extern const struct frame_unwind *spu_extra_unwind; + +diff -urNp src-orig/gdb/spu-thread.c src/gdb/spu-thread.c +--- src-orig/gdb/spu-thread.c 2007-07-24 15:07:46.760342000 +0200 ++++ src/gdb/spu-thread.c 2007-07-24 20:18:55.952424942 +0200 +@@ -56,7 +56,7 @@ static CORE_ADDR spufs_addr = 0; + static CORE_ADDR spe_current_active_context = 0; + + /* Find gdbarch for SPU. */ +-static struct gdbarch * ++struct gdbarch * + spu_gdbarch_spu (void) + { + struct gdbarch *new_gdbarch; +@@ -76,7 +76,7 @@ spu_gdbarch_spu (void) + } + + /* Find gdbarch for PPU. */ +-static struct gdbarch * ++struct gdbarch * + spu_gdbarch_ppu (void) + { + struct gdbarch *new_gdbarch; --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-skipprologue +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-skipprologue @@ -0,0 +1,116 @@ +diff -urNp src-orig/gdb/linespec.c src/gdb/linespec.c +--- src-orig/gdb/linespec.c 2007-06-18 20:23:08.000000000 +0200 ++++ src/gdb/linespec.c 2007-06-25 21:47:31.906989106 +0200 +@@ -1832,12 +1832,8 @@ minsym_found (int funfirstline, struct m + (struct bfd_section *) 0, 0); + values.sals[0].section = SYMBOL_BFD_SECTION (msymbol); + if (funfirstline) +- { +- values.sals[0].pc +- += gdbarch_deprecated_function_start_offset (current_gdbarch); +- values.sals[0].pc = gdbarch_skip_prologue +- (current_gdbarch, values.sals[0].pc); +- } ++ values.sals[0].pc = find_function_start_pc (values.sals[0].pc, ++ values.sals[0].section); + values.nelts = 1; + return values; + } +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-25 21:46:18.726486043 +0200 ++++ src/gdb/Makefile.in 2007-06-25 21:47:31.953982343 +0200 +@@ -2728,7 +2728,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) + $(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \ + $(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \ + $(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \ +- $(solist_h) ++ $(solist_h) $(arch_utils_h) + target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \ + $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ + $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \ +diff -urNp src-orig/gdb/symtab.c src/gdb/symtab.c +--- src-orig/gdb/symtab.c 2007-06-25 21:43:47.077307308 +0200 ++++ src/gdb/symtab.c 2007-06-25 21:47:32.003975149 +0200 +@@ -58,6 +58,7 @@ + #include "observer.h" + #include "gdb_assert.h" + #include "solist.h" ++#include "arch-utils.h" + + /* Prototypes for local functions */ + +@@ -2585,6 +2586,38 @@ find_pc_line_pc_range (CORE_ADDR pc, COR + return sal.symtab != 0; + } + ++/* Given a function start address PC and SECTION, find the first ++ address after the function prologue. */ ++CORE_ADDR ++find_function_start_pc (CORE_ADDR pc, asection *section) ++{ ++ struct gdbarch *gdbarch; ++ struct obj_section *osect; ++ ++ /* Find objfile associated with PC. */ ++ osect = find_pc_sect_section (pc, section); ++ if (!osect) ++ return pc; ++ ++ /* Find suitable gdbarch for objfile. */ ++ gdbarch = gdbarch_from_bfd (osect->objfile->obfd); ++ if (!gdbarch) ++ return pc; ++ ++ /* If function is in an unmapped overlay, use its unmapped LMA address, ++ so that gdbarch_skip_prologue has something unique to work on. */ ++ if (section_is_overlay (section) && !section_is_mapped (section)) ++ pc = overlay_unmapped_address (pc, section); ++ ++ pc += gdbarch_deprecated_function_start_offset (gdbarch); ++ pc = gdbarch_skip_prologue (gdbarch, pc); ++ ++ /* For overlays, map pc back into its mapped VMA range. */ ++ pc = overlay_mapped_address (pc, section); ++ ++ return pc; ++} ++ + /* Given a function symbol SYM, find the symtab and line for the start + of the function. + If the argument FUNFIRSTLINE is nonzero, we want the first line +@@ -2599,20 +2632,9 @@ find_function_start_sal (struct symbol * + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + fixup_symbol_section (sym, NULL); + if (funfirstline) +- { /* skip "first line" of function (which is actually its prologue) */ +- asection *section = SYMBOL_BFD_SECTION (sym); +- /* If function is in an unmapped overlay, use its unmapped LMA +- address, so that gdbarch_skip_prologue has something unique to work +- on */ +- if (section_is_overlay (section) && +- !section_is_mapped (section)) +- pc = overlay_unmapped_address (pc, section); +- +- pc += gdbarch_deprecated_function_start_offset (current_gdbarch); +- pc = gdbarch_skip_prologue (current_gdbarch, pc); +- +- /* For overlays, map pc back into its mapped VMA range */ +- pc = overlay_mapped_address (pc, section); ++ { ++ /* Skip "first line" of function (which is actually its prologue). */ ++ pc = find_function_start_pc (pc, SYMBOL_BFD_SECTION (sym)); + } + sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0); + +diff -urNp src-orig/gdb/symtab.h src/gdb/symtab.h +--- src-orig/gdb/symtab.h 2007-06-25 21:43:47.120301121 +0200 ++++ src/gdb/symtab.h 2007-06-25 21:47:32.045969105 +0200 +@@ -1339,6 +1339,8 @@ extern struct partial_symtab *find_main_ + + extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *); + ++extern CORE_ADDR find_function_start_pc (CORE_ADDR, asection *); ++ + extern struct symtab_and_line find_function_start_sal (struct symbol *sym, + int); + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-address +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-address @@ -0,0 +1,54 @@ +diff -urNp src-orig/gdb/solib.c src/gdb/solib.c +--- src-orig/gdb/solib.c 2007-06-25 21:44:28.695567125 +0200 ++++ src/gdb/solib.c 2007-06-25 21:46:27.132472502 +0200 +@@ -778,6 +778,8 @@ info_sharedlibrary_command (char *ignore + { + if (so->so_name[0]) + { ++ LONGEST mask = so->addr_mask ? so->addr_mask : (LONGEST)-1; ++ + if (!header_done) + { + printf_unfiltered ("%-*s%-*s%-12s%s\n", addr_width, "From", +@@ -789,13 +791,13 @@ info_sharedlibrary_command (char *ignore + printf_unfiltered ("%-*s", addr_width, + so->textsection != NULL + ? hex_string_custom ( +- (LONGEST) so->textsection->addr, ++ (LONGEST) so->textsection->addr & mask, + addr_width - 4) + : ""); + printf_unfiltered ("%-*s", addr_width, + so->textsection != NULL + ? hex_string_custom ( +- (LONGEST) so->textsection->endaddr, ++ (LONGEST) so->textsection->endaddr & mask, + addr_width - 4) + : ""); + printf_unfiltered ("%-12s", so->symbols_loaded ? "Yes" : "No"); +diff -urNp src-orig/gdb/solib-spu.c src/gdb/solib-spu.c +--- src-orig/gdb/solib-spu.c 2007-06-25 21:46:18.769479856 +0200 ++++ src/gdb/solib-spu.c 2007-06-25 21:46:27.136471927 +0200 +@@ -108,6 +108,9 @@ spu_current_sos (void) + xsnprintf (new->so_name, sizeof new->so_name, "@0x%llx <%d>", addr, fd); + strcpy (new->so_original_name, new->so_name); + ++ /* Set address mask to print just the LS offset part. */ ++ new->addr_mask = (LONGEST) 0xffffffff; ++ + *link_ptr = new; + link_ptr = &new->next; + } +diff -urNp src-orig/gdb/solist.h src/gdb/solist.h +--- src-orig/gdb/solist.h 2007-06-25 21:44:28.700566405 +0200 ++++ src/gdb/solist.h 2007-06-25 21:46:27.140471351 +0200 +@@ -54,6 +54,9 @@ struct so_list + /* shared object file name, expanded to something GDB can open */ + char so_name[SO_NAME_MAX_PATH_SIZE]; + ++ /* Mask to be used for printing addresses; 0 if unused. */ ++ LONGEST addr_mask; ++ + /* The following fields of the structure are built from + information gathered from the shared object file itself, and + are set when we actually add it to our symbol tables. --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-spu-gdb-regformatfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-spu-gdb-regformatfix @@ -0,0 +1,10 @@ +diff -urNp src-orig/gdb/regformats/reg-spu.dat src/gdb/regformats/reg-spu.dat +--- src-orig/gdb/regformats/reg-spu.dat 2006-11-22 18:34:15.000000000 +0100 ++++ src/gdb/regformats/reg-spu.dat 2007-07-24 15:05:10.594197943 +0200 +@@ -128,5 +128,5 @@ expedite:r0,r1,npc + 128:r125 + 128:r126 + 128:r127 +-32:npc + 32:id ++32:npc --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-dejagnu-config +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-dejagnu-config @@ -0,0 +1,186 @@ +diff -urpN src-orig/ppu-gdb-remote.exp src/ppu-gdb-remote.exp +--- src-orig/ppu-gdb-remote.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/ppu-gdb-remote.exp 2007-08-20 06:18:06.000000000 +0200 +@@ -0,0 +1,54 @@ ++load_generic_config "gdbserver" ++ ++process_multilib_options "" ++ ++if ![info exist env(GDB_TARGET_HOSTNAME)] { ++ error "GDB_TARGET_HOSTNAME variable must be set." ++} ++ ++note "Running tests on $env(GDB_TARGET_HOSTNAME)" ++ ++set_board_info hostname $env(GDB_TARGET_HOSTNAME) ++set_board_info username $env(USER) ++set_board_info rsh_prog /usr/bin/ssh ++set_board_info rcp_prog /usr/bin/scp ++ ++# Path to the gdbserver executable, if required. ++set_board_info gdb_server_prog /usr/bin/ppu-gdbserver ++ ++# Name of the computer whose socket will be used, if required. ++set_board_info gdb,sockethost $env(GDB_TARGET_HOSTNAME) ++ ++# Port ID to use for socket connection ++set_board_info gdb,socketport "3333" ++ ++# Use techniques appropriate to a stub ++set_board_info use_gdb_stub 1 ++ ++# This gdbserver can only run a process once per session. ++set_board_info gdb,do_reload_on_run 1 ++ ++# There's no support for argument-passing (yet). ++set_board_info noargs 1 ++ ++# Can't do input (or output) in the current gdbserver. ++set_board_info gdb,noinferiorio 1 ++ ++# Can't do hardware watchpoints, in general ++set_board_info gdb,no_hardware_watchpoints 1 ++ ++# drow's hack to run gdbserver locally ++set_board_info protocol foonevyn ++ ++proc foonevyn_download { board host dest } { ++ return $host ++} ++proc foonevyn_spawn { board cmd } { ++ global board_info ++ set baseboard [lindex [split $board "/"] 0] ++ set board_info($baseboard,isremote) 0 ++ set foo [remote_spawn $board $cmd] ++ set board_info($baseboard,isremote) 1 ++ return $foo ++} ++ +diff -urpN src-orig/test-installed-ppu-gdb src/test-installed-ppu-gdb +--- src-orig/test-installed-ppu-gdb 1970-01-01 01:00:00.000000000 +0100 ++++ src/test-installed-ppu-gdb 2007-08-20 06:18:29.000000000 +0200 +@@ -0,0 +1,124 @@ ++#! /bin/sh ++ ++# (C) 1998, 2000, 2002, 2003 Free Software Foundation ++# Originally by Alexandre Oliva ++ ++# This script is Free Software, and it can be copied, distributed and ++# modified as defined in the GNU General Public License. A copy of ++# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html ++ ++# This scripts assumes it lives in the contrib directory of the GCC ++# source tree, so it will find the testsuite tree from its location. ++# If you move it elsewhere, or want to use another testsuite tree, you ++# can override the defaults with --srcdir=/some/dir/GCC or ++# --testsuite=/some/dir/GCC/gcc/testsuite. If you specify ++# --testsuite, --srcdir will be ignored; otherwise, `/gcc/testsuite' ++# will be appended to the srcdir. ++ ++# You may specify where the binaries to be tested should be picked up ++# from. If you specify --prefix=/some/dir, gcc, g++ and g77 will be ++# looked for at /some/dir/bin. Each one may be overridden by ++# specifying --with-gcc=/pathname/to/gcc, --with-g++=/pathname/to/g++ ++# and --with-g77=/pathname/to/g77. If you specify --without-gcc, ++# --without-g++ or --without-g77, the test for the specified program ++# will be skipped. By default, gcc, g++ and g77 will be searched in ++# the PATH. ++ ++# An additional argument may specify --tmpdir=/some/dir; by default, ++# temporaries will be stored in the current directory, where the log ++# files will be stored. ++ ++# The script will interpret arguments until it finds one it does not ++# understand. The remaining ones will be passed to `runtest'. A ++# double-dash can be used to explicitly separate the arguments to ++# `test_installed' from the ones to `runtest'. ++ ++# This script should be run in an empty directory; it will refuse to ++# run if it finds a file named site.exp in the current directory. ++ ++ ++if test -f site.exp; then ++ echo site.exp already exists >&2 ++ exit 1 ++fi ++ ++while true; do ++ case "$1" in ++ --with-testsuite=*) testsuite=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --srcdir=*) srcdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ ++ --prefix=*) prefix=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-gdb=*) GDB_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-gcc=*) GCC_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-g++=*) GXX_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --target=*) RUNTARGET=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --tmpdir=*) tmpdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ ++ --help) cat <<\EOF ++Runs the testsuite for an installed version of gcc/g++/g77/objc ++Copyright (C) 1998 Free Software Foundation ++by Alexandre Oliva ++ ++Supported arguments: ++ ++--help prints this page ++ ++--with-testsuite=/some/dir/gcc/testsuite specify the testsuite directory ++--srcdir=/some/dir same as --with-testsuite=/some/dir/gcc/testsuite ++ [deduced from shell-script pathname] ++ ++--prefix=/some/dir use gdb, gcc, g++ and g77 from /some/dir/bin [PATH] ++--with-gdb=/some/dir/bin/gdb use specified gcc program [gdb] ++--with-gcc=/some/dir/bin/gcc use specified gcc program [gcc] ++--with-g++=/some/dir/bin/g++ use specified g++ program [g++] ++--target= run on specified target ++--tmpdir=/some/dir create temporaries and leave failed programs ++ at specified directory [.] ++ ++-- end of argument list; following arguments are passed to runtest ++EOF ++ exit ++ ;; ++ ++ --) shift; break;; ++ *) break;; ++ esac ++done ++ ++if test x"${testsuite+set}" != x"set" && test x"${srcdir+set}" != x"set"; then ++ file=$0 ++ while [ -h $file ]; do ++ file=`ls -l $file | sed s/'.* -> '//` ++ done ++ srcdir=`CDPATH=. && cd \`echo "$file" | sed 's,/*[^/]*$,,;s,^$,.,'\`/.. >/dev/null && ${PWDCMD-pwd}` ++fi ++ ++echo "gdb: "$GDB_UNDER_TEST ++ ++cat >site.exp <> site.exp ++ echo "set target_triplet powerpc64-unknown-linux-gnu" >> site.exp ++ echo "set host_alias powerpc64-unknown-linux-gnu" >> site.exp ++ echo "set host_triplet powerpc64-unknown-linux-gnu" >> site.exp ++ echo "set build_triplet powerpc64-unknown-linux-gnu" >> site.exp ++ } ++esac ++ ++runtest --tool gdb --tool_exec $GDB_UNDER_TEST ${1+"$@"} ++ ++exit 0 --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-solib-alignfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-solib-alignfix @@ -0,0 +1,12 @@ +diff -urNp src-orig/gdb/solib-svr4.c src/gdb/solib-svr4.c +--- src-orig/gdb/solib-svr4.c 2007-06-25 21:38:36.871749134 +0200 ++++ src/gdb/solib-svr4.c 2007-06-25 21:42:40.609768495 +0200 +@@ -184,7 +184,7 @@ LM_ADDR_CHECK (struct so_list *so, bfd * + don't adjust the base offset in the latter case, although + odds are that, if things really changed, debugging won't + quite work. */ +- if ((l_addr & align) == 0 && ((dynaddr - l_dynaddr) & align) == 0) ++ if ((l_addr & align) == ((l_dynaddr - dynaddr) & align)) + { + l_addr = l_dynaddr - dynaddr; + --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-solib-multiple +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-solib-multiple @@ -0,0 +1,704 @@ +diff -urNp src-orig/gdb/cp-namespace.c src/gdb/cp-namespace.c +--- src-orig/gdb/cp-namespace.c 2007-01-09 18:58:50.000000000 +0100 ++++ src/gdb/cp-namespace.c 2007-06-25 21:43:18.216073121 +0200 +@@ -491,7 +491,7 @@ lookup_symbol_file (const char *name, + } + else + { +- sym = lookup_symbol_global (name, linkage_name, domain, symtab); ++ sym = lookup_symbol_global (name, linkage_name, block, domain, symtab); + } + + if (sym != NULL) +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-25 21:37:17.019141143 +0200 ++++ src/gdb/Makefile.in 2007-06-25 21:43:18.265066071 +0200 +@@ -798,7 +798,7 @@ solib_h = solib.h + solib_pa64_h = solib-pa64.h + solib_som_h = solib-som.h + solib_svr4_h = solib-svr4.h +-solist_h = solist.h ++solist_h = solist.h $(symtab_h) + source_h = source.h + sparc64_tdep_h = sparc64-tdep.h $(sparc_tdep_h) + sparc_nat_h = sparc-nat.h +@@ -2572,7 +2572,7 @@ solib.o: solib.c $(defs_h) $(gdb_string_ + $(objfiles_h) $(exceptions_h) $(gdbcore_h) $(command_h) $(target_h) \ + $(frame_h) $(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) \ + $(gdbcmd_h) $(completer_h) $(filenames_h) $(exec_h) $(solist_h) \ +- $(observer_h) $(readline_h) ++ $(observer_h) $(readline_h) $(objfiles_h) + solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \ + $(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \ + $(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h) $(solib_h) +@@ -2719,7 +2719,8 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) + $(language_h) $(demangle_h) $(inferior_h) $(linespec_h) $(source_h) \ + $(filenames_h) $(objc_lang_h) $(ada_lang_h) $(hashtab_h) \ + $(gdb_obstack_h) $(block_h) $(dictionary_h) $(gdb_string_h) \ +- $(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) ++ $(gdb_stat_h) $(cp_abi_h) $(observer_h) $(gdb_assert_h) \ ++ $(solist_h) + target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \ + $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ + $(gdb_wait_h) $(dcache_h) $(regcache_h) $(gdb_assert_h) $(gdbcore_h) \ +diff -urNp src-orig/gdb/solib.c src/gdb/solib.c +--- src-orig/gdb/solib.c 2007-06-13 19:30:01.000000000 +0200 ++++ src/gdb/solib.c 2007-06-25 21:43:18.308059883 +0200 +@@ -955,6 +955,24 @@ show_auto_solib_add (struct ui_file *fil + } + + ++/* Handler for library-specific lookup of global symbol NAME in OBJFILE. Call ++ the library-specific handler if it is installed for the current target. */ ++ ++struct symbol * ++solib_global_lookup (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, ++ struct symtab **symtab) ++{ ++ if (current_target_so_ops->lookup_lib_global_symbol != NULL) ++ return current_target_so_ops->lookup_lib_global_symbol (objfile, ++ name, linkage_name, domain, symtab); ++ ++ return NULL; ++} ++ ++ + extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */ + + void +diff -urNp src-orig/gdb/solib-svr4.c src/gdb/solib-svr4.c +--- src-orig/gdb/solib-svr4.c 2007-06-25 21:43:07.447894197 +0200 ++++ src/gdb/solib-svr4.c 2007-06-25 21:43:18.316058732 +0200 +@@ -345,6 +345,76 @@ bfd_lookup_symbol (bfd *abfd, char *symn + return symaddr; + } + ++/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is ++ returned and the corresponding PTR is set. */ ++ ++static int ++scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) ++{ ++ int arch_size, step, sect_size; ++ long dyn_tag; ++ CORE_ADDR dyn_ptr, dyn_addr; ++ gdb_byte *bufend, *buf; ++ Elf32_External_Dyn *x_dynp_32; ++ Elf64_External_Dyn *x_dynp_64; ++ struct bfd_section *sect; ++ ++ if (abfd == NULL) ++ return 0; ++ arch_size = bfd_get_arch_size (abfd); ++ if (arch_size == -1) ++ return 0; ++ ++ /* Find the start address of the .dynamic section. */ ++ sect = bfd_get_section_by_name (abfd, ".dynamic"); ++ if (sect == NULL) ++ return 0; ++ dyn_addr = bfd_section_vma (abfd, sect); ++ ++ /* Read in .dynamic section, silently ignore errors. */ ++ sect_size = bfd_section_size (abfd, sect); ++ buf = alloca (sect_size); ++ if (target_read_memory (dyn_addr, buf, sect_size)) ++ { ++ /* If target_read_memory fails, try reading the BFD file. */ ++ if (!bfd_get_section_contents (abfd, sect, ++ buf, 0, sect_size)) ++ return 0; ++ } ++ ++ /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ ++ step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) ++ : sizeof (Elf64_External_Dyn); ++ for (bufend = buf + sect_size; ++ buf < bufend; ++ buf += step) ++ { ++ if (arch_size == 32) ++ { ++ x_dynp_32 = (Elf32_External_Dyn *) buf; ++ dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag); ++ dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr); ++ } ++ else ++ { ++ x_dynp_64 = (Elf64_External_Dyn *) buf; ++ dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); ++ dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr); ++ } ++ if (dyn_tag == DT_NULL) ++ return 0; ++ if (dyn_tag == dyntag) ++ { ++ if (ptr) ++ *ptr = dyn_ptr; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++ + /* + + LOCAL FUNCTION +@@ -372,114 +442,31 @@ bfd_lookup_symbol (bfd *abfd, char *symn + static CORE_ADDR + elf_locate_base (void) + { +- struct bfd_section *dyninfo_sect; +- int dyninfo_sect_size; +- CORE_ADDR dyninfo_addr; +- gdb_byte *buf; +- gdb_byte *bufend; +- int arch_size; ++ struct minimal_symbol *msymbol; ++ CORE_ADDR dyn_ptr; + +- /* Find the start address of the .dynamic section. */ +- dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); +- if (dyninfo_sect == NULL) ++ /* Find DT_DEBUG. */ ++ if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)) ++ return dyn_ptr; ++ ++ /* Find DT_MIPS_RLD_MAP. */ ++ if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)) + { +- /* This may be a static executable. Look for the symbol +- conventionally named _r_debug, as a last resort. */ +- struct minimal_symbol *msymbol; +- +- msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile); +- if (msymbol != NULL) +- return SYMBOL_VALUE_ADDRESS (msymbol); +- else ++ gdb_byte *pbuf; ++ int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); ++ pbuf = alloca (pbuf_size); ++ /* DT_MIPS_RLD_MAP contains a pointer to the address ++ of the dynamic link structure. */ ++ if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) + return 0; ++ return extract_typed_address (pbuf, builtin_type_void_data_ptr); + } + +- dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect); +- +- /* Read in .dynamic section, silently ignore errors. */ +- dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); +- buf = alloca (dyninfo_sect_size); +- if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) +- return 0; +- +- /* Find the DT_DEBUG entry in the the .dynamic section. +- For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has +- no DT_DEBUG entries. */ +- +- arch_size = bfd_get_arch_size (exec_bfd); +- if (arch_size == -1) /* failure */ +- return 0; +- +- if (arch_size == 32) +- { /* 32-bit elf */ +- for (bufend = buf + dyninfo_sect_size; +- buf < bufend; +- buf += sizeof (Elf32_External_Dyn)) +- { +- Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *) buf; +- long dyn_tag; +- CORE_ADDR dyn_ptr; +- +- dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag); +- if (dyn_tag == DT_NULL) +- break; +- else if (dyn_tag == DT_DEBUG) +- { +- dyn_ptr = bfd_h_get_32 (exec_bfd, +- (bfd_byte *) x_dynp->d_un.d_ptr); +- return dyn_ptr; +- } +- else if (dyn_tag == DT_MIPS_RLD_MAP) +- { +- gdb_byte *pbuf; +- int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); +- +- pbuf = alloca (pbuf_size); +- /* DT_MIPS_RLD_MAP contains a pointer to the address +- of the dynamic link structure. */ +- dyn_ptr = bfd_h_get_32 (exec_bfd, +- (bfd_byte *) x_dynp->d_un.d_ptr); +- if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) +- return 0; +- return extract_typed_address (pbuf, builtin_type_void_data_ptr); +- } +- } +- } +- else /* 64-bit elf */ +- { +- for (bufend = buf + dyninfo_sect_size; +- buf < bufend; +- buf += sizeof (Elf64_External_Dyn)) +- { +- Elf64_External_Dyn *x_dynp = (Elf64_External_Dyn *) buf; +- long dyn_tag; +- CORE_ADDR dyn_ptr; +- +- dyn_tag = bfd_h_get_64 (exec_bfd, (bfd_byte *) x_dynp->d_tag); +- if (dyn_tag == DT_NULL) +- break; +- else if (dyn_tag == DT_DEBUG) +- { +- dyn_ptr = bfd_h_get_64 (exec_bfd, +- (bfd_byte *) x_dynp->d_un.d_ptr); +- return dyn_ptr; +- } +- else if (dyn_tag == DT_MIPS_RLD_MAP) +- { +- gdb_byte *pbuf; +- int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); +- +- pbuf = alloca (pbuf_size); +- /* DT_MIPS_RLD_MAP contains a pointer to the address +- of the dynamic link structure. */ +- dyn_ptr = bfd_h_get_64 (exec_bfd, +- (bfd_byte *) x_dynp->d_un.d_ptr); +- if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) +- return 0; +- return extract_typed_address (pbuf, builtin_type_void_data_ptr); +- } +- } +- } ++ /* This may be a static executable. Look for the symbol ++ conventionally named _r_debug, as a last resort. */ ++ msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile); ++ if (msymbol != NULL) ++ return SYMBOL_VALUE_ADDRESS (msymbol); + + /* DT_DEBUG entry not found. */ + return 0; +@@ -1544,6 +1531,24 @@ svr4_lp64_fetch_link_map_offsets (void) + + struct target_so_ops svr4_so_ops; + ++/* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a ++ different rule for symbol lookup. The lookup begins here in the DSO, not in ++ the main executable. */ ++ ++static struct symbol * ++elf_lookup_lib_symbol (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, struct symtab **symtab) ++{ ++ if (objfile->obfd == NULL ++ || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1) ++ return NULL; ++ ++ return lookup_global_symbol_from_objfile ++ (objfile, name, linkage_name, domain, symtab); ++} ++ + extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */ + + void +@@ -1559,6 +1564,7 @@ _initialize_svr4_solib (void) + svr4_so_ops.current_sos = svr4_current_sos; + svr4_so_ops.open_symbol_file_object = open_symbol_file_object; + svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code; ++ svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol; + + /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */ + current_target_so_ops = &svr4_so_ops; +diff -urNp src-orig/gdb/solist.h src/gdb/solist.h +--- src-orig/gdb/solist.h 2007-01-09 18:58:58.000000000 +0100 ++++ src/gdb/solist.h 2007-06-25 21:43:18.358052689 +0200 +@@ -23,6 +23,8 @@ + #define SOLIST_H + + #define SO_NAME_MAX_PATH_SIZE 512 /* FIXME: Should be dynamic */ ++/* For domain_enum domain. */ ++#include "symtab.h" + + /* Forward declaration for target specific link map information. This + struct is opaque to all but the target specific file. */ +@@ -103,7 +105,14 @@ struct target_so_ops + Convenience function for remote debuggers finding host libs. */ + int (*find_and_open_solib) (char *soname, + unsigned o_flags, char **temp_pathname); +- ++ ++ /* Hook for looking up global symbols in a library-specific way. */ ++ struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, ++ struct symtab **symtab); ++ + }; + + /* Free the memory associated with a (so_list *). */ +@@ -125,4 +134,11 @@ extern struct target_so_ops *current_tar + #define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \ + (current_target_so_ops->in_dynsym_resolve_code) + ++/* Handler for library-specific global symbol lookup in solib.c. */ ++struct symbol *solib_global_lookup (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, ++ struct symtab **symtab); ++ + #endif +diff -urNp src-orig/gdb/symtab.c src/gdb/symtab.c +--- src-orig/gdb/symtab.c 2007-06-18 20:23:08.000000000 +0200 ++++ src/gdb/symtab.c 2007-06-25 21:43:18.368051250 +0200 +@@ -57,6 +57,7 @@ + #include "cp-abi.h" + #include "observer.h" + #include "gdb_assert.h" ++#include "solist.h" + + /* Prototypes for local functions */ + +@@ -1261,6 +1262,26 @@ lookup_symbol_aux_local (const char *nam + return NULL; + } + ++/* Look up OBJFILE to BLOCK. */ ++ ++static struct objfile * ++lookup_objfile_from_block (const struct block *block) ++{ ++ struct objfile *obj; ++ struct symtab *s; ++ ++ if (block == NULL) ++ return NULL; ++ ++ block = block_global_block (block); ++ /* Go through SYMTABS. */ ++ ALL_SYMTABS (obj, s) ++ if (block == BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK)) ++ return obj; ++ ++ return NULL; ++} ++ + /* Look up a symbol in a block; if found, locate its symtab, fixup the + symbol, and set block_found appropriately. */ + +@@ -1302,6 +1323,57 @@ lookup_symbol_aux_block (const char *nam + return NULL; + } + ++/* Check all global symbols in OBJFILE in symtabs and ++ psymtabs. */ ++ ++struct symbol * ++lookup_global_symbol_from_objfile (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, ++ struct symtab **symtab) ++{ ++ struct symbol *sym; ++ struct blockvector *bv; ++ const struct block *block; ++ struct symtab *s; ++ struct partial_symtab *ps; ++ ++ /* Go through symtabs. */ ++ ALL_OBJFILE_SYMTABS (objfile, s) ++ { ++ bv = BLOCKVECTOR (s); ++ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ++ sym = lookup_block_symbol (block, name, linkage_name, domain); ++ if (sym) ++ { ++ block_found = block; ++ if (symtab != NULL) ++ *symtab = s; ++ return fixup_symbol_section (sym, (struct objfile *)objfile); ++ } ++ } ++ ++ /* Now go through psymtabs. */ ++ ALL_OBJFILE_PSYMTABS (objfile, ps) ++ { ++ if (!ps->readin ++ && lookup_partial_symbol (ps, name, linkage_name, ++ 1, domain)) ++ { ++ s = PSYMTAB_TO_SYMTAB (ps); ++ bv = BLOCKVECTOR (s); ++ block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ++ sym = lookup_block_symbol (block, name, linkage_name, domain); ++ if (symtab != NULL) ++ *symtab = s; ++ return fixup_symbol_section (sym, (struct objfile *)objfile); ++ } ++ } ++ ++ return NULL; ++} ++ + /* Check to see if the symbol is defined in one of the symtabs. + BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK, + depending on whether or not we want to search global symbols or +@@ -1567,7 +1639,7 @@ basic_lookup_symbol_nonlocal (const char + if (sym != NULL) + return sym; + +- return lookup_symbol_global (name, linkage_name, domain, symtab); ++ return lookup_symbol_global (name, linkage_name, block, domain, symtab); + } + + /* Lookup a symbol in the static block associated to BLOCK, if there +@@ -1595,10 +1667,19 @@ lookup_symbol_static (const char *name, + struct symbol * + lookup_symbol_global (const char *name, + const char *linkage_name, ++ const struct block *block, + const domain_enum domain, + struct symtab **symtab) + { +- struct symbol *sym; ++ struct symbol *sym = NULL; ++ struct objfile *objfile = NULL; ++ ++ /* Call library-specific lookup procedure. */ ++ objfile = lookup_objfile_from_block (block); ++ if (objfile != NULL) ++ sym = solib_global_lookup (objfile, name, linkage_name, domain, symtab); ++ if (sym != NULL) ++ return sym; + + sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, + domain, symtab); +diff -urNp src-orig/gdb/symtab.h src/gdb/symtab.h +--- src-orig/gdb/symtab.h 2007-06-16 00:39:52.000000000 +0200 ++++ src/gdb/symtab.h 2007-06-25 21:43:18.412044919 +0200 +@@ -1050,6 +1050,7 @@ extern struct symbol *lookup_symbol_stat + + extern struct symbol *lookup_symbol_global (const char *name, + const char *linkage_name, ++ const struct block *block, + const domain_enum domain, + struct symtab **symtab); + +@@ -1398,4 +1399,12 @@ extern struct cleanup *make_cleanup_free + extern void set_main_name (const char *name); + extern /*const */ char *main_name (void); + ++/* Check global symbols in objfile. */ ++struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile, ++ const char *name, ++ const char *linkage_name, ++ const domain_enum domain, ++ struct symtab **symtab); ++ ++ + #endif /* !defined(SYMTAB_H) */ +diff -urNp src-orig/gdb/testsuite/gdb.base/libmd.c src/gdb/testsuite/gdb.base/libmd.c +--- src-orig/gdb/testsuite/gdb.base/libmd.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.base/libmd.c 2007-06-25 21:43:18.416044343 +0200 +@@ -0,0 +1,36 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling . ++*/ ++extern void foo(); ++#include ++#include "libmd.h" ++ ++void foo2 (); ++ ++void ++foo () ++{ ++ printf ("foo in lib\n"); ++ return; ++} ++ ++void ++foo2() ++{ ++ printf ("foo2 in lib\n"); ++ return; ++} +diff -urNp src-orig/gdb/testsuite/gdb.base/libmd.h src/gdb/testsuite/gdb.base/libmd.h +--- src-orig/gdb/testsuite/gdb.base/libmd.h 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.base/libmd.h 2007-06-25 21:43:18.420043768 +0200 +@@ -0,0 +1,18 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling . ++*/ ++extern void foo(); +diff -urNp src-orig/gdb/testsuite/gdb.base/solib_symbol.c src/gdb/testsuite/gdb.base/solib_symbol.c +--- src-orig/gdb/testsuite/gdb.base/solib_symbol.c 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.base/solib_symbol.c 2007-06-25 21:43:18.423043336 +0200 +@@ -0,0 +1,45 @@ ++/* Copyright 2007 Free Software Foundation, Inc. ++ 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. ++ ++ Contributed by Markus Deuling . ++*/ ++extern void foo(); ++#include ++#include "libmd.h" ++ ++extern void foo(); ++void foo3(); ++void foo2(); ++ ++int main () ++{ ++ printf ("in main\n"); ++ foo (); ++ foo3 (); ++ return 0; ++} ++ ++void foo3() ++{ ++ printf ("foo3 in main\n"); ++ return; ++} ++ ++void foo2() ++{ ++ printf ("foo2 in main\n"); ++ return; ++} ++ +diff -urNp src-orig/gdb/testsuite/gdb.base/solib_symbol.exp src/gdb/testsuite/gdb.base/solib_symbol.exp +--- src-orig/gdb/testsuite/gdb.base/solib_symbol.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/gdb/testsuite/gdb.base/solib_symbol.exp 2007-06-25 21:43:18.427042760 +0200 +@@ -0,0 +1,80 @@ ++# Copyright 2007 Free Software Foundation, Inc. ++# 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. ++# ++# Contributed by Markus Deuling . ++# ++ ++if {[skip_shlib_tests]} { ++ return 0 ++} ++ ++# Library file. ++set libname "libmd" ++set srcfile_lib ${srcdir}/${subdir}/${libname}.c ++set binfile_lib ${objdir}/${subdir}/${libname}.so ++set lib_flags [list debug ldflags=-Wl,-Bsymbolic] ++# Binary file. ++set testfile "solib_symbol" ++set srcfile ${srcdir}/${subdir}/${testfile}.c ++set binfile ${objdir}/${subdir}/${testfile} ++set bin_flags [list debug shlib=${binfile_lib}] ++ ++if [get_compiler_info ${binfile}] { ++ return -1 ++} ++ ++if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" ++ || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { ++ untested "Could not compile $binfile_lib or $binfile." ++ return -1 ++} ++ ++gdb_exit ++gdb_start ++gdb_reinitialize_dir $srcdir/$subdir ++gdb_load ${binfile} ++gdb_load_shlibs $binfile_lib ++ ++if ![runto_main] then { ++ fail "Can't run to main" ++ return 0 ++} ++ ++# Set a breakpoint in the binary. ++gdb_test "br foo2" \ ++ "Breakpoint.*file.*${srcfile}.*" \ ++ "foo2 in main" ++ ++delete_breakpoints ++ ++# Break in the library. ++gdb_test "br foo" \ ++ "" \ ++ "foo in libmd" ++ ++gdb_test "continue" \ ++ "Continuing.*" \ ++ "continue" ++ ++# This symbol is now looked up in the ELF library. ++gdb_test "br foo2" \ ++ "Breakpoint.*file.*${srcfile_lib}.*" \ ++ "foo2 in mdlib" ++ ++gdb_exit ++ ++return 0 ++ ++ --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-core +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-core @@ -0,0 +1,223 @@ +diff -urNp src-orig/gdb/corelow.c src/gdb/corelow.c +--- src-orig/gdb/corelow.c 2007-06-16 19:16:25.000000000 +0200 ++++ src/gdb/corelow.c 2007-06-25 21:48:53.928681559 +0200 +@@ -514,6 +514,33 @@ core_files_info (struct target_ops *t) + print_section_info (t, core_bfd); + } + ++struct spuid_list ++{ ++ gdb_byte *buf; ++ ULONGEST offset; ++ LONGEST len; ++ ULONGEST pos; ++ ULONGEST written; ++}; ++ ++static void ++add_to_spuid_list (bfd *abfd, asection *asect, void *list_p) ++{ ++ struct spuid_list *list = list_p; ++ int fd, pos = 0; ++ ++ sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos); ++ if (pos == 0) ++ return; ++ ++ if (list->pos >= list->offset && list->pos + 4 <= list->offset + list->len) ++ { ++ store_unsigned_integer (list->buf + list->pos - list->offset, 4, fd); ++ list->written += 4; ++ } ++ list->pos += 4; ++} ++ + static LONGEST + core_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, gdb_byte *readbuf, +@@ -594,6 +621,53 @@ core_xfer_partial (struct target_ops *op + } + return -1; + ++ case TARGET_OBJECT_SPU: ++ if (readbuf && annex) ++ { ++ /* When the SPU contexts are stored in core file, BFD ++ represents this with a fake section called "SPU/". */ ++ ++ struct bfd_section *section; ++ bfd_size_type size; ++ char *contents; ++ ++ char sectionstr[100]; ++ xsnprintf (sectionstr, sizeof sectionstr, "SPU/%s", annex); ++ ++ section = bfd_get_section_by_name (core_bfd, sectionstr); ++ if (section == NULL) ++ return -1; ++ ++ size = bfd_section_size (core_bfd, section); ++ if (offset >= size) ++ return 0; ++ size -= offset; ++ if (size > len) ++ size = len; ++ if (size > 0 ++ && !bfd_get_section_contents (core_bfd, section, readbuf, ++ (file_ptr) offset, size)) ++ { ++ warning (_("Couldn't read SPU section in core file.")); ++ return -1; ++ } ++ ++ return size; ++ } ++ else if (readbuf) ++ { ++ /* NULL annex requests list of all present spuids. */ ++ struct spuid_list list; ++ list.buf = readbuf; ++ list.offset = offset; ++ list.len = len; ++ list.pos = 0; ++ list.written = 0; ++ bfd_map_over_sections (core_bfd, add_to_spuid_list, &list); ++ return list.written; ++ } ++ return -1; ++ + default: + if (ops->beneath != NULL) + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, +diff -urNp src-orig/gdb/linux-nat.c src/gdb/linux-nat.c +--- src-orig/gdb/linux-nat.c 2007-06-25 21:47:20.635883134 +0200 ++++ src/gdb/linux-nat.c 2007-06-25 21:48:53.938680120 +0200 +@@ -2697,6 +2697,119 @@ linux_nat_do_registers (bfd *obfd, ptid_ + note_data, note_size); + } + ++/* Enumerate spufs IDs for process PID. */ ++ ++static void ++iterate_over_spus (int pid, void (*callback) (void *, int), void *data) ++{ ++ char path[128]; ++ DIR *dir; ++ struct dirent *entry; ++ ++ xsnprintf (path, sizeof path, "/proc/%d/fd", pid); ++ dir = opendir (path); ++ if (!dir) ++ return; ++ ++ rewinddir (dir); ++ while ((entry = readdir (dir)) != NULL) ++ { ++ struct stat st; ++ struct statfs stfs; ++ int fd; ++ ++ fd = atoi (entry->d_name); ++ if (!fd) ++ continue; ++ ++ xsnprintf (path, sizeof path, "/proc/%d/fd/%d", pid, fd); ++ if (stat (path, &st) != 0) ++ continue; ++ if (!S_ISDIR (st.st_mode)) ++ continue; ++ ++ if (statfs (path, &stfs) != 0) ++ continue; ++ if (stfs.f_type != SPUFS_MAGIC) ++ continue; ++ ++ callback (data, fd); ++ } ++ ++ closedir (dir); ++} ++ ++/* Generate corefile notes for SPU contexts. */ ++ ++struct linux_spu_corefile_data ++{ ++ bfd *obfd; ++ char *note_data; ++ int *note_size; ++}; ++ ++static void ++linux_spu_corefile_callback (void *data, int fd) ++{ ++ struct linux_spu_corefile_data *args = data; ++ int i; ++ ++ static const char *spu_files[] = ++ { ++ "object-id", ++ "mem", ++ "regs", ++ "fpcr", ++ "lslr", ++ "decr", ++ "decr_status", ++ "signal1", ++ "signal1_type", ++ "signal2", ++ "signal2_type", ++ "event_mask", ++ "event_status", ++ "mbox_info", ++ "ibox_info", ++ "wbox_info", ++ "dma_info", ++ "proxydma_info", ++ }; ++ ++ for (i = 0; i < sizeof (spu_files) / sizeof (spu_files[0]); i++) ++ { ++ char annex[32], note_name[32]; ++ gdb_byte *spu_data; ++ LONGEST spu_len; ++ ++ xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[i]); ++ spu_len = target_read_alloc (¤t_target, TARGET_OBJECT_SPU, ++ annex, &spu_data); ++ if (spu_len > 0) ++ { ++ xsnprintf (note_name, sizeof note_name, "SPU/%s", annex); ++ args->note_data = elfcore_write_note (args->obfd, args->note_data, ++ args->note_size, note_name, ++ NT_SPU, spu_data, spu_len); ++ xfree (spu_data); ++ } ++ } ++} ++ ++static char * ++linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size) ++{ ++ struct linux_spu_corefile_data args; ++ args.obfd = obfd; ++ args.note_data = note_data; ++ args.note_size = note_size; ++ ++ iterate_over_spus (PIDGET (inferior_ptid), ++ linux_spu_corefile_callback, &args); ++ ++ return args.note_data; ++} ++ + /* Fills the "to_make_corefile_note" target vector. Builds the note + section for a corefile, and returns it in a malloc buffer. */ + +@@ -2754,6 +2867,8 @@ linux_nat_make_corefile_notes (bfd *obfd + xfree (auxv); + } + ++ note_data = linux_spu_make_corefile_notes (obfd, note_data, note_size); ++ + make_cleanup (xfree, note_data); + return note_data; + } --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-infrunfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-infrunfix @@ -0,0 +1,36 @@ +diff -urNp src-orig/gdb/infrun.c src/gdb/infrun.c +--- src-orig/gdb/infrun.c 2007-08-02 23:04:26.927910605 +0200 ++++ src/gdb/infrun.c 2007-08-02 23:04:32.888984032 +0200 +@@ -667,19 +667,26 @@ prepare_to_proceed (int step) + + /* Switched over from WAIT_PID. */ + if (!ptid_equal (wait_ptid, minus_one_ptid) +- && !ptid_equal (inferior_ptid, wait_ptid) +- && breakpoint_here_p (read_pc_pid (wait_ptid))) ++ && !ptid_equal (inferior_ptid, wait_ptid)) + { ++ ptid_t new_ptid = inferior_ptid; ++ ++ /* Switch back to WAIT_PID thread. */ ++ switch_to_thread (wait_ptid); ++ ++ if (!breakpoint_here_p (read_pc ())) ++ { ++ switch_to_thread (new_ptid); ++ return 0; ++ } ++ + /* If stepping, remember current thread to switch back to. */ + if (step) + { + stepping_past_breakpoint = 1; +- stepping_past_breakpoint_ptid = inferior_ptid; ++ stepping_past_breakpoint_ptid = new_ptid; + } + +- /* Switch back to WAIT_PID thread. */ +- switch_to_thread (wait_ptid); +- + /* We return 1 to indicate that there is a breakpoint here, + so we need to step over it before continuing to avoid + hitting it straight away. */ --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-ea-ptr +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-ea-ptr @@ -0,0 +1,80 @@ +diff -urNp src-orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src-orig/gdb/spu-tdep.c 2007-06-25 21:46:18.779478417 +0200 ++++ src/gdb/spu-tdep.c 2007-06-25 21:50:28.117486834 +0200 +@@ -333,7 +333,39 @@ spu_register_reggroup_p (struct gdbarch + return default_register_reggroup_p (gdbarch, regnum, group); + } + +-/* Address conversion. */ ++ ++/* Address handling. */ ++ ++static int ++spu_address_class_type_flags (int byte_size, int dwarf2_addr_class) ++{ ++ if (dwarf2_addr_class == 1) ++ return TYPE_FLAG_ADDRESS_CLASS_1; ++ else ++ return 0; ++} ++ ++static const char * ++spu_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags) ++{ ++ if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1) ++ return "__ea"; ++ else ++ return NULL; ++} ++ ++static int ++spu_address_class_name_to_type_flags (struct gdbarch *gdbarch, ++ const char *name, int *type_flags_ptr) ++{ ++ if (strcmp (name, "__ea") == 0) ++ { ++ *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1; ++ return 1; ++ } ++ else ++ return 0; ++} + + static void + spu_address_to_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr) +@@ -347,7 +379,8 @@ spu_pointer_to_address (struct type *typ + ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); + ULONGEST id = 0; + +- if (target_has_registers && target_has_stack && target_has_memory) ++ if (target_has_registers && target_has_stack && target_has_memory ++ && !TYPE_ADDRESS_CLASS_1 (type)) /* Pointer to ppe. */ + { + struct frame_info *frame = get_selected_frame (NULL); + id = get_frame_register_unsigned (frame, SPU_ID_REGNUM); +@@ -364,6 +397,7 @@ spu_integer_to_address (struct gdbarch * + ULONGEST id = 0; + + if (target_has_registers && target_has_stack && target_has_memory ++ && !TYPE_ADDRESS_CLASS_1 (type) /* Pointer to ppe. */ + /* FIXME: Currently needed for dwarf2_read_address to work. */ + && type != builtin_type_uint32) + { +@@ -2177,10 +2211,16 @@ spu_gdbarch_init (struct gdbarch_info in + set_gdbarch_double_format (gdbarch, floatformats_ieee_double); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); + +- /* Address conversion. */ ++ /* Address handling. */ + set_gdbarch_address_to_pointer (gdbarch, spu_address_to_pointer); + set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address); + set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address); ++ set_gdbarch_address_class_type_flags (gdbarch, spu_address_class_type_flags); ++ set_gdbarch_address_class_type_flags_to_name ++ (gdbarch, spu_address_class_type_flags_to_name); ++ set_gdbarch_address_class_name_to_type_flags ++ (gdbarch, spu_address_class_name_to_type_flags); ++ + + /* Inferior function calls. */ + set_gdbarch_call_dummy_location (gdbarch, ON_STACK); --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-spu-gdb-fix-fortran_registers +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-spu-gdb-fix-fortran_registers @@ -0,0 +1,64 @@ +diff -urNp src-orig/gdb/f-typeprint.c src/gdb/f-typeprint.c +--- src-orig/gdb/f-typeprint.c 2007-01-09 18:58:50.000000000 +0100 ++++ src/gdb/f-typeprint.c 2007-06-25 21:36:36.623838539 +0200 +@@ -33,6 +33,7 @@ + #include "gdbcore.h" + #include "target.h" + #include "f-lang.h" ++#include "c-lang.h" + + #include "gdb_string.h" + #include +@@ -406,6 +407,11 @@ f_type_print_base (struct type *type, st + fputs_filtered (TYPE_TAG_NAME (type), stream); + break; + ++ case TYPE_CODE_UNION: ++ /* Union is a unknown data type in Fortran. Call the C-specific valprint ++ routine to print unions. */ ++ c_type_print_base (type, stream, show, level); ++ + default_case: + default: + /* Handle types not explicitly handled by the other cases, +diff -urNp src-orig/gdb/f-valprint.c src/gdb/f-valprint.c +--- src-orig/gdb/f-valprint.c 2007-02-27 20:46:04.000000000 +0100 ++++ src/gdb/f-valprint.c 2007-06-25 21:36:36.628837820 +0200 +@@ -36,6 +36,7 @@ + #include "gdbcore.h" + #include "command.h" + #include "block.h" ++#include "c-lang.h" + + #if 0 + static int there_is_a_visible_common_named (char *); +@@ -377,6 +378,13 @@ f_val_print (struct type *type, const gd + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { ++ /* Union is a unknown data type in Fortran. Call the C-specific valprint ++ routine to print unions. */ ++ case TYPE_CODE_UNION: ++ c_val_print (type, valaddr, embedded_offset, address, stream, format, ++ deref_ref, recurse, pretty); ++ break; ++ + case TYPE_CODE_STRING: + f77_get_dynamic_length_of_aggregate (type); + LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0); +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-18 17:46:36.000000000 +0200 ++++ src/gdb/Makefile.in 2007-06-25 21:36:36.640836093 +0200 +@@ -2018,10 +2018,10 @@ frv-tdep.o: frv-tdep.c $(defs_h) $(gdb_s + $(elf_bfd_h) $(elf_frv_h) $(osabi_h) $(infcall_h) $(frv_tdep_h) + f-typeprint.o: f-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ + $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \ +- $(f_lang_h) $(gdb_string_h) ++ $(f_lang_h) $(c_lang_h) $(gdb_string_h) + f-valprint.o: f-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \ + $(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \ +- $(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h) ++ $(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h) $(c_lang_h) + gcore.o: gcore.c $(defs_h) $(elf_bfd_h) $(infcall_h) $(inferior_h) \ + $(gdbcore_h) $(objfiles_h) $(symfile_h) $(cli_decode_h) \ + $(gdb_assert_h) --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-gdb-prepareproceed +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-gdb-prepareproceed @@ -0,0 +1,190 @@ +diff -urNp src-orig/gdb/gdbthread.h src/gdb/gdbthread.h +--- src-orig/gdb/gdbthread.h 2007-08-02 23:03:27.522405046 +0200 ++++ src/gdb/gdbthread.h 2007-08-02 22:57:49.557659066 +0200 +@@ -137,6 +137,9 @@ extern void load_infrun_state (ptid_t pt + int *current_line, + struct symtab **current_symtab); + ++/* Switch from one thread to another. */ ++extern void switch_to_thread (ptid_t ptid); ++ + /* Commands with a prefix of `thread'. */ + extern struct cmd_list_element *thread_cmd_list; + +diff -urNp src-orig/gdb/infrun.c src/gdb/infrun.c +--- src-orig/gdb/infrun.c 2007-08-02 23:03:27.541402316 +0200 ++++ src/gdb/infrun.c 2007-08-02 23:03:32.794445747 +0200 +@@ -80,7 +80,7 @@ static int currently_stepping (struct ex + + static void xdb_handle_command (char *args, int from_tty); + +-static int prepare_to_proceed (void); ++static int prepare_to_proceed (int); + + void _initialize_infrun (void); + +@@ -448,6 +448,11 @@ static CORE_ADDR singlestep_pc; + thread here so that we can resume single-stepping it later. */ + static ptid_t saved_singlestep_ptid; + static int stepping_past_singlestep_breakpoint; ++ ++/* Similarly, if we are stepping another thread past a breakpoint, ++ save the original thread here so that we can resume stepping it later. */ ++static ptid_t stepping_past_breakpoint_ptid; ++static int stepping_past_breakpoint; + + + /* Things to clean up if we QUIT out of resume (). */ +@@ -645,7 +650,7 @@ clear_proceed_status (void) + /* This should be suitable for any targets that support threads. */ + + static int +-prepare_to_proceed (void) ++prepare_to_proceed (int step) + { + ptid_t wait_ptid; + struct target_waitstatus wait_status; +@@ -653,42 +658,35 @@ prepare_to_proceed (void) + /* Get the last target status returned by target_wait(). */ + get_last_target_status (&wait_ptid, &wait_status); + +- /* Make sure we were stopped either at a breakpoint, or because +- of a Ctrl-C. */ ++ /* Make sure we were stopped at a breakpoint. */ + if (wait_status.kind != TARGET_WAITKIND_STOPPED +- || (wait_status.value.sig != TARGET_SIGNAL_TRAP +- && wait_status.value.sig != TARGET_SIGNAL_INT)) ++ || wait_status.value.sig != TARGET_SIGNAL_TRAP) + { + return 0; + } + ++ /* Switched over from WAIT_PID. */ + if (!ptid_equal (wait_ptid, minus_one_ptid) +- && !ptid_equal (inferior_ptid, wait_ptid)) ++ && !ptid_equal (inferior_ptid, wait_ptid) ++ && breakpoint_here_p (read_pc_pid (wait_ptid))) + { +- /* Switched over from WAIT_PID. */ +- CORE_ADDR wait_pc = read_pc_pid (wait_ptid); +- +- if (wait_pc != read_pc ()) ++ /* If stepping, remember current thread to switch back to. */ ++ if (step) + { +- /* Switch back to WAIT_PID thread. */ +- inferior_ptid = wait_ptid; +- +- /* FIXME: This stuff came from switch_to_thread() in +- thread.c (which should probably be a public function). */ +- reinit_frame_cache (); +- registers_changed (); +- stop_pc = wait_pc; ++ stepping_past_breakpoint = 1; ++ stepping_past_breakpoint_ptid = inferior_ptid; + } + ++ /* Switch back to WAIT_PID thread. */ ++ switch_to_thread (wait_ptid); ++ + /* We return 1 to indicate that there is a breakpoint here, +- so we need to step over it before continuing to avoid +- hitting it straight away. */ +- if (breakpoint_here_p (wait_pc)) +- return 1; ++ so we need to step over it before continuing to avoid ++ hitting it straight away. */ ++ return 1; + } + + return 0; +- + } + + /* Record the pc of the program the last time it stopped. This is +@@ -754,7 +752,7 @@ proceed (CORE_ADDR addr, enum target_sig + prepare_to_proceed checks the current thread against the thread + that reported the most recent event. If a step-over is required + it returns TRUE and sets the current thread to the old thread. */ +- if (prepare_to_proceed () && breakpoint_here_p (read_pc ())) ++ if (prepare_to_proceed (step)) + oneproc = 1; + + if (oneproc) +@@ -875,6 +873,7 @@ init_wait_for_inferior (void) + clear_proceed_status (); + + stepping_past_singlestep_breakpoint = 0; ++ stepping_past_breakpoint = 0; + } + + /* This enum encodes possible reasons for doing a target_wait, so that +@@ -1144,8 +1143,8 @@ context_switch (struct execution_control + &ecs->stepping_through_solib_catchpoints, + &ecs->current_line, &ecs->current_symtab); + } +- inferior_ptid = ecs->ptid; +- reinit_frame_cache (); ++ ++ switch_to_thread (ecs->ptid); + } + + static void +@@ -1568,6 +1567,37 @@ handle_inferior_event (struct execution_ + + stepping_past_singlestep_breakpoint = 0; + ++ if (stepping_past_breakpoint) ++ { ++ stepping_past_breakpoint = 0; ++ ++ /* If we stopped for some other reason than single-stepping, ignore ++ the fact that we were supposed to switch back. */ ++ if (stop_signal == TARGET_SIGNAL_TRAP) ++ { ++ if (debug_infrun) ++ fprintf_unfiltered (gdb_stdlog, ++ "infrun: stepping_past_breakpoint\n"); ++ ++ /* Pull the single step breakpoints out of the target. */ ++ if (singlestep_breakpoints_inserted_p) ++ { ++ remove_single_step_breakpoints (); ++ singlestep_breakpoints_inserted_p = 0; ++ } ++ ++ /* Note: We do not call context_switch at this point, as the ++ context is already set up for stepping the original thread. */ ++ switch_to_thread (stepping_past_breakpoint_ptid); ++ /* Suppress spurious "Switching to ..." message. */ ++ previous_inferior_ptid = inferior_ptid; ++ ++ resume (1, TARGET_SIGNAL_0); ++ prepare_to_wait (ecs); ++ return; ++ } ++ } ++ + /* See if a thread hit a thread-specific breakpoint that was meant for + another thread. If so, then step that thread past the breakpoint, + and continue it. */ +diff -urNp src-orig/gdb/thread.c src/gdb/thread.c +--- src-orig/gdb/thread.c 2007-08-02 23:03:27.549401166 +0200 ++++ src/gdb/thread.c 2007-08-02 22:57:49.622649726 +0200 +@@ -61,7 +61,6 @@ static int thread_alive (struct thread_i + static void info_threads_command (char *, int); + static void thread_apply_command (char *, int); + static void restore_current_thread (ptid_t); +-static void switch_to_thread (ptid_t ptid); + static void prune_threads (void); + static struct cleanup *make_cleanup_restore_current_thread (ptid_t, + struct frame_id); +@@ -454,7 +453,7 @@ info_threads_command (char *arg, int fro + + /* Switch from one thread to another. */ + +-static void ++void + switch_to_thread (ptid_t ptid) + { + if (ptid_equal (ptid, inferior_ptid)) --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/ppu/diff-combined-gdb-pr37807 +++ cell-gdb-6.6.50cvs20070623/debian/patches/ppu/diff-combined-gdb-pr37807 @@ -0,0 +1,42 @@ +diff -urNp src-orig/gdb/regcache.c src/gdb/regcache.c +--- src-orig/gdb/regcache.c 2007-08-20 18:11:25.018120000 +0200 ++++ src/gdb/regcache.c 2007-08-20 18:10:23.550667966 +0200 +@@ -463,6 +463,22 @@ regcache_observer_target_changed (struct + registers_changed (); + } + ++ ++static void ++do_switch_current_gdbarch_cleanup (void *arg) ++{ ++ current_gdbarch = arg; ++} ++ ++static struct cleanup * ++make_cleanup_switch_current_gdbarch (struct regcache *regcache) ++{ ++ struct gdbarch *old_gdbarch = current_gdbarch; ++ current_gdbarch = get_regcache_arch (regcache); ++ return make_cleanup (do_switch_current_gdbarch_cleanup, old_gdbarch); ++} ++ ++ + /* Low level examining and depositing of registers. + + The caller is responsible for making sure that the inferior is +@@ -505,6 +521,7 @@ regcache_raw_read (struct regcache *regc + if (!regcache_valid_p (regcache, regnum)) + { + struct cleanup *old_chain = save_inferior_ptid (); ++ make_cleanup_switch_current_gdbarch (regcache); + inferior_ptid = regcache->ptid; + target_fetch_registers (regcache, regnum); + do_cleanups (old_chain); +@@ -663,6 +680,7 @@ regcache_raw_write (struct regcache *reg + return; + + old_chain = save_inferior_ptid (); ++ make_cleanup_switch_current_gdbarch (regcache); + inferior_ptid = regcache->ptid; + + target_prepare_to_store (regcache); --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/series +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/series @@ -0,0 +1,6 @@ +diff-spu-gdb-regformatfix -p0 +diff-spu-gdb-fix-fortran_registers -p0 +diff-spu-ext-mi -p0 +diff-dejagnu-config -p0 +diff-wrap-spu-addr -p0 +diff-fix-gdbsrv-dejagnu -p0 --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-spu-ext-mi +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-spu-ext-mi @@ -0,0 +1,15 @@ +diff -urNp src-orig/gdb/mi/mi-cmds.c src/gdb/mi/mi-cmds.c +--- src-orig/gdb/mi/mi-cmds.c 2007-04-14 11:51:29.000000000 +0200 ++++ src/gdb/mi/mi-cmds.c 2007-06-25 21:37:23.172186121 +0200 +@@ -100,6 +100,11 @@ struct mi_cmd mi_cmds[] = + { "signal-handle", { NULL, 0 }, NULL, NULL }, + { "signal-list-handle-actions", { NULL, 0 }, NULL, NULL }, + { "signal-list-signal-types", { NULL, 0 }, NULL, NULL }, ++ { "spu-info-event", { "info spu event", 0 }, NULL, NULL }, ++ { "spu-info-signal", { "info spu signal", 0 }, NULL, NULL }, ++ { "spu-info-mailbox", { "info spu mailbox", 0 }, NULL, NULL }, ++ { "spu-info-dma", { "info spu dma", 0 }, NULL, NULL }, ++ { "spu-info-proxydma", { "info spu proxydma", 0 }, NULL, NULL }, + { "stack-info-depth", { NULL, 0 }, 0, mi_cmd_stack_info_depth}, + { "stack-info-frame", { NULL, 0 }, 0, mi_cmd_stack_info_frame}, + { "stack-list-arguments", { NULL, 0 }, 0, mi_cmd_stack_list_args}, --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-fix-gdbsrv-dejagnu +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-fix-gdbsrv-dejagnu @@ -0,0 +1,32 @@ +diff -urpN src-orig/gdb/testsuite/lib/gdbserver-support.exp src/gdb/testsuite/lib/gdbserver-support.exp +--- src-orig/gdb/testsuite/lib/gdbserver-support.exp 2007-05-23 14:41:12.000000000 +0200 ++++ src/gdb/testsuite/lib/gdbserver-support.exp 2007-08-17 19:28:49.000000000 +0200 +@@ -179,10 +179,10 @@ proc gdbserver_spawn { child_args } { + } + + # Extract the local and remote host ids from the target board struct. +- if [target_info exists sockethost] { +- set debughost [target_info sockethost] ++ if [target_info exists gdb,sockethost] { ++ set debughost [target_info gdb,sockethost] + } else { +- set debughost "localhost:" ++ set debughost "localhost" + } + + # Extract the protocol +@@ -195,12 +195,12 @@ proc gdbserver_spawn { child_args } { + set gdbserver [find_gdbserver] + + # Export the host:port pair. +- set gdbport $debughost$portnum ++ set gdbport $debughost:$portnum + + # Fire off the debug agent. This flavour of gdbserver takes as + # arguments the port information, the name of the executable file to + # be debugged, and any arguments. +- set gdbserver_command "$gdbserver :$portnum $gdbserver_server_exec" ++ set gdbserver_command "$gdbserver $gdbport $gdbserver_server_exec" + if { $child_args != "" } { + append gdbserver_command " $child_args" + } --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-wrap-spu-addr +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-wrap-spu-addr @@ -0,0 +1,50 @@ +diff -urpN src.orig/gdb/spu-tdep.c src/gdb/spu-tdep.c +--- src.orig/gdb/spu-tdep.c 2007-06-16 19:25:59.000000000 +0200 ++++ src/gdb/spu-tdep.c 2007-08-09 08:33:15.839885981 +0200 +@@ -324,6 +324,35 @@ spu_register_reggroup_p (struct gdbarch + return default_register_reggroup_p (gdbarch, regnum, group); + } + ++/* Address conversion. */ ++ ++static CORE_ADDR ++spu_pointer_to_address (struct type *type, const gdb_byte *buf) ++{ ++ ULONGEST addr = extract_unsigned_integer (buf, TYPE_LENGTH (type)); ++ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */ ++ ++ if (target_has_registers && target_has_stack && target_has_memory) ++ lslr = get_frame_register_unsigned (get_selected_frame (NULL), ++ SPU_LSLR_REGNUM); ++ ++ return addr & lslr; ++} ++ ++static CORE_ADDR ++spu_integer_to_address (struct gdbarch *gdbarch, ++ struct type *type, const gdb_byte *buf) ++{ ++ ULONGEST addr = unpack_long (type, buf); ++ ULONGEST lslr = SPU_LS_SIZE - 1; /* Hard-wired LS size. */ ++ ++ if (target_has_registers && target_has_stack && target_has_memory) ++ lslr = get_frame_register_unsigned (get_selected_frame (NULL), ++ SPU_LSLR_REGNUM); ++ ++ return addr & lslr; ++} ++ + + /* Decoding SPU instructions. */ + +@@ -2008,6 +2037,10 @@ spu_gdbarch_init (struct gdbarch_info in + set_gdbarch_double_format (gdbarch, floatformats_ieee_double); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); + ++ /* Address conversion. */ ++ set_gdbarch_pointer_to_address (gdbarch, spu_pointer_to_address); ++ set_gdbarch_integer_to_address (gdbarch, spu_integer_to_address); ++ + /* Inferior function calls. */ + set_gdbarch_call_dummy_location (gdbarch, ON_STACK); + set_gdbarch_frame_align (gdbarch, spu_frame_align); --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-spu-gdb-regformatfix +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-spu-gdb-regformatfix @@ -0,0 +1,10 @@ +diff -urNp src-orig/gdb/regformats/reg-spu.dat src/gdb/regformats/reg-spu.dat +--- src-orig/gdb/regformats/reg-spu.dat 2006-11-22 18:34:15.000000000 +0100 ++++ src/gdb/regformats/reg-spu.dat 2007-07-24 15:05:10.594197943 +0200 +@@ -128,5 +128,5 @@ expedite:r0,r1,npc + 128:r125 + 128:r126 + 128:r127 +-32:npc + 32:id ++32:npc --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-dejagnu-config +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-dejagnu-config @@ -0,0 +1,220 @@ +diff -urpN src.orig/spu-gdb-native.exp src/spu-gdb-native.exp +--- src.orig/spu-gdb-native.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/spu-gdb-native.exp 2007-08-17 17:11:43.000000000 +0200 +@@ -0,0 +1,15 @@ ++load_generic_config "unix" ++ ++if { [istarget "spu-*"] } { ++ # We can't pass arguments. ++ set_board_info gdb,noargs 1 ++ set_board_info noargs 1 ++ # Or do signals. ++ set_board_info gdb,nosignals 1 ++ # We can't do I/O in GDB. ++ set_board_info gdb,noinferiorio 1 ++ set_board_info gdb,nofileio 1 ++ # Huge tests don't work ++ set_board_info gdb,skip_huge_test 1 ++ set_board_info gcc,stack_size 16384 ++} +diff -urpN src.orig/spu-gdb-remote.exp src/spu-gdb-remote.exp +--- src.orig/spu-gdb-remote.exp 1970-01-01 01:00:00.000000000 +0100 ++++ src/spu-gdb-remote.exp 2007-08-17 17:19:58.000000000 +0200 +@@ -0,0 +1,69 @@ ++load_generic_config "gdbserver" ++ ++process_multilib_options "" ++ ++if ![info exist env(GDB_TARGET_HOSTNAME)] { ++ error "GDB_TARGET_HOSTNAME variable must be set." ++} ++ ++note "Running tests on $env(GDB_TARGET_HOSTNAME)" ++ ++set_board_info hostname $env(GDB_TARGET_HOSTNAME) ++set_board_info username $env(USER) ++set_board_info rsh_prog /usr/bin/ssh ++set_board_info rcp_prog /usr/bin/scp ++ ++# Path to the gdbserver executable, if required. ++set_board_info gdb_server_prog /usr/bin/spu-gdbserver ++ ++# Name of the computer whose socket will be used, if required. ++set_board_info gdb,sockethost $env(GDB_TARGET_HOSTNAME) ++ ++# Port ID to use for socket connection ++set_board_info gdb,socketport "1111" ++ ++# Use techniques appropriate to a stub ++set_board_info use_gdb_stub 1 ++ ++# This gdbserver can only run a process once per session. ++set_board_info gdb,do_reload_on_run 1 ++ ++# There's no support for argument-passing (yet). ++set_board_info noargs 1 ++ ++# Can't do input (or output) in the current gdbserver. ++set_board_info gdb,noinferiorio 1 ++ ++# Can't do hardware watchpoints, in general ++set_board_info gdb,no_hardware_watchpoints 1 ++ ++ ++if { [istarget "spu-*"] } { ++ # We can't pass arguments. ++ set_board_info gdb,noargs 1 ++ set_board_info noargs 1 ++ # Or do signals. ++ set_board_info gdb,nosignals 1 ++ # We can't do I/O in GDB. ++ set_board_info gdb,noinferiorio 1 ++ set_board_info gdb,nofileio 1 ++ # Huge tests don't work ++ set_board_info gdb,skip_huge_test 1 ++ set_board_info gcc,stack_size 16384 ++} ++ ++# drow's hack to run gdbserver locally ++set_board_info protocol foonevyn ++ ++proc foonevyn_download { board host dest } { ++ return $host ++} ++proc foonevyn_spawn { board cmd } { ++ global board_info ++ set baseboard [lindex [split $board "/"] 0] ++ set board_info($baseboard,isremote) 0 ++ set foo [remote_spawn $board $cmd] ++ set board_info($baseboard,isremote) 1 ++ return $foo ++} ++ +diff -urpN src.orig/test-installed-spu-gdb src/test-installed-spu-gdb +--- src.orig/test-installed-spu-gdb 1970-01-01 01:00:00.000000000 +0100 ++++ src/test-installed-spu-gdb 2007-08-17 17:31:37.000000000 +0200 +@@ -0,0 +1,124 @@ ++#! /bin/sh ++ ++# (C) 1998, 2000, 2002, 2003 Free Software Foundation ++# Originally by Alexandre Oliva ++ ++# This script is Free Software, and it can be copied, distributed and ++# modified as defined in the GNU General Public License. A copy of ++# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html ++ ++# This scripts assumes it lives in the contrib directory of the GCC ++# source tree, so it will find the testsuite tree from its location. ++# If you move it elsewhere, or want to use another testsuite tree, you ++# can override the defaults with --srcdir=/some/dir/GCC or ++# --testsuite=/some/dir/GCC/gcc/testsuite. If you specify ++# --testsuite, --srcdir will be ignored; otherwise, `/gcc/testsuite' ++# will be appended to the srcdir. ++ ++# You may specify where the binaries to be tested should be picked up ++# from. If you specify --prefix=/some/dir, gcc, g++ and g77 will be ++# looked for at /some/dir/bin. Each one may be overridden by ++# specifying --with-gcc=/pathname/to/gcc, --with-g++=/pathname/to/g++ ++# and --with-g77=/pathname/to/g77. If you specify --without-gcc, ++# --without-g++ or --without-g77, the test for the specified program ++# will be skipped. By default, gcc, g++ and g77 will be searched in ++# the PATH. ++ ++# An additional argument may specify --tmpdir=/some/dir; by default, ++# temporaries will be stored in the current directory, where the log ++# files will be stored. ++ ++# The script will interpret arguments until it finds one it does not ++# understand. The remaining ones will be passed to `runtest'. A ++# double-dash can be used to explicitly separate the arguments to ++# `test_installed' from the ones to `runtest'. ++ ++# This script should be run in an empty directory; it will refuse to ++# run if it finds a file named site.exp in the current directory. ++ ++ ++if test -f site.exp; then ++ echo site.exp already exists >&2 ++ exit 1 ++fi ++ ++while true; do ++ case "$1" in ++ --with-testsuite=*) testsuite=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --srcdir=*) srcdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ ++ --prefix=*) prefix=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-gdb=*) GDB_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-gcc=*) GCC_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --with-g++=*) GXX_UNDER_TEST=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --target=*) RUNTARGET=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ --tmpdir=*) tmpdir=`echo "$1" | sed 's/[^=]*=//'`; shift;; ++ ++ --help) cat <<\EOF ++Runs the testsuite for an installed version of gcc/g++/g77/objc ++Copyright (C) 1998 Free Software Foundation ++by Alexandre Oliva ++ ++Supported arguments: ++ ++--help prints this page ++ ++--with-testsuite=/some/dir/gcc/testsuite specify the testsuite directory ++--srcdir=/some/dir same as --with-testsuite=/some/dir/gcc/testsuite ++ [deduced from shell-script pathname] ++ ++--prefix=/some/dir use gdb, gcc, g++ and g77 from /some/dir/bin [PATH] ++--with-gdb=/some/dir/bin/gdb use specified gcc program [gdb] ++--with-gcc=/some/dir/bin/gcc use specified gcc program [gcc] ++--with-g++=/some/dir/bin/g++ use specified g++ program [g++] ++--target= run on specified target ++--tmpdir=/some/dir create temporaries and leave failed programs ++ at specified directory [.] ++ ++-- end of argument list; following arguments are passed to runtest ++EOF ++ exit ++ ;; ++ ++ --) shift; break;; ++ *) break;; ++ esac ++done ++ ++if test x"${testsuite+set}" != x"set" && test x"${srcdir+set}" != x"set"; then ++ file=$0 ++ while [ -h $file ]; do ++ file=`ls -l $file | sed s/'.* -> '//` ++ done ++ srcdir=`CDPATH=. && cd \`echo "$file" | sed 's,/*[^/]*$,,;s,^$,.,'\`/.. >/dev/null && ${PWDCMD-pwd}` ++fi ++ ++echo "gdb: "$GDB_UNDER_TEST ++ ++cat >site.exp <> site.exp ++ echo "set target_triplet spu-unknown-elf" >> site.exp ++ echo "set host_alias powerpc-unknown-linux-gnu" >> site.exp ++ echo "set host_triplet powerpc-unknown-linux-gnu" >> site.exp ++ echo "set build_triplet powerpc-unknown-linux-gnu" >> site.exp ++ } ++esac ++ ++runtest --tool gdb --tool_exec $GDB_UNDER_TEST ${1+"$@"} ++ ++exit 0 --- cell-gdb-6.6.50cvs20070623.orig/debian/patches/spu/diff-spu-gdb-fix-fortran_registers +++ cell-gdb-6.6.50cvs20070623/debian/patches/spu/diff-spu-gdb-fix-fortran_registers @@ -0,0 +1,64 @@ +diff -urNp src-orig/gdb/f-typeprint.c src/gdb/f-typeprint.c +--- src-orig/gdb/f-typeprint.c 2007-01-09 18:58:50.000000000 +0100 ++++ src/gdb/f-typeprint.c 2007-06-25 21:36:36.623838539 +0200 +@@ -33,6 +33,7 @@ + #include "gdbcore.h" + #include "target.h" + #include "f-lang.h" ++#include "c-lang.h" + + #include "gdb_string.h" + #include +@@ -406,6 +407,11 @@ f_type_print_base (struct type *type, st + fputs_filtered (TYPE_TAG_NAME (type), stream); + break; + ++ case TYPE_CODE_UNION: ++ /* Union is a unknown data type in Fortran. Call the C-specific valprint ++ routine to print unions. */ ++ c_type_print_base (type, stream, show, level); ++ + default_case: + default: + /* Handle types not explicitly handled by the other cases, +diff -urNp src-orig/gdb/f-valprint.c src/gdb/f-valprint.c +--- src-orig/gdb/f-valprint.c 2007-02-27 20:46:04.000000000 +0100 ++++ src/gdb/f-valprint.c 2007-06-25 21:36:36.628837820 +0200 +@@ -36,6 +36,7 @@ + #include "gdbcore.h" + #include "command.h" + #include "block.h" ++#include "c-lang.h" + + #if 0 + static int there_is_a_visible_common_named (char *); +@@ -377,6 +378,13 @@ f_val_print (struct type *type, const gd + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { ++ /* Union is a unknown data type in Fortran. Call the C-specific valprint ++ routine to print unions. */ ++ case TYPE_CODE_UNION: ++ c_val_print (type, valaddr, embedded_offset, address, stream, format, ++ deref_ref, recurse, pretty); ++ break; ++ + case TYPE_CODE_STRING: + f77_get_dynamic_length_of_aggregate (type); + LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0); +diff -urNp src-orig/gdb/Makefile.in src/gdb/Makefile.in +--- src-orig/gdb/Makefile.in 2007-06-18 17:46:36.000000000 +0200 ++++ src/gdb/Makefile.in 2007-06-25 21:36:36.640836093 +0200 +@@ -2018,10 +2018,10 @@ frv-tdep.o: frv-tdep.c $(defs_h) $(gdb_s + $(elf_bfd_h) $(elf_frv_h) $(osabi_h) $(infcall_h) $(frv_tdep_h) + f-typeprint.o: f-typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \ + $(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(target_h) \ +- $(f_lang_h) $(gdb_string_h) ++ $(f_lang_h) $(c_lang_h) $(gdb_string_h) + f-valprint.o: f-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \ + $(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \ +- $(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h) ++ $(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h) $(c_lang_h) + gcore.o: gcore.c $(defs_h) $(elf_bfd_h) $(infcall_h) $(inferior_h) \ + $(gdbcore_h) $(objfiles_h) $(symfile_h) $(cli_decode_h) \ + $(gdb_assert_h) --- cell-gdb-6.6.50cvs20070623.orig/debian/copyright +++ cell-gdb-6.6.50cvs20070623/debian/copyright @@ -0,0 +1,37 @@ +This package was debianized by Matthias Klose +on Mon, 14 May 2007 17:51:30 +0200. + +It was downloaded from + + http://www.bsc.es/plantillaH.php?cat_id=304 + +The Debian packaging is (C) 2007, Canonical Ltd, done by +Matthias Klose and is licensed under the GPL, +see `/usr/share/common-licenses/GPL'. + +License: + +GDB is Copyright (C) Free Software Foundation, Inc. + + 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. + +On Debian GNU/Linux systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses'. + +The file `gdb/doc/observer.texi' is normally distributed under the +GNU Free Documentation License, but certain lines from it are also +permitted to be distributed under the GPL. Only those lines are included in +this package. --- cell-gdb-6.6.50cvs20070623.orig/debian/README.Debian +++ cell-gdb-6.6.50cvs20070623/debian/README.Debian @@ -0,0 +1,6 @@ +cell-gdb for Debian +------------------- + + + + -- Matthias Klose Mon, 11 Jun 2007 11:45:46 +0200 --- cell-gdb-6.6.50cvs20070623.orig/debian/control +++ cell-gdb-6.6.50cvs20070623/debian/control @@ -0,0 +1,18 @@ +Source: cell-gdb +Section: devel +Priority: extra +Maintainer: Matthias Klose +Build-Depends: debhelper (>= 5), quilt, bzip2, texinfo, dejagnu, gettext, flex, bison, libncurses5-dev, libreadline5-dev, gcc-multilib [amd64 i386], ppu-g++ [powerpc], gfortran, ppu-gfortran [powerpc], libexpat1-dev, lib64expat1-dev [powerpc], lib64readline5-dev [powerpc] +Standards-Version: 3.7.2 + +Package: ppu-gdb +Architecture: amd64 i386 powerpc +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Combined debugger for Linux on Cell BE + GNU debugger for Cell Broadband Engine PPU/SPU. + +Package: spu-gdb +Architecture: amd64 i386 powerpc +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: SPU stand-alone debugger + GNU debugger for Cell Broadband Engine SPU (standalone). --- cell-gdb-6.6.50cvs20070623.orig/debian/compat +++ cell-gdb-6.6.50cvs20070623/debian/compat @@ -0,0 +1 @@ +5