OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/gnu-old/gdb-6.8/gdb/gdbserver
    from Rev 157 to Rev 816
    Reverse comparison

Rev 157 → Rev 816

/configure
0,0 → 1,5679
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
 
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
DUALCASE=1; export DUALCASE # for MKS sh
 
# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
fi
 
 
# Work around bugs in pre-3.0 UWIN ksh.
$as_unset ENV MAIL MAILPATH
PS1='$ '
PS2='> '
PS4='+ '
 
# NLS nuisances.
for as_var in \
LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
LC_TELEPHONE LC_TIME
do
if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
fi
done
 
# Required to use basename.
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
 
if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
 
 
# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
. : '\(.\)' 2>/dev/null ||
echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
/^X\/\(\/\/\)$/{ s//\1/; q; }
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
 
 
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
 
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conf$$.sh
echo "exit 0" >>conf$$.sh
chmod +x conf$$.sh
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conf$$.sh
fi
 
 
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" || {
# Find who we are. Look in the path if we contain no path at all
# relative or not.
case $0 in
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
 
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
{ echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
{ (exit 1); exit 1; }; }
fi
case $CONFIG_SHELL in
'')
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for as_base in sh bash ksh sh5; do
case $as_dir in
/*)
if ("$as_dir/$as_base" -c '
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
$as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
$as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
fi;;
esac
done
done
;;
esac
 
# Create $as_me.lineno as a copy of $as_myself, but with $LINENO
# uniformly replaced by the line number. The first 'sed' inserts a
# line-number line before each line; the second 'sed' does the real
# work. The second script uses 'N' to pair each line-number line
# with the numbered line, and appends trailing '-' during
# substitution so that $LINENO is not a special case at line end.
# (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
# second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
sed '=' <$as_myself |
sed '
N
s,$,-,
: loop
s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
t loop
s,-$,,
s,^['$as_cr_digits']*\n,,
' >$as_me.lineno &&
chmod +x $as_me.lineno ||
{ echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
{ (exit 1); exit 1; }; }
 
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensible to this).
. ./$as_me.lineno
# Exit status is that of the last command.
exit
}
 
 
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
 
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
 
rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
# We could just check for DJGPP; but this test a) works b) is more generic
# and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
if test -f conf$$.exe; then
# Don't use ln at all; we don't have any links
as_ln_s='cp -p'
else
as_ln_s='ln -s'
fi
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file
 
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
 
as_executable_p="test -f"
 
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" $as_nl"
 
# CDPATH.
$as_unset CDPATH
 
 
# Name of the host.
# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
exec 6>&1
 
#
# Initializations.
#
ac_default_prefix=/usr/local
ac_config_libobj_dir=.
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
 
# Maximum number of lines to put in a shell here document.
# This variable seems obsolete. It should probably be removed, and
# only ac_max_sed_lines should be used.
: ${ac_max_here_lines=38}
 
# Identity of this package.
PACKAGE_NAME=
PACKAGE_TARNAME=
PACKAGE_VERSION=
PACKAGE_STRING=
PACKAGE_BUGREPORT=
 
ac_unique_file="server.c"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#endif
#if HAVE_STRINGS_H
# include <strings.h>
#endif
#if HAVE_INTTYPES_H
# include <inttypes.h>
#else
# if HAVE_STDINT_H
# include <stdint.h>
# endif
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif"
 
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CPP EGREP RDYNAMIC GDBSERVER_DEPFILES GDBSERVER_LIBS USE_THREAD_DB srv_xmlbuiltin srv_xmlfiles srv_xmltarget LIBOBJS LTLIBOBJS'
ac_subst_files=''
 
# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
exec_prefix=NONE
no_create=
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
verbose=
x_includes=NONE
x_libraries=NONE
 
# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
 
ac_prev=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
 
ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
 
# Accept the important Cygnus configure options, so we can diagnose typos.
 
case $ac_option in
 
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir=$ac_optarg ;;
 
-build | --build | --buil | --bui | --bu)
ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build_alias=$ac_optarg ;;
 
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file=$ac_optarg ;;
 
--config-cache | -C)
cache_file=config.cache ;;
 
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
datadir=$ac_optarg ;;
 
-disable-* | --disable-*)
ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid feature name: $ac_feature" >&2
{ (exit 1); exit 1; }; }
ac_feature=`echo $ac_feature | sed 's/-/_/g'`
eval "enable_$ac_feature=no" ;;
 
-enable-* | --enable-*)
ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid feature name: $ac_feature" >&2
{ (exit 1); exit 1; }; }
ac_feature=`echo $ac_feature | sed 's/-/_/g'`
case $ac_option in
*=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
eval "enable_$ac_feature='$ac_optarg'" ;;
 
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix=$ac_optarg ;;
 
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
 
-help | --help | --hel | --he | -h)
ac_init_help=long ;;
-help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
ac_init_help=recursive ;;
-help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
ac_init_help=short ;;
 
-host | --host | --hos | --ho)
ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
host_alias=$ac_optarg ;;
 
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir=$ac_optarg ;;
 
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir=$ac_optarg ;;
 
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir=$ac_optarg ;;
 
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir=$ac_optarg ;;
 
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc | --lo)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir=$ac_optarg ;;
 
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir=$ac_optarg ;;
 
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
 
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c | -n)
no_create=yes ;;
 
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
 
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir=$ac_optarg ;;
 
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix=$ac_optarg ;;
 
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix=$ac_optarg ;;
 
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix=$ac_optarg ;;
 
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name=$ac_optarg ;;
 
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
 
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir=$ac_optarg ;;
 
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir=$ac_optarg ;;
 
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site=$ac_optarg ;;
 
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir=$ac_optarg ;;
 
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir=$ac_optarg ;;
 
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target_alias=$ac_optarg ;;
 
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
 
-version | --version | --versio | --versi | --vers | -V)
ac_init_version=: ;;
 
-with-* | --with-*)
ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid package name: $ac_package" >&2
{ (exit 1); exit 1; }; }
ac_package=`echo $ac_package| sed 's/-/_/g'`
case $ac_option in
*=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
eval "with_$ac_package='$ac_optarg'" ;;
 
-without-* | --without-*)
ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid package name: $ac_package" >&2
{ (exit 1); exit 1; }; }
ac_package=`echo $ac_package | sed 's/-/_/g'`
eval "with_$ac_package=no" ;;
 
--x)
# Obsolete; use --with-x.
with_x=yes ;;
 
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes=$ac_optarg ;;
 
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
 
-*) { echo "$as_me: error: unrecognized option: $ac_option
Try \`$0 --help' for more information." >&2
{ (exit 1); exit 1; }; }
;;
 
*=*)
ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
# Reject names that are not valid shell variable names.
expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid variable name: $ac_envvar" >&2
{ (exit 1); exit 1; }; }
ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
eval "$ac_envvar='$ac_optarg'"
export $ac_envvar ;;
 
*)
# FIXME: should be removed in autoconf 3.0.
echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
echo "$as_me: WARNING: invalid host type: $ac_option" >&2
: ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
;;
 
esac
done
 
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
{ echo "$as_me: error: missing argument to $ac_option" >&2
{ (exit 1); exit 1; }; }
fi
 
# Be sure to have absolute paths.
for ac_var in exec_prefix prefix
do
eval ac_val=$`echo $ac_var`
case $ac_val in
[\\/$]* | ?:[\\/]* | NONE | '' ) ;;
*) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
{ (exit 1); exit 1; }; };;
esac
done
 
# Be sure to have absolute paths.
for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
localstatedir libdir includedir oldincludedir infodir mandir
do
eval ac_val=$`echo $ac_var`
case $ac_val in
[\\/$]* | ?:[\\/]* ) ;;
*) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
{ (exit 1); exit 1; }; };;
esac
done
 
# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias
 
# FIXME: To remove some day.
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
fi
 
ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-
 
test "$silent" = yes && exec 6>/dev/null
 
 
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
ac_confdir=`(dirname "$0") 2>/dev/null ||
$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$0" : 'X\(//\)[^/]' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$0" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
{ (exit 1); exit 1; }; }
else
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
{ (exit 1); exit 1; }; }
fi
fi
(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
{ echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
{ (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
ac_env_build_alias_set=${build_alias+set}
ac_env_build_alias_value=$build_alias
ac_cv_env_build_alias_set=${build_alias+set}
ac_cv_env_build_alias_value=$build_alias
ac_env_host_alias_set=${host_alias+set}
ac_env_host_alias_value=$host_alias
ac_cv_env_host_alias_set=${host_alias+set}
ac_cv_env_host_alias_value=$host_alias
ac_env_target_alias_set=${target_alias+set}
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
ac_env_CC_set=${CC+set}
ac_env_CC_value=$CC
ac_cv_env_CC_set=${CC+set}
ac_cv_env_CC_value=$CC
ac_env_CFLAGS_set=${CFLAGS+set}
ac_env_CFLAGS_value=$CFLAGS
ac_cv_env_CFLAGS_set=${CFLAGS+set}
ac_cv_env_CFLAGS_value=$CFLAGS
ac_env_LDFLAGS_set=${LDFLAGS+set}
ac_env_LDFLAGS_value=$LDFLAGS
ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
ac_cv_env_LDFLAGS_value=$LDFLAGS
ac_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_env_CPPFLAGS_value=$CPPFLAGS
ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_cv_env_CPPFLAGS_value=$CPPFLAGS
ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP
 
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures this package to adapt to many kinds of systems.
 
Usage: $0 [OPTION]... [VAR=VALUE]...
 
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
 
Defaults for the options are specified in brackets.
 
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print \`checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or \`..']
 
_ACEOF
 
cat <<_ACEOF
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
 
By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.
 
For better control, use the options below.
 
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data [PREFIX/share]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--infodir=DIR info documentation [PREFIX/info]
--mandir=DIR man documentation [PREFIX/man]
_ACEOF
 
cat <<\_ACEOF
 
Program names:
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM run sed PROGRAM on installed program names
 
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--target=TARGET configure for building compilers for TARGET [HOST]
_ACEOF
fi
 
if test -n "$ac_init_help"; then
 
cat <<\_ACEOF
 
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
CPP C preprocessor
 
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
 
_ACEOF
fi
 
if test "$ac_init_help" = "recursive"; then
# If there are subdirs, report their specific --help.
ac_popdir=`pwd`
for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
test -d $ac_dir || continue
ac_builddir=.
 
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
 
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
 
# Do not use `cd foo && pwd` to compute absolute paths, because
# the directories may not exist.
case `pwd` in
.) ac_abs_builddir="$ac_dir";;
*)
case "$ac_dir" in
.) ac_abs_builddir=`pwd`;;
[\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
*) ac_abs_builddir=`pwd`/"$ac_dir";;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_builddir=${ac_top_builddir}.;;
*)
case ${ac_top_builddir}. in
.) ac_abs_top_builddir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
*) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_srcdir=$ac_srcdir;;
*)
case $ac_srcdir in
.) ac_abs_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
*) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_srcdir=$ac_top_srcdir;;
*)
case $ac_top_srcdir in
.) ac_abs_top_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
*) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
esac;;
esac
 
cd $ac_dir
# Check for guested configure; otherwise get Cygnus style configure.
if test -f $ac_srcdir/configure.gnu; then
echo
$SHELL $ac_srcdir/configure.gnu --help=recursive
elif test -f $ac_srcdir/configure; then
echo
$SHELL $ac_srcdir/configure --help=recursive
elif test -f $ac_srcdir/configure.ac ||
test -f $ac_srcdir/configure.in; then
echo
$ac_configure --help
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
cd $ac_popdir
done
fi
 
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
 
Copyright (C) 2003 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
exit 0
fi
exec 5>config.log
cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
 
It was created by $as_me, which was
generated by GNU Autoconf 2.59. Invocation command line was
 
$ $0 $@
 
_ACEOF
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##
 
hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
 
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
 
/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
 
_ASUNAME
 
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
echo "PATH: $as_dir"
done
 
} >&5
 
cat >&5 <<_ACEOF
 
 
## ----------- ##
## Core tests. ##
## ----------- ##
 
_ACEOF
 
 
# Keep a trace of the command line.
# Strip out --no-create and --no-recursion so they do not pile up.
# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
ac_sep=
ac_must_keep_next=false
for ac_pass in 1 2
do
for ac_arg
do
case $ac_arg in
-no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
continue ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
case $ac_pass in
1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
2)
ac_configure_args1="$ac_configure_args1 '$ac_arg'"
if test $ac_must_keep_next = true; then
ac_must_keep_next=false # Got value, back to normal.
else
case $ac_arg in
*=* | --config-cache | -C | -disable-* | --disable-* \
| -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
| -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
| -with-* | --with-* | -without-* | --without-* | --x)
case "$ac_configure_args0 " in
"$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
esac
;;
-* ) ac_must_keep_next=true ;;
esac
fi
ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
# Get rid of the leading space.
ac_sep=" "
;;
esac
done
done
$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
 
# When interrupted or exit'd, cleanup temporary files, and complete
# config.log. We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Be sure not to use single quotes in there, as some shells,
# such as our DU 5.0 friend, will then `close' the trap.
trap 'exit_status=$?
# Save into config.log some information that might help in debugging.
{
echo
 
cat <<\_ASBOX
## ---------------- ##
## Cache variables. ##
## ---------------- ##
_ASBOX
echo
# The following way of writing the cache mishandles newlines in values,
{
(set) 2>&1 |
case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
*ac_space=\ *)
sed -n \
"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
;;
*)
sed -n \
"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
}
echo
 
cat <<\_ASBOX
## ----------------- ##
## Output variables. ##
## ----------------- ##
_ASBOX
echo
for ac_var in $ac_subst_vars
do
eval ac_val=$`echo $ac_var`
echo "$ac_var='"'"'$ac_val'"'"'"
done | sort
echo
 
if test -n "$ac_subst_files"; then
cat <<\_ASBOX
## ------------- ##
## Output files. ##
## ------------- ##
_ASBOX
echo
for ac_var in $ac_subst_files
do
eval ac_val=$`echo $ac_var`
echo "$ac_var='"'"'$ac_val'"'"'"
done | sort
echo
fi
 
if test -s confdefs.h; then
cat <<\_ASBOX
## ----------- ##
## confdefs.h. ##
## ----------- ##
_ASBOX
echo
sed "/^$/d" confdefs.h | sort
echo
fi
test "$ac_signal" != 0 &&
echo "$as_me: caught signal $ac_signal"
echo "$as_me: exit $exit_status"
} >&5
rm -f core *.core &&
rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
done
ac_signal=0
 
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo >confdefs.h
 
# Predefined preprocessor variables.
 
cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF
 
 
cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF
 
 
cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF
 
 
cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF
 
 
cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF
 
 
# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
{ echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file"
fi
done
 
if test -r "$cache_file"; then
# Some versions of bash will fail to source /dev/null (special
# files actually), so we avoid doing that.
if test -f "$cache_file"; then
{ echo "$as_me:$LINENO: loading cache $cache_file" >&5
echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
[\\/]* | ?:[\\/]* ) . $cache_file;;
*) . ./$cache_file;;
esac
fi
else
{ echo "$as_me:$LINENO: creating cache $cache_file" >&5
echo "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
 
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in `(set) 2>&1 |
sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
eval ac_old_set=\$ac_cv_env_${ac_var}_set
eval ac_new_set=\$ac_env_${ac_var}_set
eval ac_old_val="\$ac_cv_env_${ac_var}_value"
eval ac_new_val="\$ac_env_${ac_var}_value"
case $ac_old_set,$ac_new_set in
set,)
{ echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
ac_cache_corrupted=: ;;
,set)
{ echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
ac_cache_corrupted=: ;;
,);;
*)
if test "x$ac_old_val" != "x$ac_new_val"; then
{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
{ echo "$as_me:$LINENO: former value: $ac_old_val" >&5
echo "$as_me: former value: $ac_old_val" >&2;}
{ echo "$as_me:$LINENO: current value: $ac_new_val" >&5
echo "$as_me: current value: $ac_new_val" >&2;}
ac_cache_corrupted=:
fi;;
esac
# Pass precious variables to config.status.
if test "$ac_new_set" = set; then
case $ac_new_val in
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
*) ac_arg=$ac_var=$ac_new_val ;;
esac
case " $ac_configure_args " in
*" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
*) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
esac
fi
done
if $ac_cache_corrupted; then
{ echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
echo "$as_me: error: changes in the environment can compromise the build" >&2;}
{ { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
{ (exit 1); exit 1; }; }
fi
 
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ac_config_headers="$ac_config_headers config.h:config.in"
 
 
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
CC=$ac_ct_CC
else
CC="$ac_cv_prog_CC"
fi
 
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
CC=$ac_ct_CC
else
CC="$ac_cv_prog_CC"
fi
 
fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# != 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
for ac_prog in cl
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
test -n "$CC" && break
done
fi
if test -z "$CC"; then
ac_ct_CC=$CC
for ac_prog in cl
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
 
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
 
test -n "$ac_ct_CC" && break
done
 
CC=$ac_ct_CC
fi
 
fi
 
 
test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
See \`config.log' for more details." >&5
echo "$as_me: error: no acceptable C compiler found in \$PATH
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
 
# Provide some information about the compiler.
echo "$as_me:$LINENO:" \
"checking for C compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
(eval $ac_compiler --version </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
(eval $ac_compiler -v </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
(eval $ac_compiler -V </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
 
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
int
main ()
{
 
;
return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
(eval $ac_link_default) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
# Find the output, starting from the most likely. This scheme is
# not robust to junk in `.', hence go to wildcards (a.*) only as a last
# resort.
 
# Be careful to initialize this variable, since it used to be cached.
# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
ac_cv_exeext=
# b.out is created by i960 compilers.
for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
;;
conftest.$ac_ext )
# This is the source file.
;;
[ab].out )
# We found the default executable, but exeext='' is most
# certainly right.
break;;
*.* )
ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
# FIXME: I believe we export ac_cv_exeext for Libtool,
# but it would be cool to find out if it's true. Does anybody
# maintain Libtool? --akim.
export ac_cv_exeext
break;;
* )
break;;
esac
done
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
See \`config.log' for more details." >&5
echo "$as_me: error: C compiler cannot create executables
See \`config.log' for more details." >&2;}
{ (exit 77); exit 77; }; }
fi
 
ac_exeext=$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_file" >&5
echo "${ECHO_T}$ac_file" >&6
 
# Check the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether the C compiler works" >&5
echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
# If not cross compiling, check that we can run a simple program.
if test "$cross_compiling" != yes; then
if { ac_try='./$ac_file'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
cross_compiling=no
else
if test "$cross_compiling" = maybe; then
cross_compiling=yes
else
{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details." >&5
echo "$as_me: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
fi
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
 
rm -f a.out a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
# Check the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $cross_compiling" >&5
echo "${ECHO_T}$cross_compiling" >&6
 
echo "$as_me:$LINENO: checking for suffix of executables" >&5
echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
# If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
export ac_cv_exeext
break;;
* ) break;;
esac
done
else
{ { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details." >&5
echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
 
rm -f conftest$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
echo "${ECHO_T}$ac_cv_exeext" >&6
 
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
echo "$as_me:$LINENO: checking for suffix of object files" >&5
echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
if test "${ac_cv_objext+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
int
main ()
{
 
;
return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
See \`config.log' for more details." >&5
echo "$as_me: error: cannot compute suffix of object files: cannot compile
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
 
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
echo "${ECHO_T}$ac_cv_objext" >&6
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
if test "${ac_cv_c_compiler_gnu+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
int
main ()
{
#ifndef __GNUC__
choke me
#endif
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_compiler_gnu=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
fi
echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
GCC=`test $ac_compiler_gnu = yes && echo yes`
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
CFLAGS="-g"
echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
if test "${ac_cv_prog_cc_g+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
int
main ()
{
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_prog_cc_g=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_cv_prog_cc_g=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
CFLAGS="-O2"
else
CFLAGS=
fi
fi
echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
if test "${ac_cv_prog_cc_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_prog_cc_stdc=no
ac_save_CC=$CC
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
char **p;
int i;
{
return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
char *s;
va_list v;
va_start (v,p);
s = g (p, va_arg (v,int));
va_end (v);
return s;
}
 
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
function prototypes and stuff, but not '\xHH' hex character constants.
These don't provoke an error unfortunately, instead are silently treated
as 'x'. The following induces an error, until -std1 is added to get
proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
array size at least. It's necessary to write '\x00'==0 to get something
that's true only with -std1. */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];
 
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
;
return 0;
}
_ACEOF
# Don't try gcc -ansi; that turns off useful extensions and
# breaks some systems' header files.
# AIX -qlanglvl=ansi
# Ultrix and OSF/1 -std1
# HP-UX 10.20 and later -Ae
# HP-UX older versions -Aa -D_HPUX_SOURCE
# SVR4 -Xc -D__EXTENSIONS__
for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
CC="$ac_save_CC $ac_arg"
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_prog_cc_stdc=$ac_arg
break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
fi
rm -f conftest.err conftest.$ac_objext
done
rm -f conftest.$ac_ext conftest.$ac_objext
CC=$ac_save_CC
 
fi
 
case "x$ac_cv_prog_cc_stdc" in
x|xno)
echo "$as_me:$LINENO: result: none needed" >&5
echo "${ECHO_T}none needed" >&6 ;;
*)
echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
CC="$CC $ac_cv_prog_cc_stdc" ;;
esac
 
# Some people use a C++ compiler to compile C. Since we use `exit',
# in C++ we need to declare it. In case someone uses the same compiler
# for both compiling C and C++ we need to have the C++ compiler decide
# the declaration of exit, since it's the most demanding environment.
cat >conftest.$ac_ext <<_ACEOF
#ifndef __cplusplus
choke me
#endif
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
for ac_declaration in \
'' \
'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \
'extern "C" void exit (int);' \
'void exit (int);'
do
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_declaration
#include <stdlib.h>
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
continue
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_declaration
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
echo '#ifdef __cplusplus' >>confdefs.h
echo $ac_declaration >>confdefs.h
echo '#endif' >>confdefs.h
fi
 
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
cat >>confdefs.h <<\_ACEOF
#define _GNU_SOURCE 1
_ACEOF
 
 
 
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
elif test -f $ac_dir/shtool; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/shtool install -c"
break
fi
done
if test -z "$ac_aux_dir"; then
{ { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
{ (exit 1); exit 1; }; }
fi
ac_config_guess="$SHELL $ac_aux_dir/config.guess"
ac_config_sub="$SHELL $ac_aux_dir/config.sub"
ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
 
# Make sure we can run config.sub.
$ac_config_sub sun4 >/dev/null 2>&1 ||
{ { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
echo "$as_me: error: cannot run $ac_config_sub" >&2;}
{ (exit 1); exit 1; }; }
 
echo "$as_me:$LINENO: checking build system type" >&5
echo $ECHO_N "checking build system type... $ECHO_C" >&6
if test "${ac_cv_build+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_build_alias=$build_alias
test -z "$ac_cv_build_alias" &&
ac_cv_build_alias=`$ac_config_guess`
test -z "$ac_cv_build_alias" &&
{ { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
{ (exit 1); exit 1; }; }
ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
{ { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
{ (exit 1); exit 1; }; }
 
fi
echo "$as_me:$LINENO: result: $ac_cv_build" >&5
echo "${ECHO_T}$ac_cv_build" >&6
build=$ac_cv_build
build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 
 
echo "$as_me:$LINENO: checking host system type" >&5
echo $ECHO_N "checking host system type... $ECHO_C" >&6
if test "${ac_cv_host+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_host_alias=$host_alias
test -z "$ac_cv_host_alias" &&
ac_cv_host_alias=$ac_cv_build_alias
ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
{ { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
{ (exit 1); exit 1; }; }
 
fi
echo "$as_me:$LINENO: result: $ac_cv_host" >&5
echo "${ECHO_T}$ac_cv_host" >&6
host=$ac_cv_host
host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 
 
echo "$as_me:$LINENO: checking target system type" >&5
echo $ECHO_N "checking target system type... $ECHO_C" >&6
if test "${ac_cv_target+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_target_alias=$target_alias
test "x$ac_cv_target_alias" = "x" &&
ac_cv_target_alias=$ac_cv_host_alias
ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
{ { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
{ (exit 1); exit 1; }; }
 
fi
echo "$as_me:$LINENO: result: $ac_cv_target" >&5
echo "${ECHO_T}$ac_cv_target" >&6
target=$ac_cv_target
target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 
 
# The aliases save the names the user supplied, while $host etc.
# will get canonicalized.
test -n "$target_alias" &&
test "$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, &&
program_prefix=${target_alias}-
 
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AmigaOS /C/install, which installs bootblocks on floppy discs
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# OS/2's system install, which has a completely different semantic
# ./install, which can be erroneously created by make from ./install.sh.
echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
if test -z "$INSTALL"; then
if test "${ac_cv_path_install+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
# Account for people who put trailing slashes in PATH elements.
case $as_dir/ in
./ | .// | /cC/* | \
/etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
/usr/ucb/* ) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
elif test $ac_prog = install &&
grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# program-specific install script used by HP pwplus--don't use.
:
else
ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
break 3
fi
fi
done
done
;;
esac
done
 
 
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL=$ac_cv_path_install
else
# As a last resort, use the slow shell script. We don't cache a
# path for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the path is relative.
INSTALL=$ac_install_sh
fi
fi
echo "$as_me:$LINENO: result: $INSTALL" >&5
echo "${ECHO_T}$INSTALL" >&6
 
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
 
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
test "$program_prefix" != NONE &&
program_transform_name="s,^,$program_prefix,;$program_transform_name"
# Use a double $ so make ignores it.
test "$program_suffix" != NONE &&
program_transform_name="s,\$,$program_suffix,;$program_transform_name"
# Double any \ or $. echo might interpret backslashes.
# By default was `s,x,x', remove it if useless.
cat <<\_ACEOF >conftest.sed
s/[\\$]/&&/g;s/;s,x,x,$//
_ACEOF
program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
rm conftest.sed
 
 
 
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
if test "${ac_cv_prog_CPP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
# Double quotes because CPP needs to be expanded
for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
do
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
# <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext
 
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
# Broken: success on invalid input.
continue
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext
 
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
break
fi
 
done
ac_cv_prog_CPP=$CPP
 
fi
CPP=$ac_cv_prog_CPP
else
ac_cv_prog_CPP=$CPP
fi
echo "$as_me:$LINENO: result: $CPP" >&5
echo "${ECHO_T}$CPP" >&6
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
# <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext
 
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
# Broken: success on invalid input.
continue
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext
 
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
:
else
{ { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&5
echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
 
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
echo "$as_me:$LINENO: checking for egrep" >&5
echo $ECHO_N "checking for egrep... $ECHO_C" >&6
if test "${ac_cv_prog_egrep+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if echo a | (grep -E '(a|b)') >/dev/null 2>&1
then ac_cv_prog_egrep='grep -E'
else ac_cv_prog_egrep='egrep'
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
echo "${ECHO_T}$ac_cv_prog_egrep" >&6
EGREP=$ac_cv_prog_egrep
 
 
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
 
int
main ()
{
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_header_stdc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_cv_header_stdc=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <string.h>
 
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "memchr" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
fi
rm -f conftest*
 
fi
 
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
 
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "free" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
fi
rm -f conftest*
 
fi
 
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then
:
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <ctype.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
(('a' <= (c) && (c) <= 'i') \
|| ('j' <= (c) && (c) <= 'r') \
|| ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif
 
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int
main ()
{
int i;
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
|| toupper (i) != TOUPPER (i))
exit(2);
exit (0);
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
( exit $ac_status )
ac_cv_header_stdc=no
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
echo "${ECHO_T}$ac_cv_header_stdc" >&6
if test $ac_cv_header_stdc = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define STDC_HEADERS 1
_ACEOF
 
fi
 
 
# On IRIX 5.3, sys/types and inttypes.h are conflicting.
 
 
 
 
 
 
 
 
 
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
 
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_Header=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
eval "$as_ac_Header=no"
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
 
fi
 
done
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
for ac_header in sgtty.h termio.h termios.h sys/reg.h string.h proc_service.h sys/procfs.h thread_db.h linux/elf.h stdlib.h unistd.h errno.h fcntl.h signal.h sys/file.h malloc.h sys/ioctl.h netinet/in.h sys/socket.h netdb.h netinet/tcp.h arpa/inet.h sys/wait.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
 
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
 
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to the AC_PACKAGE_NAME lists. ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
 
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
 
fi
 
done
 
 
 
 
for ac_func in pread pwrite pread64
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
 
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
 
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
 
#undef $ac_func
 
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
char (*f) () = $ac_func;
#endif
#ifdef __cplusplus
}
#endif
 
int
main ()
{
return f != $ac_func;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
eval "$as_ac_var=no"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
 
fi
done
 
 
have_errno=no
echo "$as_me:$LINENO: checking for errno" >&5
echo $ECHO_N "checking for errno... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#if HAVE_ERRNO_H
#include <errno.h>
#endif
int
main ()
{
static int x; x = errno;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - in errno.h" >&5
echo "${ECHO_T}yes - in errno.h" >&6;
cat >>confdefs.h <<\_ACEOF
#define HAVE_ERRNO 1
_ACEOF
have_errno=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test $have_errno = no; then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#if HAVE_ERRNO_H
#include <errno.h>
#endif
int
main ()
{
extern int errno; static int x; x = errno;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - must define" >&5
echo "${ECHO_T}yes - must define" >&6;
cat >>confdefs.h <<\_ACEOF
#define HAVE_ERRNO 1
_ACEOF
 
cat >>confdefs.h <<\_ACEOF
#define MUST_DEFINE_ERRNO 1
_ACEOF
 
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
 
echo "$as_me:$LINENO: checking whether strerror is declared" >&5
echo $ECHO_N "checking whether strerror is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_strerror+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
#ifndef strerror
char *p = (char *) strerror;
#endif
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_have_decl_strerror=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_cv_have_decl_strerror=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_decl_strerror" >&5
echo "${ECHO_T}$ac_cv_have_decl_strerror" >&6
if test $ac_cv_have_decl_strerror = yes; then
 
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_STRERROR 1
_ACEOF
 
 
else
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_STRERROR 0
_ACEOF
 
 
fi
echo "$as_me:$LINENO: checking whether perror is declared" >&5
echo $ECHO_N "checking whether perror is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_perror+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
#ifndef perror
char *p = (char *) perror;
#endif
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_have_decl_perror=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_cv_have_decl_perror=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_decl_perror" >&5
echo "${ECHO_T}$ac_cv_have_decl_perror" >&6
if test $ac_cv_have_decl_perror = yes; then
 
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PERROR 1
_ACEOF
 
 
else
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PERROR 0
_ACEOF
 
 
fi
 
 
 
echo "$as_me:$LINENO: checking for socklen_t" >&5
echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
if test "${ac_cv_type_socklen_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/socket.h>
 
 
int
main ()
{
if ((socklen_t *) 0)
return 0;
if (sizeof (socklen_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_socklen_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
ac_cv_type_socklen_t=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5
echo "${ECHO_T}$ac_cv_type_socklen_t" >&6
if test $ac_cv_type_socklen_t = yes; then
 
cat >>confdefs.h <<_ACEOF
#define HAVE_SOCKLEN_T 1
_ACEOF
 
 
fi
 
 
# Check for various supplementary target information (beyond the
# triplet) which might affect the choices in configure.srv.
case "${target}" in
arm*-*-linux*)
echo "$as_me:$LINENO: checking if iWMMXt is selected" >&5
echo $ECHO_N "checking if iWMMXt is selected... $ECHO_C" >&6
if test "${gdb_cv_arm_iwmmxt+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CFLAGS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#ifdef __IWMMXT__
got it
#endif
 
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "got it" >/dev/null 2>&1; then
gdb_cv_arm_iwmmxt=yes
else
gdb_cv_arm_iwmmxt=no
fi
rm -f conftest*
 
CPPFLAGS="$save_CPPFLAGS"
fi
echo "$as_me:$LINENO: result: $gdb_cv_arm_iwmmxt" >&5
echo "${ECHO_T}$gdb_cv_arm_iwmmxt" >&6
;;
powerpc*-*-*)
echo "$as_me:$LINENO: checking if Altivec is selected" >&5
echo $ECHO_N "checking if Altivec is selected... $ECHO_C" >&6
if test "${gdb_cv_ppc_altivec+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CFLAGS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#ifdef __ALTIVEC__
got it
#endif
 
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "got it" >/dev/null 2>&1; then
gdb_cv_ppc_altivec=yes
else
gdb_cv_ppc_altivec=no
fi
rm -f conftest*
 
CPPFLAGS="$save_CPPFLAGS"
fi
echo "$as_me:$LINENO: result: $gdb_cv_ppc_altivec" >&5
echo "${ECHO_T}$gdb_cv_ppc_altivec" >&6
echo "$as_me:$LINENO: checking if SPE is selected" >&5
echo $ECHO_N "checking if SPE is selected... $ECHO_C" >&6
if test "${gdb_cv_ppc_spe+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CFLAGS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#ifdef __SPE__
got it
#endif
 
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "got it" >/dev/null 2>&1; then
gdb_cv_ppc_spe=yes
else
gdb_cv_ppc_spe=no
fi
rm -f conftest*
 
CPPFLAGS="$save_CPPFLAGS"
fi
echo "$as_me:$LINENO: result: $gdb_cv_ppc_spe" >&5
echo "${ECHO_T}$gdb_cv_ppc_spe" >&6
;;
esac
 
. ${srcdir}/configure.srv
 
if test "${srv_mingwce}" = "yes"; then
LIBS="$LIBS -lws2"
elif test "${srv_mingw}" = "yes"; then
LIBS="$LIBS -lwsock32"
fi
 
if test "${srv_mingw}" = "yes"; then
 
cat >>confdefs.h <<\_ACEOF
#define USE_WIN32API 1
_ACEOF
 
fi
 
if test "${srv_linux_usrregs}" = "yes"; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_LINUX_USRREGS 1
_ACEOF
 
fi
 
if test "${srv_linux_regsets}" = "yes"; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_LINUX_REGSETS 1
_ACEOF
 
 
echo "$as_me:$LINENO: checking for PTRACE_GETREGS" >&5
echo $ECHO_N "checking for PTRACE_GETREGS... $ECHO_C" >&6
if test "${gdbsrv_cv_have_ptrace_getregs+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/ptrace.h>
int
main ()
{
PTRACE_GETREGS;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
gdbsrv_cv_have_ptrace_getregs=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
gdbsrv_cv_have_ptrace_getregs=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
echo "$as_me:$LINENO: result: $gdbsrv_cv_have_ptrace_getregs" >&5
echo "${ECHO_T}$gdbsrv_cv_have_ptrace_getregs" >&6
if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_PTRACE_GETREGS 1
_ACEOF
 
fi
 
echo "$as_me:$LINENO: checking for PTRACE_GETFPXREGS" >&5
echo $ECHO_N "checking for PTRACE_GETFPXREGS... $ECHO_C" >&6
if test "${gdbsrv_cv_have_ptrace_getfpxregs+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/ptrace.h>
int
main ()
{
PTRACE_GETFPXREGS;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
gdbsrv_cv_have_ptrace_getfpxregs=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
gdbsrv_cv_have_ptrace_getfpxregs=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
echo "$as_me:$LINENO: result: $gdbsrv_cv_have_ptrace_getfpxregs" >&5
echo "${ECHO_T}$gdbsrv_cv_have_ptrace_getfpxregs" >&6
if test "${gdbsrv_cv_have_ptrace_getfpxregs}" = "yes"; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_PTRACE_GETFPXREGS 1
_ACEOF
 
fi
fi
 
if test "$ac_cv_header_sys_procfs_h" = yes; then
echo "$as_me:$LINENO: checking for lwpid_t in sys/procfs.h" >&5
echo $ECHO_N "checking for lwpid_t in sys/procfs.h... $ECHO_C" >&6
if test "${bfd_cv_have_sys_procfs_type_lwpid_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#define _SYSCALL32
#include <sys/procfs.h>
int
main ()
{
lwpid_t avar
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
bfd_cv_have_sys_procfs_type_lwpid_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
bfd_cv_have_sys_procfs_type_lwpid_t=no
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
if test $bfd_cv_have_sys_procfs_type_lwpid_t = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_LWPID_T 1
_ACEOF
 
fi
echo "$as_me:$LINENO: result: $bfd_cv_have_sys_procfs_type_lwpid_t" >&5
echo "${ECHO_T}$bfd_cv_have_sys_procfs_type_lwpid_t" >&6
 
echo "$as_me:$LINENO: checking for psaddr_t in sys/procfs.h" >&5
echo $ECHO_N "checking for psaddr_t in sys/procfs.h... $ECHO_C" >&6
if test "${bfd_cv_have_sys_procfs_type_psaddr_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#define _SYSCALL32
#include <sys/procfs.h>
int
main ()
{
psaddr_t avar
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
bfd_cv_have_sys_procfs_type_psaddr_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
bfd_cv_have_sys_procfs_type_psaddr_t=no
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
if test $bfd_cv_have_sys_procfs_type_psaddr_t = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_PSADDR_T 1
_ACEOF
 
fi
echo "$as_me:$LINENO: result: $bfd_cv_have_sys_procfs_type_psaddr_t" >&5
echo "${ECHO_T}$bfd_cv_have_sys_procfs_type_psaddr_t" >&6
 
echo "$as_me:$LINENO: checking for prgregset_t in sys/procfs.h" >&5
echo $ECHO_N "checking for prgregset_t in sys/procfs.h... $ECHO_C" >&6
if test "${bfd_cv_have_sys_procfs_type_prgregset_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#define _SYSCALL32
#include <sys/procfs.h>
int
main ()
{
prgregset_t avar
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
bfd_cv_have_sys_procfs_type_prgregset_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
bfd_cv_have_sys_procfs_type_prgregset_t=no
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
if test $bfd_cv_have_sys_procfs_type_prgregset_t = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_PRGREGSET_T 1
_ACEOF
 
fi
echo "$as_me:$LINENO: result: $bfd_cv_have_sys_procfs_type_prgregset_t" >&5
echo "${ECHO_T}$bfd_cv_have_sys_procfs_type_prgregset_t" >&6
 
echo "$as_me:$LINENO: checking for elf_fpregset_t in sys/procfs.h" >&5
echo $ECHO_N "checking for elf_fpregset_t in sys/procfs.h... $ECHO_C" >&6
if test "${bfd_cv_have_sys_procfs_type_elf_fpregset_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
#define _SYSCALL32
#include <sys/procfs.h>
int
main ()
{
elf_fpregset_t avar
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
bfd_cv_have_sys_procfs_type_elf_fpregset_t=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
bfd_cv_have_sys_procfs_type_elf_fpregset_t=no
 
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
 
if test $bfd_cv_have_sys_procfs_type_elf_fpregset_t = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_ELF_FPREGSET_T 1
_ACEOF
 
fi
echo "$as_me:$LINENO: result: $bfd_cv_have_sys_procfs_type_elf_fpregset_t" >&5
echo "${ECHO_T}$bfd_cv_have_sys_procfs_type_elf_fpregset_t" >&6
 
fi
 
srv_thread_depfiles=
srv_libs=
USE_THREAD_DB=
 
if test "$srv_linux_thread_db" = "yes"; then
echo "$as_me:$LINENO: checking for libthread_db" >&5
echo $ECHO_N "checking for libthread_db... $ECHO_C" >&6
if test "${srv_cv_thread_db+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
old_LIBS="$LIBS"
LIBS="$LIBS -lthread_db"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void ps_pglobal_lookup() {}
void ps_pdread() {}
void ps_pdwrite() {}
void ps_lgetregs() {}
void ps_lsetregs() {}
void ps_lgetfpregs() {}
void ps_lsetfpregs() {}
void ps_get_thread_area() {}
void ps_getpid() {}
int
main ()
{
td_ta_new();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
srv_cv_thread_db="-lthread_db"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
srv_cv_thread_db=no
 
if test "$prefix" = "/usr" || test "$prefix" = "NONE"; then
thread_db="/lib/libthread_db.so.1"
else
thread_db='$prefix/lib/libthread_db.so.1'
fi
LIBS="$old_LIBS `eval echo "$thread_db"`"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void ps_pglobal_lookup() {}
void ps_pdread() {}
void ps_pdwrite() {}
void ps_lgetregs() {}
void ps_lsetregs() {}
void ps_lgetfpregs() {}
void ps_lsetfpregs() {}
void ps_get_thread_area() {}
void ps_getpid() {}
int
main ()
{
td_ta_new();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
srv_cv_thread_db="$thread_db"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
srv_cv_thread_db=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
 
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS="$old_LIBS"
 
fi
echo "$as_me:$LINENO: result: $srv_cv_thread_db" >&5
echo "${ECHO_T}$srv_cv_thread_db" >&6
if test "$srv_cv_thread_db" = no; then
{ echo "$as_me:$LINENO: WARNING: Could not find libthread_db." >&5
echo "$as_me: WARNING: Could not find libthread_db." >&2;}
{ echo "$as_me:$LINENO: WARNING: Disabling thread support in gdbserver." >&5
echo "$as_me: WARNING: Disabling thread support in gdbserver." >&2;}
srv_linux_thread_db=no
else
srv_libs="$srv_cv_thread_db"
echo "$as_me:$LINENO: checking for thread_db_tls_get_addr" >&5
echo $ECHO_N "checking for thread_db_tls_get_addr... $ECHO_C" >&6
if test "${srv_cv_tls_get_addr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
old_LIBS="$LIBS"
LIBS="$LIBS $srv_cv_thread_db"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void ps_pglobal_lookup() {}
void ps_pdread() {}
void ps_pdwrite() {}
void ps_lgetregs() {}
void ps_lsetregs() {}
void ps_lgetfpregs() {}
void ps_lsetfpregs() {}
void ps_get_thread_area() {}
void ps_getpid() {}
int
main ()
{
td_thr_tls_get_addr();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
srv_cv_tls_get_addr=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
srv_cv_tls_get_addr=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS="$old_LIBS"
 
fi
echo "$as_me:$LINENO: result: $srv_cv_tls_get_addr" >&5
echo "${ECHO_T}$srv_cv_tls_get_addr" >&6
fi
old_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -rdynamic"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
 
int
main ()
{
 
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
RDYNAMIC=-rdynamic
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
RDYNAMIC=
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
 
LDFLAGS="$old_LDFLAGS"
fi
 
if test "$srv_linux_thread_db" = "yes"; then
srv_thread_depfiles="thread-db.o proc-service.o"
USE_THREAD_DB="-DUSE_THREAD_DB"
echo "$as_me:$LINENO: checking for TD_VERSION" >&5
echo $ECHO_N "checking for TD_VERSION... $ECHO_C" >&6
if test "${gdbsrv_cv_have_td_version+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <thread_db.h>
int
main ()
{
TD_VERSION;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
gdbsrv_cv_have_td_version=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
 
gdbsrv_cv_have_td_version=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $gdbsrv_cv_have_td_version" >&5
echo "${ECHO_T}$gdbsrv_cv_have_td_version" >&6
if test $gdbsrv_cv_have_td_version = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_TD_VERSION 1
_ACEOF
 
fi
 
if test "$srv_cv_tls_get_addr" = yes; then
 
cat >>confdefs.h <<\_ACEOF
#define HAVE_TD_THR_TLS_GET_ADDR 1
_ACEOF
 
fi
fi
 
if test "$srv_xmltarget" != ""; then
srv_xmltarget="\$(XML_DIR)/$srv_xmltarget"
srv_xmlbuiltin="xml-builtin.o"
 
cat >>confdefs.h <<\_ACEOF
#define USE_XML 1
_ACEOF
 
 
tmp_xmlfiles=$srv_xmlfiles
srv_xmlfiles="target.xml"
for f in $tmp_xmlfiles; do
srv_xmlfiles="$srv_xmlfiles \$(XML_DIR)/$f"
done
fi
 
GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_hostio_err_objs $srv_thread_depfiles"
GDBSERVER_LIBS="$srv_libs"
 
 
 
 
 
 
 
 
ac_config_files="$ac_config_files Makefile"
ac_config_commands="$ac_config_commands default"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems. If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
 
_ACEOF
 
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
{
(set) 2>&1 |
case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote
# substitution turns \\\\ into \\, and sed turns \\ into \).
sed -n \
"s/'/'\\\\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n \
"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
} |
sed '
t clear
: clear
s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
t end
/^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
: end' >>confcache
if diff $cache_file confcache >/dev/null 2>&1; then :; else
if test -w $cache_file; then
test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
cat confcache >$cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
 
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
# VPATH may cause trouble with some makes, so we remove $(srcdir),
# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=/{
s/:*\$(srcdir):*/:/;
s/:*\${srcdir}:*/:/;
s/:*@srcdir@:*/:/;
s/^\([^=]*=[ ]*\):*/\1/;
s/:*$//;
s/^[^=]*=[ ]*$//;
}'
fi
 
DEFS=-DHAVE_CONFIG_H
 
ac_libobjs=
ac_ltlibobjs=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_i=`echo "$ac_i" |
sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
# 2. Add them.
ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs
 
LTLIBOBJS=$ac_ltlibobjs
 
 
 
: ${CONFIG_STATUS=./config.status}
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
echo "$as_me: creating $CONFIG_STATUS" >&6;}
cat >$CONFIG_STATUS <<_ACEOF
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
 
debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=\${CONFIG_SHELL-$SHELL}
_ACEOF
 
cat >>$CONFIG_STATUS <<\_ACEOF
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
 
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
DUALCASE=1; export DUALCASE # for MKS sh
 
# Support unset when possible.
if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
fi
 
 
# Work around bugs in pre-3.0 UWIN ksh.
$as_unset ENV MAIL MAILPATH
PS1='$ '
PS2='> '
PS4='+ '
 
# NLS nuisances.
for as_var in \
LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
LC_TELEPHONE LC_TIME
do
if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
fi
done
 
# Required to use basename.
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
 
if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
 
 
# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
. : '\(.\)' 2>/dev/null ||
echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
/^X\/\(\/\/\)$/{ s//\1/; q; }
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
 
 
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
 
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conf$$.sh
echo "exit 0" >>conf$$.sh
chmod +x conf$$.sh
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conf$$.sh
fi
 
 
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" || {
# Find who we are. Look in the path if we contain no path at all
# relative or not.
case $0 in
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
 
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi
case $CONFIG_SHELL in
'')
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for as_base in sh bash ksh sh5; do
case $as_dir in
/*)
if ("$as_dir/$as_base" -c '
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
$as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
$as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
fi;;
esac
done
done
;;
esac
 
# Create $as_me.lineno as a copy of $as_myself, but with $LINENO
# uniformly replaced by the line number. The first 'sed' inserts a
# line-number line before each line; the second 'sed' does the real
# work. The second script uses 'N' to pair each line-number line
# with the numbered line, and appends trailing '-' during
# substitution so that $LINENO is not a special case at line end.
# (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
# second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
sed '=' <$as_myself |
sed '
N
s,$,-,
: loop
s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
t loop
s,-$,,
s,^['$as_cr_digits']*\n,,
' >$as_me.lineno &&
chmod +x $as_me.lineno ||
{ { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
{ (exit 1); exit 1; }; }
 
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensible to this).
. ./$as_me.lineno
# Exit status is that of the last command.
exit
}
 
 
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
 
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
 
rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
# We could just check for DJGPP; but this test a) works b) is more generic
# and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
if test -f conf$$.exe; then
# Don't use ln at all; we don't have any links
as_ln_s='cp -p'
else
as_ln_s='ln -s'
fi
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file
 
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
 
as_executable_p="test -f"
 
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" $as_nl"
 
# CDPATH.
$as_unset CDPATH
 
exec 6>&1
 
# Open the log real soon, to keep \$[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. Logging --version etc. is OK.
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
} >&5
cat >&5 <<_CSEOF
 
This file was extended by $as_me, which was
generated by GNU Autoconf 2.59. Invocation command line was
 
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
 
_CSEOF
echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
echo >&5
_ACEOF
 
# Files that config.status was made for.
if test -n "$ac_config_files"; then
echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
fi
 
if test -n "$ac_config_headers"; then
echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
fi
 
if test -n "$ac_config_links"; then
echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
fi
 
if test -n "$ac_config_commands"; then
echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
fi
 
cat >>$CONFIG_STATUS <<\_ACEOF
 
ac_cs_usage="\
\`$as_me' instantiates files from templates according to the
current configuration.
 
Usage: $0 [OPTIONS] [FILE]...
 
-h, --help print this help, then exit
-V, --version print version number, then exit
-q, --quiet do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
 
Configuration files:
$config_files
 
Configuration headers:
$config_headers
 
Configuration commands:
$config_commands
 
Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
 
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
config.status
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
Copyright (C) 2003 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
srcdir=$srcdir
INSTALL="$INSTALL"
_ACEOF
 
cat >>$CONFIG_STATUS <<\_ACEOF
# If no file are specified by the user, then we need to provide default
# value. By we need to know if files were specified by the user.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=*)
ac_option=`expr "x$1" : 'x\([^=]*\)='`
ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
ac_shift=:
;;
-*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
*) # This is not an option, so the user has probably given explicit
# arguments.
ac_option=$1
ac_need_defaults=false;;
esac
 
case $ac_option in
# Handling of the options.
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --vers* | -V )
echo "$ac_cs_version"; exit 0 ;;
--he | --h)
# Conflict between --help and --header
{ { echo "$as_me:$LINENO: error: ambiguous option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: ambiguous option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; };;
--help | --hel | -h )
echo "$ac_cs_usage"; exit 0 ;;
--debug | --d* | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
CONFIG_FILES="$CONFIG_FILES $ac_optarg"
ac_need_defaults=false;;
--header | --heade | --head | --hea )
$ac_shift
CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
ac_need_defaults=false;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
 
# This is an error.
-*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: unrecognized option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; } ;;
 
*) ac_config_targets="$ac_config_targets $1" ;;
 
esac
shift
done
 
ac_configure_extra_args=
 
if $ac_cs_silent; then
exec 6>/dev/null
ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
 
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
if \$ac_cs_recheck; then
echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
fi
 
_ACEOF
 
 
 
 
 
cat >>$CONFIG_STATUS <<\_ACEOF
for ac_config_target in $ac_config_targets
do
case "$ac_config_target" in
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };;
esac
done
 
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
fi
 
# Have a temporary directory for convenience. Make it in the build tree
# simply because there is no reason to put it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Create a temporary directory, and hook for its removal unless debugging.
$debug ||
{
trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
trap '{ (exit 1); exit 1; }' 1 2 13 15
}
 
# Create a (secure) tmp directory for tmp files.
 
{
tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
tmp=./confstat$$-$RANDOM
(umask 077 && mkdir $tmp)
} ||
{
echo "$me: cannot create a temporary directory in ." >&2
{ (exit 1); exit 1; }
}
 
_ACEOF
 
cat >>$CONFIG_STATUS <<_ACEOF
 
#
# CONFIG_FILES section.
#
 
# No need to generate the scripts if there are no CONFIG_FILES.
# This happens for instance when ./config.status config.h
if test -n "\$CONFIG_FILES"; then
# Protect against being on the right side of a sed subst in config.status.
sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
s,@SHELL@,$SHELL,;t t
s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
s,@exec_prefix@,$exec_prefix,;t t
s,@prefix@,$prefix,;t t
s,@program_transform_name@,$program_transform_name,;t t
s,@bindir@,$bindir,;t t
s,@sbindir@,$sbindir,;t t
s,@libexecdir@,$libexecdir,;t t
s,@datadir@,$datadir,;t t
s,@sysconfdir@,$sysconfdir,;t t
s,@sharedstatedir@,$sharedstatedir,;t t
s,@localstatedir@,$localstatedir,;t t
s,@libdir@,$libdir,;t t
s,@includedir@,$includedir,;t t
s,@oldincludedir@,$oldincludedir,;t t
s,@infodir@,$infodir,;t t
s,@mandir@,$mandir,;t t
s,@build_alias@,$build_alias,;t t
s,@host_alias@,$host_alias,;t t
s,@target_alias@,$target_alias,;t t
s,@DEFS@,$DEFS,;t t
s,@ECHO_C@,$ECHO_C,;t t
s,@ECHO_N@,$ECHO_N,;t t
s,@ECHO_T@,$ECHO_T,;t t
s,@LIBS@,$LIBS,;t t
s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@ac_ct_CC@,$ac_ct_CC,;t t
s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
s,@build@,$build,;t t
s,@build_cpu@,$build_cpu,;t t
s,@build_vendor@,$build_vendor,;t t
s,@build_os@,$build_os,;t t
s,@host@,$host,;t t
s,@host_cpu@,$host_cpu,;t t
s,@host_vendor@,$host_vendor,;t t
s,@host_os@,$host_os,;t t
s,@target@,$target,;t t
s,@target_cpu@,$target_cpu,;t t
s,@target_vendor@,$target_vendor,;t t
s,@target_os@,$target_os,;t t
s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
s,@INSTALL_DATA@,$INSTALL_DATA,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@RDYNAMIC@,$RDYNAMIC,;t t
s,@GDBSERVER_DEPFILES@,$GDBSERVER_DEPFILES,;t t
s,@GDBSERVER_LIBS@,$GDBSERVER_LIBS,;t t
s,@USE_THREAD_DB@,$USE_THREAD_DB,;t t
s,@srv_xmlbuiltin@,$srv_xmlbuiltin,;t t
s,@srv_xmlfiles@,$srv_xmlfiles,;t t
s,@srv_xmltarget@,$srv_xmltarget,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
 
_ACEOF
 
cat >>$CONFIG_STATUS <<\_ACEOF
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_lines=48
ac_sed_frag=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_lines # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
else
sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
fi
if test ! -s $tmp/subs.frag; then
ac_more_lines=false
else
# The purpose of the label and of the branching condition is to
# speed up the sed processing (if there are no `@' at all, there
# is no need to browse any of the substitutions).
# These are the two extra sed commands mentioned above.
(echo ':t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
else
ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
fi
ac_sed_frag=`expr $ac_sed_frag + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_lines`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
fi # test -n "$CONFIG_FILES"
 
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
 
# Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
 
ac_builddir=.
 
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
 
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
 
# Do not use `cd foo && pwd` to compute absolute paths, because
# the directories may not exist.
case `pwd` in
.) ac_abs_builddir="$ac_dir";;
*)
case "$ac_dir" in
.) ac_abs_builddir=`pwd`;;
[\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
*) ac_abs_builddir=`pwd`/"$ac_dir";;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_builddir=${ac_top_builddir}.;;
*)
case ${ac_top_builddir}. in
.) ac_abs_top_builddir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
*) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_srcdir=$ac_srcdir;;
*)
case $ac_srcdir in
.) ac_abs_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
*) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_srcdir=$ac_top_srcdir;;
*)
case $ac_top_srcdir in
.) ac_abs_top_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
*) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
esac;;
esac
 
 
case $INSTALL in
[\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
 
if test x"$ac_file" != x-; then
{ echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
rm -f "$ac_file"
fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
configure_input=
else
configure_input="$ac_file. "
fi
configure_input=$configure_input"Generated from `echo $ac_file_in |
sed 's,.*/,,'` by configure."
 
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo "$f";;
*) # Relative
if test -f "$f"; then
# Build tree
echo "$f"
elif test -f "$srcdir/$f"; then
# Source tree
echo "$srcdir/$f"
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s,@configure_input@,$configure_input,;t t
s,@srcdir@,$ac_srcdir,;t t
s,@abs_srcdir@,$ac_abs_srcdir,;t t
s,@top_srcdir@,$ac_top_srcdir,;t t
s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
s,@builddir@,$ac_builddir,;t t
s,@abs_builddir@,$ac_abs_builddir,;t t
s,@top_builddir@,$ac_top_builddir,;t t
s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
s,@INSTALL@,$ac_INSTALL,;t t
" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
rm -f $tmp/stdin
if test x"$ac_file" != x-; then
mv $tmp/out $ac_file
else
cat $tmp/out
rm -f $tmp/out
fi
 
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
 
#
# CONFIG_HEADER section.
#
 
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
 
for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
 
test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
 
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
# Do quote $f, to prevent DOS paths from being IFS'd.
echo "$f";;
*) # Relative
if test -f "$f"; then
# Build tree
echo "$f"
elif test -f "$srcdir/$f"; then
# Source tree
echo "$srcdir/$f"
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
 
_ACEOF
 
# Transform confdefs.h into two sed scripts, `conftest.defines' and
# `conftest.undefs', that substitutes the proper values into
# config.h.in to produce config.h. The first handles `#define'
# templates, and the second `#undef' templates.
# And first: Protect against being on the right side of a sed subst in
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
# Using a here document instead of a string reduces the quoting nightmare.
# Putting comments in sed scripts is not portable.
#
# `end' is used to avoid that the second main sed command (meant for
# 0-ary CPP macros) applies to n-ary macro definitions.
# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\_ACEOF
s/[\\&,]/\\&/g
s,[\\$`],\\&,g
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
t end
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
: end
_ACEOF
# If some macros were called several times there might be several times
# the same #defines, which is useless. Nevertheless, we may not want to
# sort them, since we want the *last* AC-DEFINE to be honored.
uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
rm -f confdef2sed.sed
 
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >>conftest.undefs <<\_ACEOF
s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
_ACEOF
 
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.defines >/dev/null
do
# Write a limited-size here document to $tmp/defines.sed.
echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#define' lines.
echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/defines.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
rm -f conftest.defines
mv conftest.tail conftest.defines
done
rm -f conftest.defines
echo ' fi # grep' >>$CONFIG_STATUS
echo >>$CONFIG_STATUS
 
# Break up conftest.undefs because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.undefs >/dev/null
do
# Write a limited-size here document to $tmp/undefs.sed.
echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#undef'
echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/undefs.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
rm -f conftest.undefs
mv conftest.tail conftest.undefs
done
rm -f conftest.undefs
 
cat >>$CONFIG_STATUS <<\_ACEOF
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
echo "/* Generated by configure. */" >$tmp/config.h
else
echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
 
rm -f $ac_file
mv $tmp/config.h $ac_file
fi
else
cat $tmp/config.h
rm -f $tmp/config.h
fi
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
 
#
# CONFIG_COMMANDS section.
#
for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_dest" : 'X\(//\)[^/]' \| \
X"$ac_dest" : 'X\(//\)$' \| \
X"$ac_dest" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_dest" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
 
ac_builddir=.
 
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
 
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
 
# Do not use `cd foo && pwd` to compute absolute paths, because
# the directories may not exist.
case `pwd` in
.) ac_abs_builddir="$ac_dir";;
*)
case "$ac_dir" in
.) ac_abs_builddir=`pwd`;;
[\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
*) ac_abs_builddir=`pwd`/"$ac_dir";;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_builddir=${ac_top_builddir}.;;
*)
case ${ac_top_builddir}. in
.) ac_abs_top_builddir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
*) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_srcdir=$ac_srcdir;;
*)
case $ac_srcdir in
.) ac_abs_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
*) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
esac;;
esac
case $ac_abs_builddir in
.) ac_abs_top_srcdir=$ac_top_srcdir;;
*)
case $ac_top_srcdir in
.) ac_abs_top_srcdir=$ac_abs_builddir;;
[\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
*) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
esac;;
esac
 
 
{ echo "$as_me:$LINENO: executing $ac_dest commands" >&5
echo "$as_me: executing $ac_dest commands" >&6;}
case $ac_dest in
default ) case x$CONFIG_HEADERS in
xconfig.h:config.in)
echo > stamp-h ;;
esac
;;
esac
done
_ACEOF
 
cat >>$CONFIG_STATUS <<\_ACEOF
 
{ (exit 0); exit 0; }
_ACEOF
chmod +x $CONFIG_STATUS
ac_clean_files=$ac_clean_files_save
 
 
# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded. So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status. When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
ac_cs_success=:
ac_config_status_args=
test "$silent" = yes &&
ac_config_status_args="$ac_config_status_args --quiet"
exec 5>/dev/null
$SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
$ac_cs_success || { (exit 1); exit 1; }
fi
 
configure Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: Makefile.in =================================================================== --- Makefile.in (nonexistent) +++ Makefile.in (revision 816) @@ -0,0 +1,400 @@ +# Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, +# 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +host_alias = @host_alias@ +target_alias = @target_alias@ +program_transform_name = @program_transform_name@ +bindir = @bindir@ +libdir = @libdir@ +tooldir = $(libdir)/$(target_alias) + +datadir = @datadir@ +mandir = @mandir@ +man1dir = $(mandir)/man1 +man2dir = $(mandir)/man2 +man3dir = $(mandir)/man3 +man4dir = $(mandir)/man4 +man5dir = $(mandir)/man5 +man6dir = $(mandir)/man6 +man7dir = $(mandir)/man7 +man8dir = $(mandir)/man8 +man9dir = $(mandir)/man9 +infodir = @infodir@ +htmldir = $(prefix)/html +includedir = @includedir@ + +SHELL = /bin/sh +EXEEXT = @EXEEXT@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +CC = @CC@ + +# Directory containing source files. Don't clean up the spacing, +# this exact string is matched for by the "configure" script. +srcdir = @srcdir@ +VPATH = @srcdir@ + +# It is also possible that you will need to add -I/usr/include/sys to the +# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which +# is where it should be according to Posix). + +# Set this up with gcc if you have gnu ld and the loader will print out +# line numbers for undefinded refs. +#CC-LD=gcc -static +CC-LD=${CC} + +# Where is the "include" directory? Traditionally ../include or ./include +INCLUDE_DIR = ${srcdir}/../../include +INCLUDE_DEP = $$(INCLUDE_DIR) + +# Where are the BFD library? +BFD_DIR = ../../bfd +BFD = $(BFD_DIR)/libbfd.a +BFD_SRC = $(srcdir)/$(BFD_DIR) +BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC) + +# Where is the source dir for the READLINE library? Traditionally in .. or . +# (For the binary library built from it, we use ${READLINE_DIR}${subdir}.) +READLINE_DIR = ${srcdir}/../readline +READLINE_DEP = $$(READLINE_DIR) + +# All the includes used for CFLAGS and for lint. +# -I. for config files. +# -I${srcdir} for our headers. +# -I$(srcdir)/../regformats for regdef.h. +INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR) + +# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS +# from the config/ directory. +GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS} +#PROFILE_CFLAGS = -pg + +WARN_CFLAGS = -Wall + +# CFLAGS is specifically reserved for setting from the command line +# when running make. I.E. "make CFLAGS=-Wmissing-prototypes". +CFLAGS = @CFLAGS@ + +# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros. +INTERNAL_CFLAGS = $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \ + ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${BFD_CFLAGS} + +# LDFLAGS is specifically reserved for setting from the command line +# when running make. +LDFLAGS = @LDFLAGS@ +INTERNAL_LDFLAGS = $(LDFLAGS) @RDYNAMIC@ + +# Perhaps should come from parent Makefile +VERSION = gdbserver-4.12.3 +DIST=gdb + +LINT=/usr/5bin/lint +LINTFLAGS= $(BFD_CFLAGS) + +# All source files that go into linking GDB remote server. + +SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \ + $(srcdir)/mem-break.c $(srcdir)/proc-service.c $(srcdir)/regcache.c \ + $(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \ + $(srcdir)/thread-db.c $(srcdir)/utils.c \ + $(srcdir)/linux-arm-low.c $(srcdir)/linux-cris-low.c \ + $(srcdir)/linux-crisv32-low.c $(srcdir)/linux-i386-low.c \ + $(srcdir)/i387-fp.c \ + $(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \ + $(srcdir)/linux-m32r-low.c \ + $(srcdir)/linux-m68k-low.c $(srcdir)/linux-mips-low.c \ + $(srcdir)/linux-ppc-low.c $(srcdir)/linux-ppc64-low.c \ + $(srcdir)/linux-s390-low.c \ + $(srcdir)/linux-sh-low.c $(srcdir)/linux-x86-64-low.c \ + $(srcdir)/linux-xtensa-low.c \ + $(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \ + $(srcdir)/win32-low.c $(srcdir)/wincecompat.c \ + $(srcdir)/hostio.c $(srcdir)/hostio-errno.c + +DEPFILES = @GDBSERVER_DEPFILES@ + +SOURCES = $(SFILES) +TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} + +OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \ + utils.o version.o \ + mem-break.o hostio.o \ + $(XML_BUILTIN) \ + $(DEPFILES) +GDBSERVER_LIBS = @GDBSERVER_LIBS@ +XM_CLIBS = @LIBS@ + +# XML files to compile in to gdbserver, if any. +XML_DIR = $(srcdir)/../features +XML_TARGET = @srv_xmltarget@ +XML_FILES = @srv_xmlfiles@ +XML_BUILTIN = @srv_xmlbuiltin@ + +# Prevent Sun make from putting in the machine type. Setting +# TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. +.c.o: + ${CC} -c ${INTERNAL_CFLAGS} $< + +all: gdbserver$(EXEEXT) gdbreplay$(EXEEXT) + +# Traditionally "install" depends on "all". But it may be useful +# not to; for example, if the user has made some trivial change to a +# source file and doesn't care about rebuilding or just wants to save the +# time it takes for make to check that all is up to date. +# install-only is intended to address that need. +install: all install-only +install-only: + n=`echo gdbserver | sed '$(program_transform_name)'`; \ + if [ x$$n = x ]; then n=gdbserver; else true; fi; \ + $(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(bindir); \ + $(INSTALL_PROGRAM) gdbserver$(EXEEXT) $(DESTDIR)$(bindir)/$$n$(EXEEXT); \ + $(SHELL) $(srcdir)/../../mkinstalldirs $(DESTDIR)$(man1dir); \ + $(INSTALL_DATA) $(srcdir)/gdbserver.1 $(DESTDIR)$(man1dir)/$$n.1 + +uninstall: force + n=`echo gdbserver | sed '$(program_transform_name)'`; \ + if [ x$$n = x ]; then n=gdbserver; else true; fi; \ + rm -f $(bindir)/$$n $(DESTDIR)$(man1dir)/$$n.1 + +installcheck: +check: +info dvi pdf: +install-info: +install-pdf: +html: +install-html: +clean-info: + +gdbserver$(EXEEXT): $(OBS) ${ADD_DEPS} ${CDEPS} + rm -f gdbserver$(EXEEXT) + ${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbserver$(EXEEXT) $(OBS) \ + $(GDBSERVER_LIBS) $(XM_CLIBS) + +gdbreplay$(EXEEXT): gdbreplay.o + rm -f gdbreplay$(EXEEXT) + ${CC-LD} $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) -o gdbreplay$(EXEEXT) gdbreplay.o \ + $(XM_CLIBS) + +# Put the proper machine-specific files first, so M-. on a machine +# specific routine gets the one for the correct machine. +# The xyzzy stuff below deals with empty DEPFILES +TAGS: ${TAGFILES} + etags `find ${srcdir}/../config -name $(DEPRECATED_TM_FILE) -print` \ + `find ${srcdir}/../config -name ${XM_FILE} -print` \ + `find ${srcdir}/../config -name ${NAT_FILE} -print` \ + `for i in yzzy ${DEPFILES}; do \ + if [ x$$i != xyzzy ]; then \ + echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \ + fi; \ + done` \ + ${TAGFILES} +tags: TAGS + +clean: + rm -f *.o ${ADD_FILES} *~ + rm -f version.c + rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log + rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c + rm -f reg-ppc.c reg-sh.c reg-spu.c reg-x86-64.c reg-i386-linux.c + rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c + rm -f arm-with-iwmmxt.c mips-linux.c mips64-linux.c + rm -f powerpc-32.c powerpc-64.c powerpc-e500.c + rm -f xml-builtin.c stamp-xml target.xml + +maintainer-clean realclean distclean: clean + rm -f nm.h tm.h xm.h config.status config.h stamp-h config.log + rm -f Makefile + +config.h: stamp-h ; @true +stamp-h: config.in config.status + CONFIG_FILES="" CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status + +Makefile: Makefile.in config.status + CONFIG_HEADERS="" $(SHELL) ./config.status + +config.status: configure configure.srv + $(SHELL) ./config.status --recheck + +force: + +version.c: Makefile $(srcdir)/../version.in + rm -f version.c-tmp version.c + echo '#include "server.h"' >> version.c-tmp + echo 'const char version[] = "'"`sed q ${srcdir}/../version.in`"'";' >> version.c-tmp + echo 'const char host_name[] = "$(host_alias)";' >> version.c-tmp + mv version.c-tmp version.c +version.o: version.c $(server_h) + +target.xml: $(XML_TARGET) + rm -f target.xml + cp $(XML_TARGET) target.xml + +xml-builtin.c: stamp-xml; @true +stamp-xml: $(XML_DIR)/feature_to_c.sh Makefile $(XML_FILES) + rm -f xml-builtin.tmp + $(SHELL) $(XML_DIR)/feature_to_c.sh xml-builtin.tmp $(XML_FILES) + $(SHELL) $(srcdir)/../../move-if-change xml-builtin.tmp xml-builtin.c + echo stamp > stamp-xml + +.PRECIOUS: target.xml xml-builtin.c + +# GNU Make has an annoying habit of putting *all* the Makefile variables +# into the environment, unless you include this target as a circumvention. +# Rumor is that this will be fixed (and this target can be removed) +# in GNU Make 4.0. +.NOEXPORT: + +# GNU Make 3.63 has a different problem: it keeps tacking command line +# overrides onto the definition of $(MAKE). This variable setting +# will remove them. +MAKEOVERRIDES= + +gdb_proc_service_h = $(srcdir)/gdb_proc_service.h +regdat_sh = $(srcdir)/../regformats/regdat.sh +regdef_h = $(srcdir)/../regformats/regdef.h +regcache_h = $(srcdir)/regcache.h +server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \ + $(srcdir)/mem-break.h + +hostio.o: hostio.c $(server_h) +hostio-errno.o: hostio-errno.c $(server_h) +inferiors.o: inferiors.c $(server_h) +mem-break.o: mem-break.c $(server_h) +proc-service.o: proc-service.c $(server_h) $(gdb_proc_service_h) +regcache.o: regcache.c $(server_h) $(regdef_h) +remote-utils.o: remote-utils.c terminal.h $(server_h) +server.o: server.c $(server_h) +target.o: target.c $(server_h) +thread-db.o: thread-db.c $(server_h) $(gdb_proc_service_h) +utils.o: utils.c $(server_h) + +signals.o: ../signals/signals.c $(server_h) + $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER + +i387-fp.o: i387-fp.c $(server_h) + +linux_low_h = $(srcdir)/linux-low.h + +linux-low.o: linux-low.c $(linux_low_h) $(server_h) + $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@ + +linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) \ + $(gdb_proc_service_h) +linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h) +linux-crisv32-low.o: linux-crisv32-low.c $(linux_low_h) $(server_h) +linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h) \ + $(gdb_proc_service_h) +linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h) +linux-m32r-low.o: linux-m32r-low.c $(linux_low_h) $(server_h) +linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h) \ + $(gdb_proc_service_h) +linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h) +linux-ppc64-low.o: linux-ppc64-low.c $(linux_low_h) $(server_h) +linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h) +linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h) +linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h) \ + $(gdb_proc_service_h) +linux-xtensa-low.o: linux-xtensa-low.c xtensa-xtregs.c $(linux_low_h) $(server_h) + +win32_low_h = $(srcdir)/win32-low.h + +win32-low.o: win32-low.c $(win32_low_h) $(server_h) $(regdef_h) $(regcache_h) + +win32-arm-low.o: win32-arm-low.c $(win32_low_h) $(server_h) +win32-i386-low.o: win32-i386-low.c $(win32_low_h) $(server_h) + +spu-low.o: spu-low.c $(server_h) + +reg-arm.o : reg-arm.c $(regdef_h) +reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-arm.dat reg-arm.c +arm-with-iwmmxt.o : arm-with-iwmmxt.c $(regdef_h) +arm-with-iwmmxt.c : $(srcdir)/../regformats/arm-with-iwmmxt.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/arm-with-iwmmxt.dat arm-with-iwmmxt.c +reg-cris.o : reg-cris.c $(regdef_h) +reg-cris.c : $(srcdir)/../regformats/reg-cris.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-cris.dat reg-cris.c +reg-crisv32.o : reg-crisv32.c $(regdef_h) +reg-crisv32.c : $(srcdir)/../regformats/reg-crisv32.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-crisv32.dat reg-crisv32.c +reg-i386.o : reg-i386.c $(regdef_h) +reg-i386.c : $(srcdir)/../regformats/reg-i386.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386.dat reg-i386.c +reg-i386-linux.o : reg-i386-linux.c $(regdef_h) +reg-i386-linux.c : $(srcdir)/../regformats/reg-i386-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386-linux.dat reg-i386-linux.c +reg-ia64.o : reg-ia64.c $(regdef_h) +reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c +reg-m32r.o : reg-m32r.c $(regdef_h) +reg-m32r.c : $(srcdir)/../regformats/reg-m32r.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-m32r.dat reg-m32r.c +reg-m68k.o : reg-m68k.c $(regdef_h) +reg-m68k.c : $(srcdir)/../regformats/reg-m68k.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-m68k.dat reg-m68k.c +mips-linux.o : mips-linux.c $(regdef_h) +mips-linux.c : $(srcdir)/../regformats/mips-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips-linux.dat mips-linux.c +mips64-linux.o : mips64-linux.c $(regdef_h) +mips64-linux.c : $(srcdir)/../regformats/mips64-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/mips64-linux.dat mips64-linux.c +reg-ppc.o : reg-ppc.c $(regdef_h) +reg-ppc.c : $(srcdir)/../regformats/reg-ppc.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ppc.dat reg-ppc.c +reg-ppc64.o : reg-ppc64.c $(regdef_h) +reg-ppc64.c : $(srcdir)/../regformats/reg-ppc64.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ppc64.dat reg-ppc64.c +powerpc-32.o : powerpc-32.c $(regdef_h) +powerpc-32.c : $(srcdir)/../regformats/rs6000/powerpc-32.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-32.dat powerpc-32.c +powerpc-e500.o : powerpc-e500.c $(regdef_h) +powerpc-e500.c : $(srcdir)/../regformats/rs6000/powerpc-e500.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-e500.dat powerpc-e500.c +powerpc-64.o : powerpc-64.c $(regdef_h) +powerpc-64.c : $(srcdir)/../regformats/rs6000/powerpc-64.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/rs6000/powerpc-64.dat powerpc-64.c +reg-s390.o : reg-s390.c $(regdef_h) +reg-s390.c : $(srcdir)/../regformats/reg-s390.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-s390.dat reg-s390.c +reg-s390x.o : reg-s390x.c $(regdef_h) +reg-s390x.c : $(srcdir)/../regformats/reg-s390x.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-s390x.dat reg-s390x.c +reg-sh.o : reg-sh.c $(regdef_h) +reg-sh.c : $(srcdir)/../regformats/reg-sh.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-sh.dat reg-sh.c +reg-spu.o : reg-spu.c $(regdef_h) +reg-spu.c : $(srcdir)/../regformats/reg-spu.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-spu.dat reg-spu.c +reg-x86-64.o : reg-x86-64.c $(regdef_h) +reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c +reg-x86-64-linux.o : reg-x86-64-linux.c $(regdef_h) +reg-x86-64-linux.c : $(srcdir)/../regformats/reg-x86-64-linux.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64-linux.dat reg-x86-64-linux.c +reg-xtensa.o : reg-xtensa.c $(regdef_h) +reg-xtensa.c : $(srcdir)/../regformats/reg-xtensa.dat $(regdat_sh) + $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-xtensa.dat reg-xtensa.c +# This is the end of "Makefile.in". Index: aclocal.m4 =================================================================== --- aclocal.m4 (nonexistent) +++ aclocal.m4 (revision 816) @@ -0,0 +1,14 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_include([acinclude.m4]) Index: linux-xtensa-low.c =================================================================== --- linux-xtensa-low.c (nonexistent) +++ linux-xtensa-low.c (revision 816) @@ -0,0 +1,187 @@ +/* GNU/Linux/Xtensa specific low level interface, for the remote server for GDB. + Copyright 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + + +#include "server.h" +#include "linux-low.h" + +#include +#include + +#include "xtensa-xtregs.c" + +enum regnum { + R_PC=0, R_PS, + R_LBEG, R_LEND, R_LCOUNT, + R_SAR, + R_WS, R_WB, + R_A0 = 64 +}; + +static void +xtensa_fill_gregset (void *buf) +{ + elf_greg_t* rset = (elf_greg_t*)buf; + int ar0_regnum; + char *ptr; + int i; + + /* Take care of AR registers. */ + + ar0_regnum = find_regno ("ar0"); + ptr = (char*)&rset[R_A0]; + + for (i = ar0_regnum; i < ar0_regnum + XCHAL_NUM_AREGS; i++) + { + collect_register (i, ptr); + ptr += register_size(i); + } + + /* Loop registers, if hardware has it. */ + +#if XCHAL_HAVE_LOOP + collect_register_by_name ("lbeg", (char*)&rset[R_LBEG]); + collect_register_by_name ("lend", (char*)&rset[R_LEND]); + collect_register_by_name ("lcount", (char*)&rset[R_LCOUNT]); +#endif + + collect_register_by_name ("sar", (char*)&rset[R_SAR]); + collect_register_by_name ("pc", (char*)&rset[R_PC]); + collect_register_by_name ("ps", (char*)&rset[R_PS]); + collect_register_by_name ("windowbase", (char*)&rset[R_WB]); + collect_register_by_name ("windowstart", (char*)&rset[R_WS]); +} + +static void +xtensa_store_gregset (const void *buf) +{ + const elf_greg_t* rset = (const elf_greg_t*)buf; + int ar0_regnum; + char *ptr; + int i; + + /* Take care of AR registers. */ + + ar0_regnum = find_regno ("ar0"); + ptr = (char *)&rset[R_A0]; + + for (i = ar0_regnum; i < ar0_regnum + XCHAL_NUM_AREGS; i++) + { + supply_register (i, ptr); + ptr += register_size(i); + } + + /* Loop registers, if hardware has it. */ + +#if XCHAL_HAVE_LOOP + supply_register_by_name ("lbeg", (char*)&rset[R_LBEG]); + supply_register_by_name ("lend", (char*)&rset[R_LEND]); + supply_register_by_name ("lcount", (char*)&rset[R_LCOUNT]); +#endif + + supply_register_by_name ("sar", (char*)&rset[R_SAR]); + supply_register_by_name ("pc", (char*)&rset[R_PC]); + supply_register_by_name ("ps", (char*)&rset[R_PS]); + supply_register_by_name ("windowbase", (char*)&rset[R_WB]); + supply_register_by_name ("windowstart", (char*)&rset[R_WS]); +} + +/* Xtensa GNU/Linux PTRACE interface includes extended register set. */ + +static void +xtensa_fill_xtregset (void *buf) +{ + const xtensa_regtable_t *ptr; + + for (ptr = xtensa_regmap_table; ptr->name; ptr++) + { + collect_register_by_name (ptr->name, + (char*)buf + ptr->ptrace_offset); + } +} + +static void +xtensa_store_xtregset (const void *buf) +{ + const xtensa_regtable_t *ptr; + + for (ptr = xtensa_regmap_table; ptr->name; ptr++) + { + supply_register_by_name (ptr->name, + (char*)buf + ptr->ptrace_offset); + } +} + +struct regset_info target_regsets[] = { + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), + GENERAL_REGS, + xtensa_fill_gregset, xtensa_store_gregset }, + { PTRACE_GETXTREGS, PTRACE_SETXTREGS, XTENSA_ELF_XTREG_SIZE, + EXTENDED_REGS, + xtensa_fill_xtregset, xtensa_store_xtregset }, + { 0, 0, -1, -1, NULL, NULL } +}; + +#if XCHAL_HAVE_BE +#define XTENSA_BREAKPOINT {0xd2,0x0f} +#else +#define XTENSA_BREAKPOINT {0x2d,0xf0} +#endif + +static const unsigned char xtensa_breakpoint[] = XTENSA_BREAKPOINT; +#define xtensa_breakpoint_len 2 + +static CORE_ADDR +xtensa_get_pc (void) +{ + unsigned long pc; + + collect_register_by_name ("pc", &pc); + return pc; +} + +static void +xtensa_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +static int +xtensa_breakpoint_at (CORE_ADDR where) +{ + unsigned long insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, + xtensa_breakpoint_len); + return memcmp((char *)&insn, xtensa_breakpoint, xtensa_breakpoint_len) == 0; +} + +struct linux_target_ops the_low_target = { + 0, + 0, + 0, + 0, + xtensa_get_pc, + xtensa_set_pc, + xtensa_breakpoint, + xtensa_breakpoint_len, + NULL, + 0, + xtensa_breakpoint_at, +};
linux-xtensa-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-low.c =================================================================== --- linux-low.c (nonexistent) +++ linux-low.c (revision 816) @@ -0,0 +1,2078 @@ +/* Low level interface to ptrace, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PTRACE_GETSIGINFO +# define PTRACE_GETSIGINFO 0x4202 +# define PTRACE_SETSIGINFO 0x4203 +#endif + +#ifndef O_LARGEFILE +#define O_LARGEFILE 0 +#endif + +/* If the system headers did not provide the constants, hard-code the normal + values. */ +#ifndef PTRACE_EVENT_FORK + +#define PTRACE_SETOPTIONS 0x4200 +#define PTRACE_GETEVENTMSG 0x4201 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 +#define PTRACE_O_TRACEFORK 0x00000002 +#define PTRACE_O_TRACEVFORK 0x00000004 +#define PTRACE_O_TRACECLONE 0x00000008 +#define PTRACE_O_TRACEEXEC 0x00000010 +#define PTRACE_O_TRACEVFORKDONE 0x00000020 +#define PTRACE_O_TRACEEXIT 0x00000040 + +/* Wait extended result codes for the above trace options. */ +#define PTRACE_EVENT_FORK 1 +#define PTRACE_EVENT_VFORK 2 +#define PTRACE_EVENT_CLONE 3 +#define PTRACE_EVENT_EXEC 4 +#define PTRACE_EVENT_VFORK_DONE 5 +#define PTRACE_EVENT_EXIT 6 + +#endif /* PTRACE_EVENT_FORK */ + +/* We can't always assume that this flag is available, but all systems + with the ptrace event handlers also have __WALL, so it's safe to use + in some contexts. */ +#ifndef __WALL +#define __WALL 0x40000000 /* Wait for any child. */ +#endif + +#ifdef __UCLIBC__ +#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__)) +#define HAS_NOMMU +#endif +#endif + +/* ``all_threads'' is keyed by the LWP ID, which we use as the GDB protocol + representation of the thread ID. + + ``all_processes'' is keyed by the process ID - which on Linux is (presently) + the same as the LWP ID. */ + +struct inferior_list all_processes; + +/* A list of all unknown processes which receive stop signals. Some other + process will presumably claim each of these as forked children + momentarily. */ + +struct inferior_list stopped_pids; + +/* FIXME this is a bit of a hack, and could be removed. */ +int stopping_threads; + +/* FIXME make into a target method? */ +int using_threads = 1; +static int thread_db_active; + +static int must_set_ptrace_flags; + +static void linux_resume_one_process (struct inferior_list_entry *entry, + int step, int signal, siginfo_t *info); +static void linux_resume (struct thread_resume *resume_info); +static void stop_all_processes (void); +static int linux_wait_for_event (struct thread_info *child); +static int check_removed_breakpoint (struct process_info *event_child); +static void *add_process (unsigned long pid); + +struct pending_signals +{ + int signal; + siginfo_t info; + struct pending_signals *prev; +}; + +#define PTRACE_ARG3_TYPE long +#define PTRACE_XFER_TYPE long + +#ifdef HAVE_LINUX_REGSETS +static int use_regsets_p = 1; +#endif + +#define pid_of(proc) ((proc)->head.id) + +/* FIXME: Delete eventually. */ +#define inferior_pid (pid_of (get_thread_process (current_inferior))) + +static void +handle_extended_wait (struct process_info *event_child, int wstat) +{ + int event = wstat >> 16; + struct process_info *new_process; + + if (event == PTRACE_EVENT_CLONE) + { + unsigned long new_pid; + int ret, status; + + ptrace (PTRACE_GETEVENTMSG, inferior_pid, 0, &new_pid); + + /* If we haven't already seen the new PID stop, wait for it now. */ + if (! pull_pid_from_list (&stopped_pids, new_pid)) + { + /* The new child has a pending SIGSTOP. We can't affect it until it + hits the SIGSTOP, but we're already attached. */ + + do { + ret = waitpid (new_pid, &status, __WALL); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) + perror_with_name ("waiting for new child"); + else if (ret != new_pid) + warning ("wait returned unexpected PID %d", ret); + else if (!WIFSTOPPED (status)) + warning ("wait returned unexpected status 0x%x", status); + } + + ptrace (PTRACE_SETOPTIONS, new_pid, 0, PTRACE_O_TRACECLONE); + + new_process = (struct process_info *) add_process (new_pid); + add_thread (new_pid, new_process, new_pid); + new_thread_notify (thread_id_to_gdb_id (new_process->lwpid)); + + /* Normally we will get the pending SIGSTOP. But in some cases + we might get another signal delivered to the group first. + If we do, be sure not to lose it. */ + if (WSTOPSIG (status) == SIGSTOP) + { + if (stopping_threads) + new_process->stopped = 1; + else + ptrace (PTRACE_CONT, new_pid, 0, 0); + } + else + { + new_process->stop_expected = 1; + if (stopping_threads) + { + new_process->stopped = 1; + new_process->status_pending_p = 1; + new_process->status_pending = status; + } + else + /* Pass the signal on. This is what GDB does - except + shouldn't we really report it instead? */ + ptrace (PTRACE_CONT, new_pid, 0, WSTOPSIG (status)); + } + + /* Always resume the current thread. If we are stopping + threads, it will have a pending SIGSTOP; we may as well + collect it now. */ + linux_resume_one_process (&event_child->head, + event_child->stepping, 0, NULL); + } +} + +/* This function should only be called if the process got a SIGTRAP. + The SIGTRAP could mean several things. + + On i386, where decr_pc_after_break is non-zero: + If we were single-stepping this process using PTRACE_SINGLESTEP, + we will get only the one SIGTRAP (even if the instruction we + stepped over was a breakpoint). The value of $eip will be the + next instruction. + If we continue the process using PTRACE_CONT, we will get a + SIGTRAP when we hit a breakpoint. The value of $eip will be + the instruction after the breakpoint (i.e. needs to be + decremented). If we report the SIGTRAP to GDB, we must also + report the undecremented PC. If we cancel the SIGTRAP, we + must resume at the decremented PC. + + (Presumably, not yet tested) On a non-decr_pc_after_break machine + with hardware or kernel single-step: + If we single-step over a breakpoint instruction, our PC will + point at the following instruction. If we continue and hit a + breakpoint instruction, our PC will point at the breakpoint + instruction. */ + +static CORE_ADDR +get_stop_pc (void) +{ + CORE_ADDR stop_pc = (*the_low_target.get_pc) (); + + if (get_thread_process (current_inferior)->stepping) + return stop_pc; + else + return stop_pc - the_low_target.decr_pc_after_break; +} + +static void * +add_process (unsigned long pid) +{ + struct process_info *process; + + process = (struct process_info *) malloc (sizeof (*process)); + memset (process, 0, sizeof (*process)); + + process->head.id = pid; + process->lwpid = pid; + + add_inferior_to_list (&all_processes, &process->head); + + return process; +} + +/* Start an inferior process and returns its pid. + ALLARGS is a vector of program-name and args. */ + +static int +linux_create_inferior (char *program, char **allargs) +{ + void *new_process; + int pid; + +#if defined(__UCLIBC__) && defined(HAS_NOMMU) + pid = vfork (); +#else + pid = fork (); +#endif + if (pid < 0) + perror_with_name ("fork"); + + if (pid == 0) + { + ptrace (PTRACE_TRACEME, 0, 0, 0); + + signal (__SIGRTMIN + 1, SIG_DFL); + + setpgid (0, 0); + + execv (program, allargs); + if (errno == ENOENT) + execvp (program, allargs); + + fprintf (stderr, "Cannot exec %s: %s.\n", program, + strerror (errno)); + fflush (stderr); + _exit (0177); + } + + new_process = add_process (pid); + add_thread (pid, new_process, pid); + must_set_ptrace_flags = 1; + + return pid; +} + +/* Attach to an inferior process. */ + +void +linux_attach_lwp (unsigned long pid) +{ + struct process_info *new_process; + + if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0) + { + if (all_threads.head != NULL) + { + /* If we fail to attach to an LWP, just warn. */ + fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid, + strerror (errno), errno); + fflush (stderr); + return; + } + else + /* If we fail to attach to a process, report an error. */ + error ("Cannot attach to process %ld: %s (%d)\n", pid, + strerror (errno), errno); + } + + ptrace (PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACECLONE); + + new_process = (struct process_info *) add_process (pid); + add_thread (pid, new_process, pid); + new_thread_notify (thread_id_to_gdb_id (new_process->lwpid)); + + /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH + brings it to a halt. We should ignore that SIGSTOP and resume the process + (unless this is the first process, in which case the flag will be cleared + in linux_attach). + + On the other hand, if we are currently trying to stop all threads, we + should treat the new thread as if we had sent it a SIGSTOP. This works + because we are guaranteed that add_process added us to the end of the + list, and so the new thread has not yet reached wait_for_sigstop (but + will). */ + if (! stopping_threads) + new_process->stop_expected = 1; +} + +int +linux_attach (unsigned long pid) +{ + struct process_info *process; + + linux_attach_lwp (pid); + + /* Don't ignore the initial SIGSTOP if we just attached to this process. + It will be collected by wait shortly. */ + process = (struct process_info *) find_inferior_id (&all_processes, pid); + process->stop_expected = 0; + + return 0; +} + +/* Kill the inferior process. Make us have no inferior. */ + +static void +linux_kill_one_process (struct inferior_list_entry *entry) +{ + struct thread_info *thread = (struct thread_info *) entry; + struct process_info *process = get_thread_process (thread); + int wstat; + + /* We avoid killing the first thread here, because of a Linux kernel (at + least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before + the children get a chance to be reaped, it will remain a zombie + forever. */ + if (entry == all_threads.head) + return; + + do + { + ptrace (PTRACE_KILL, pid_of (process), 0, 0); + + /* Make sure it died. The loop is most likely unnecessary. */ + wstat = linux_wait_for_event (thread); + } while (WIFSTOPPED (wstat)); +} + +static void +linux_kill (void) +{ + struct thread_info *thread = (struct thread_info *) all_threads.head; + struct process_info *process; + int wstat; + + if (thread == NULL) + return; + + for_each_inferior (&all_threads, linux_kill_one_process); + + /* See the comment in linux_kill_one_process. We did not kill the first + thread in the list, so do so now. */ + process = get_thread_process (thread); + do + { + ptrace (PTRACE_KILL, pid_of (process), 0, 0); + + /* Make sure it died. The loop is most likely unnecessary. */ + wstat = linux_wait_for_event (thread); + } while (WIFSTOPPED (wstat)); + + clear_inferiors (); + free (all_processes.head); + all_processes.head = all_processes.tail = NULL; +} + +static void +linux_detach_one_process (struct inferior_list_entry *entry) +{ + struct thread_info *thread = (struct thread_info *) entry; + struct process_info *process = get_thread_process (thread); + + /* Make sure the process isn't stopped at a breakpoint that's + no longer there. */ + check_removed_breakpoint (process); + + /* If this process is stopped but is expecting a SIGSTOP, then make + sure we take care of that now. This isn't absolutely guaranteed + to collect the SIGSTOP, but is fairly likely to. */ + if (process->stop_expected) + { + /* Clear stop_expected, so that the SIGSTOP will be reported. */ + process->stop_expected = 0; + if (process->stopped) + linux_resume_one_process (&process->head, 0, 0, NULL); + linux_wait_for_event (thread); + } + + /* Flush any pending changes to the process's registers. */ + regcache_invalidate_one ((struct inferior_list_entry *) + get_process_thread (process)); + + /* Finally, let it resume. */ + ptrace (PTRACE_DETACH, pid_of (process), 0, 0); +} + +static int +linux_detach (void) +{ + delete_all_breakpoints (); + for_each_inferior (&all_threads, linux_detach_one_process); + clear_inferiors (); + free (all_processes.head); + all_processes.head = all_processes.tail = NULL; + return 0; +} + +static void +linux_join (void) +{ + extern unsigned long signal_pid; + int status, ret; + + do { + ret = waitpid (signal_pid, &status, 0); + if (WIFEXITED (status) || WIFSIGNALED (status)) + break; + } while (ret != -1 || errno != ECHILD); +} + +/* Return nonzero if the given thread is still alive. */ +static int +linux_thread_alive (unsigned long lwpid) +{ + if (find_inferior_id (&all_threads, lwpid) != NULL) + return 1; + else + return 0; +} + +/* Return nonzero if this process stopped at a breakpoint which + no longer appears to be inserted. Also adjust the PC + appropriately to resume where the breakpoint used to be. */ +static int +check_removed_breakpoint (struct process_info *event_child) +{ + CORE_ADDR stop_pc; + struct thread_info *saved_inferior; + + if (event_child->pending_is_breakpoint == 0) + return 0; + + if (debug_threads) + fprintf (stderr, "Checking for breakpoint in process %ld.\n", + event_child->lwpid); + + saved_inferior = current_inferior; + current_inferior = get_process_thread (event_child); + + stop_pc = get_stop_pc (); + + /* If the PC has changed since we stopped, then we shouldn't do + anything. This happens if, for instance, GDB handled the + decr_pc_after_break subtraction itself. */ + if (stop_pc != event_child->pending_stop_pc) + { + if (debug_threads) + fprintf (stderr, "Ignoring, PC was changed. Old PC was 0x%08llx\n", + event_child->pending_stop_pc); + + event_child->pending_is_breakpoint = 0; + current_inferior = saved_inferior; + return 0; + } + + /* If the breakpoint is still there, we will report hitting it. */ + if ((*the_low_target.breakpoint_at) (stop_pc)) + { + if (debug_threads) + fprintf (stderr, "Ignoring, breakpoint is still present.\n"); + current_inferior = saved_inferior; + return 0; + } + + if (debug_threads) + fprintf (stderr, "Removed breakpoint.\n"); + + /* For decr_pc_after_break targets, here is where we perform the + decrement. We go immediately from this function to resuming, + and can not safely call get_stop_pc () again. */ + if (the_low_target.set_pc != NULL) + (*the_low_target.set_pc) (stop_pc); + + /* We consumed the pending SIGTRAP. */ + event_child->pending_is_breakpoint = 0; + event_child->status_pending_p = 0; + event_child->status_pending = 0; + + current_inferior = saved_inferior; + return 1; +} + +/* Return 1 if this process has an interesting status pending. This function + may silently resume an inferior process. */ +static int +status_pending_p (struct inferior_list_entry *entry, void *dummy) +{ + struct process_info *process = (struct process_info *) entry; + + if (process->status_pending_p) + if (check_removed_breakpoint (process)) + { + /* This thread was stopped at a breakpoint, and the breakpoint + is now gone. We were told to continue (or step...) all threads, + so GDB isn't trying to single-step past this breakpoint. + So instead of reporting the old SIGTRAP, pretend we got to + the breakpoint just after it was removed instead of just + before; resume the process. */ + linux_resume_one_process (&process->head, 0, 0, NULL); + return 0; + } + + return process->status_pending_p; +} + +static void +linux_wait_for_process (struct process_info **childp, int *wstatp) +{ + int ret; + int to_wait_for = -1; + + if (*childp != NULL) + to_wait_for = (*childp)->lwpid; + +retry: + while (1) + { + ret = waitpid (to_wait_for, wstatp, WNOHANG); + + if (ret == -1) + { + if (errno != ECHILD) + perror_with_name ("waitpid"); + } + else if (ret > 0) + break; + + ret = waitpid (to_wait_for, wstatp, WNOHANG | __WCLONE); + + if (ret == -1) + { + if (errno != ECHILD) + perror_with_name ("waitpid (WCLONE)"); + } + else if (ret > 0) + break; + + usleep (1000); + } + + if (debug_threads + && (!WIFSTOPPED (*wstatp) + || (WSTOPSIG (*wstatp) != 32 + && WSTOPSIG (*wstatp) != 33))) + fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp); + + if (to_wait_for == -1) + *childp = (struct process_info *) find_inferior_id (&all_processes, ret); + + /* If we didn't find a process, one of two things presumably happened: + - A process we started and then detached from has exited. Ignore it. + - A process we are controlling has forked and the new child's stop + was reported to us by the kernel. Save its PID. */ + if (*childp == NULL && WIFSTOPPED (*wstatp)) + { + add_pid_to_list (&stopped_pids, ret); + goto retry; + } + else if (*childp == NULL) + goto retry; + + (*childp)->stopped = 1; + (*childp)->pending_is_breakpoint = 0; + + (*childp)->last_status = *wstatp; + + if (debug_threads + && WIFSTOPPED (*wstatp)) + { + current_inferior = (struct thread_info *) + find_inferior_id (&all_threads, (*childp)->lwpid); + /* For testing only; i386_stop_pc prints out a diagnostic. */ + if (the_low_target.get_pc != NULL) + get_stop_pc (); + } +} + +static int +linux_wait_for_event (struct thread_info *child) +{ + CORE_ADDR stop_pc; + struct process_info *event_child; + int wstat; + int bp_status; + + /* Check for a process with a pending status. */ + /* It is possible that the user changed the pending task's registers since + it stopped. We correctly handle the change of PC if we hit a breakpoint + (in check_removed_breakpoint); signals should be reported anyway. */ + if (child == NULL) + { + event_child = (struct process_info *) + find_inferior (&all_processes, status_pending_p, NULL); + if (debug_threads && event_child) + fprintf (stderr, "Got a pending child %ld\n", event_child->lwpid); + } + else + { + event_child = get_thread_process (child); + if (event_child->status_pending_p + && check_removed_breakpoint (event_child)) + event_child = NULL; + } + + if (event_child != NULL) + { + if (event_child->status_pending_p) + { + if (debug_threads) + fprintf (stderr, "Got an event from pending child %ld (%04x)\n", + event_child->lwpid, event_child->status_pending); + wstat = event_child->status_pending; + event_child->status_pending_p = 0; + event_child->status_pending = 0; + current_inferior = get_process_thread (event_child); + return wstat; + } + } + + /* We only enter this loop if no process has a pending wait status. Thus + any action taken in response to a wait status inside this loop is + responding as soon as we detect the status, not after any pending + events. */ + while (1) + { + if (child == NULL) + event_child = NULL; + else + event_child = get_thread_process (child); + + linux_wait_for_process (&event_child, &wstat); + + if (event_child == NULL) + error ("event from unknown child"); + + current_inferior = (struct thread_info *) + find_inferior_id (&all_threads, event_child->lwpid); + + /* Check for thread exit. */ + if (! WIFSTOPPED (wstat)) + { + if (debug_threads) + fprintf (stderr, "LWP %ld exiting\n", event_child->head.id); + + /* If the last thread is exiting, just return. */ + if (all_threads.head == all_threads.tail) + return wstat; + + dead_thread_notify (thread_id_to_gdb_id (event_child->lwpid)); + + remove_inferior (&all_processes, &event_child->head); + free (event_child); + remove_thread (current_inferior); + current_inferior = (struct thread_info *) all_threads.head; + + /* If we were waiting for this particular child to do something... + well, it did something. */ + if (child != NULL) + return wstat; + + /* Wait for a more interesting event. */ + continue; + } + + if (WIFSTOPPED (wstat) + && WSTOPSIG (wstat) == SIGSTOP + && event_child->stop_expected) + { + if (debug_threads) + fprintf (stderr, "Expected stop.\n"); + event_child->stop_expected = 0; + linux_resume_one_process (&event_child->head, + event_child->stepping, 0, NULL); + continue; + } + + if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP + && wstat >> 16 != 0) + { + handle_extended_wait (event_child, wstat); + continue; + } + + /* If GDB is not interested in this signal, don't stop other + threads, and don't report it to GDB. Just resume the + inferior right away. We do this for threading-related + signals as well as any that GDB specifically requested we + ignore. But never ignore SIGSTOP if we sent it ourselves, + and do not ignore signals when stepping - they may require + special handling to skip the signal handler. */ + /* FIXME drow/2002-06-09: Get signal numbers from the inferior's + thread library? */ + if (WIFSTOPPED (wstat) + && !event_child->stepping + && ( +#ifdef USE_THREAD_DB + (thread_db_active && (WSTOPSIG (wstat) == __SIGRTMIN + || WSTOPSIG (wstat) == __SIGRTMIN + 1)) + || +#endif + (pass_signals[target_signal_from_host (WSTOPSIG (wstat))] + && (WSTOPSIG (wstat) != SIGSTOP || !stopping_threads)))) + { + siginfo_t info, *info_p; + + if (debug_threads) + fprintf (stderr, "Ignored signal %d for LWP %ld.\n", + WSTOPSIG (wstat), event_child->head.id); + + if (ptrace (PTRACE_GETSIGINFO, event_child->lwpid, 0, &info) == 0) + info_p = &info; + else + info_p = NULL; + linux_resume_one_process (&event_child->head, + event_child->stepping, + WSTOPSIG (wstat), info_p); + continue; + } + + /* If this event was not handled above, and is not a SIGTRAP, report + it. */ + if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGTRAP) + return wstat; + + /* If this target does not support breakpoints, we simply report the + SIGTRAP; it's of no concern to us. */ + if (the_low_target.get_pc == NULL) + return wstat; + + stop_pc = get_stop_pc (); + + /* bp_reinsert will only be set if we were single-stepping. + Notice that we will resume the process after hitting + a gdbserver breakpoint; single-stepping to/over one + is not supported (yet). */ + if (event_child->bp_reinsert != 0) + { + if (debug_threads) + fprintf (stderr, "Reinserted breakpoint.\n"); + reinsert_breakpoint (event_child->bp_reinsert); + event_child->bp_reinsert = 0; + + /* Clear the single-stepping flag and SIGTRAP as we resume. */ + linux_resume_one_process (&event_child->head, 0, 0, NULL); + continue; + } + + bp_status = check_breakpoints (stop_pc); + + if (bp_status != 0) + { + if (debug_threads) + fprintf (stderr, "Hit a gdbserver breakpoint.\n"); + + /* We hit one of our own breakpoints. We mark it as a pending + breakpoint, so that check_removed_breakpoint () will do the PC + adjustment for us at the appropriate time. */ + event_child->pending_is_breakpoint = 1; + event_child->pending_stop_pc = stop_pc; + + /* We may need to put the breakpoint back. We continue in the event + loop instead of simply replacing the breakpoint right away, + in order to not lose signals sent to the thread that hit the + breakpoint. Unfortunately this increases the window where another + thread could sneak past the removed breakpoint. For the current + use of server-side breakpoints (thread creation) this is + acceptable; but it needs to be considered before this breakpoint + mechanism can be used in more general ways. For some breakpoints + it may be necessary to stop all other threads, but that should + be avoided where possible. + + If breakpoint_reinsert_addr is NULL, that means that we can + use PTRACE_SINGLESTEP on this platform. Uninsert the breakpoint, + mark it for reinsertion, and single-step. + + Otherwise, call the target function to figure out where we need + our temporary breakpoint, create it, and continue executing this + process. */ + if (bp_status == 2) + /* No need to reinsert. */ + linux_resume_one_process (&event_child->head, 0, 0, NULL); + else if (the_low_target.breakpoint_reinsert_addr == NULL) + { + event_child->bp_reinsert = stop_pc; + uninsert_breakpoint (stop_pc); + linux_resume_one_process (&event_child->head, 1, 0, NULL); + } + else + { + reinsert_breakpoint_by_bp + (stop_pc, (*the_low_target.breakpoint_reinsert_addr) ()); + linux_resume_one_process (&event_child->head, 0, 0, NULL); + } + + continue; + } + + if (debug_threads) + fprintf (stderr, "Hit a non-gdbserver breakpoint.\n"); + + /* If we were single-stepping, we definitely want to report the + SIGTRAP. The single-step operation has completed, so also + clear the stepping flag; in general this does not matter, + because the SIGTRAP will be reported to the client, which + will give us a new action for this thread, but clear it for + consistency anyway. It's safe to clear the stepping flag + because the only consumer of get_stop_pc () after this point + is check_removed_breakpoint, and pending_is_breakpoint is not + set. It might be wiser to use a step_completed flag instead. */ + if (event_child->stepping) + { + event_child->stepping = 0; + return wstat; + } + + /* A SIGTRAP that we can't explain. It may have been a breakpoint. + Check if it is a breakpoint, and if so mark the process information + accordingly. This will handle both the necessary fiddling with the + PC on decr_pc_after_break targets and suppressing extra threads + hitting a breakpoint if two hit it at once and then GDB removes it + after the first is reported. Arguably it would be better to report + multiple threads hitting breakpoints simultaneously, but the current + remote protocol does not allow this. */ + if ((*the_low_target.breakpoint_at) (stop_pc)) + { + event_child->pending_is_breakpoint = 1; + event_child->pending_stop_pc = stop_pc; + } + + return wstat; + } + + /* NOTREACHED */ + return 0; +} + +/* Wait for process, returns status. */ + +static unsigned char +linux_wait (char *status) +{ + int w; + struct thread_info *child = NULL; + +retry: + /* If we were only supposed to resume one thread, only wait for + that thread - if it's still alive. If it died, however - which + can happen if we're coming from the thread death case below - + then we need to make sure we restart the other threads. We could + pick a thread at random or restart all; restarting all is less + arbitrary. */ + if (cont_thread != 0 && cont_thread != -1) + { + child = (struct thread_info *) find_inferior_id (&all_threads, + cont_thread); + + /* No stepping, no signal - unless one is pending already, of course. */ + if (child == NULL) + { + struct thread_resume resume_info; + resume_info.thread = -1; + resume_info.step = resume_info.sig = resume_info.leave_stopped = 0; + linux_resume (&resume_info); + } + } + + w = linux_wait_for_event (child); + stop_all_processes (); + + if (must_set_ptrace_flags) + { + ptrace (PTRACE_SETOPTIONS, inferior_pid, 0, PTRACE_O_TRACECLONE); + must_set_ptrace_flags = 0; + } + + /* If we are waiting for a particular child, and it exited, + linux_wait_for_event will return its exit status. Similarly if + the last child exited. If this is not the last child, however, + do not report it as exited until there is a 'thread exited' response + available in the remote protocol. Instead, just wait for another event. + This should be safe, because if the thread crashed we will already + have reported the termination signal to GDB; that should stop any + in-progress stepping operations, etc. + + Report the exit status of the last thread to exit. This matches + LinuxThreads' behavior. */ + + if (all_threads.head == all_threads.tail) + { + if (WIFEXITED (w)) + { + fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); + *status = 'W'; + clear_inferiors (); + free (all_processes.head); + all_processes.head = all_processes.tail = NULL; + return WEXITSTATUS (w); + } + else if (!WIFSTOPPED (w)) + { + fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); + *status = 'X'; + clear_inferiors (); + free (all_processes.head); + all_processes.head = all_processes.tail = NULL; + return target_signal_from_host (WTERMSIG (w)); + } + } + else + { + if (!WIFSTOPPED (w)) + goto retry; + } + + *status = 'T'; + return target_signal_from_host (WSTOPSIG (w)); +} + +/* Send a signal to an LWP. For LinuxThreads, kill is enough; however, if + thread groups are in use, we need to use tkill. */ + +static int +kill_lwp (unsigned long lwpid, int signo) +{ + static int tkill_failed; + + errno = 0; + +#ifdef SYS_tkill + if (!tkill_failed) + { + int ret = syscall (SYS_tkill, lwpid, signo); + if (errno != ENOSYS) + return ret; + errno = 0; + tkill_failed = 1; + } +#endif + + return kill (lwpid, signo); +} + +static void +send_sigstop (struct inferior_list_entry *entry) +{ + struct process_info *process = (struct process_info *) entry; + + if (process->stopped) + return; + + /* If we already have a pending stop signal for this process, don't + send another. */ + if (process->stop_expected) + { + if (debug_threads) + fprintf (stderr, "Have pending sigstop for process %ld\n", + process->lwpid); + + /* We clear the stop_expected flag so that wait_for_sigstop + will receive the SIGSTOP event (instead of silently resuming and + waiting again). It'll be reset below. */ + process->stop_expected = 0; + return; + } + + if (debug_threads) + fprintf (stderr, "Sending sigstop to process %ld\n", process->head.id); + + kill_lwp (process->head.id, SIGSTOP); +} + +static void +wait_for_sigstop (struct inferior_list_entry *entry) +{ + struct process_info *process = (struct process_info *) entry; + struct thread_info *saved_inferior, *thread; + int wstat; + unsigned long saved_tid; + + if (process->stopped) + return; + + saved_inferior = current_inferior; + saved_tid = ((struct inferior_list_entry *) saved_inferior)->id; + thread = (struct thread_info *) find_inferior_id (&all_threads, + process->lwpid); + wstat = linux_wait_for_event (thread); + + /* If we stopped with a non-SIGSTOP signal, save it for later + and record the pending SIGSTOP. If the process exited, just + return. */ + if (WIFSTOPPED (wstat) + && WSTOPSIG (wstat) != SIGSTOP) + { + if (debug_threads) + fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n", + process->lwpid, wstat); + process->status_pending_p = 1; + process->status_pending = wstat; + process->stop_expected = 1; + } + + if (linux_thread_alive (saved_tid)) + current_inferior = saved_inferior; + else + { + if (debug_threads) + fprintf (stderr, "Previously current thread died.\n"); + + /* Set a valid thread as current. */ + set_desired_inferior (0); + } +} + +static void +stop_all_processes (void) +{ + stopping_threads = 1; + for_each_inferior (&all_processes, send_sigstop); + for_each_inferior (&all_processes, wait_for_sigstop); + stopping_threads = 0; +} + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +static void +linux_resume_one_process (struct inferior_list_entry *entry, + int step, int signal, siginfo_t *info) +{ + struct process_info *process = (struct process_info *) entry; + struct thread_info *saved_inferior; + + if (process->stopped == 0) + return; + + /* If we have pending signals or status, and a new signal, enqueue the + signal. Also enqueue the signal if we are waiting to reinsert a + breakpoint; it will be picked up again below. */ + if (signal != 0 + && (process->status_pending_p || process->pending_signals != NULL + || process->bp_reinsert != 0)) + { + struct pending_signals *p_sig; + p_sig = malloc (sizeof (*p_sig)); + p_sig->prev = process->pending_signals; + p_sig->signal = signal; + if (info == NULL) + memset (&p_sig->info, 0, sizeof (siginfo_t)); + else + memcpy (&p_sig->info, info, sizeof (siginfo_t)); + process->pending_signals = p_sig; + } + + if (process->status_pending_p && !check_removed_breakpoint (process)) + return; + + saved_inferior = current_inferior; + current_inferior = get_process_thread (process); + + if (debug_threads) + fprintf (stderr, "Resuming process %ld (%s, signal %d, stop %s)\n", inferior_pid, + step ? "step" : "continue", signal, + process->stop_expected ? "expected" : "not expected"); + + /* This bit needs some thinking about. If we get a signal that + we must report while a single-step reinsert is still pending, + we often end up resuming the thread. It might be better to + (ew) allow a stack of pending events; then we could be sure that + the reinsert happened right away and not lose any signals. + + Making this stack would also shrink the window in which breakpoints are + uninserted (see comment in linux_wait_for_process) but not enough for + complete correctness, so it won't solve that problem. It may be + worthwhile just to solve this one, however. */ + if (process->bp_reinsert != 0) + { + if (debug_threads) + fprintf (stderr, " pending reinsert at %08lx", (long)process->bp_reinsert); + if (step == 0) + fprintf (stderr, "BAD - reinserting but not stepping.\n"); + step = 1; + + /* Postpone any pending signal. It was enqueued above. */ + signal = 0; + } + + check_removed_breakpoint (process); + + if (debug_threads && the_low_target.get_pc != NULL) + { + fprintf (stderr, " "); + (*the_low_target.get_pc) (); + } + + /* If we have pending signals, consume one unless we are trying to reinsert + a breakpoint. */ + if (process->pending_signals != NULL && process->bp_reinsert == 0) + { + struct pending_signals **p_sig; + + p_sig = &process->pending_signals; + while ((*p_sig)->prev != NULL) + p_sig = &(*p_sig)->prev; + + signal = (*p_sig)->signal; + if ((*p_sig)->info.si_signo != 0) + ptrace (PTRACE_SETSIGINFO, process->lwpid, 0, &(*p_sig)->info); + + free (*p_sig); + *p_sig = NULL; + } + + regcache_invalidate_one ((struct inferior_list_entry *) + get_process_thread (process)); + errno = 0; + process->stopped = 0; + process->stepping = step; + ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, process->lwpid, 0, signal); + + current_inferior = saved_inferior; + if (errno) + perror_with_name ("ptrace"); +} + +static struct thread_resume *resume_ptr; + +/* This function is called once per thread. We look up the thread + in RESUME_PTR, and mark the thread with a pointer to the appropriate + resume request. + + This algorithm is O(threads * resume elements), but resume elements + is small (and will remain small at least until GDB supports thread + suspension). */ +static void +linux_set_resume_request (struct inferior_list_entry *entry) +{ + struct process_info *process; + struct thread_info *thread; + int ndx; + + thread = (struct thread_info *) entry; + process = get_thread_process (thread); + + ndx = 0; + while (resume_ptr[ndx].thread != -1 && resume_ptr[ndx].thread != entry->id) + ndx++; + + process->resume = &resume_ptr[ndx]; +} + +/* This function is called once per thread. We check the thread's resume + request, which will tell us whether to resume, step, or leave the thread + stopped; and what signal, if any, it should be sent. For threads which + we aren't explicitly told otherwise, we preserve the stepping flag; this + is used for stepping over gdbserver-placed breakpoints. */ + +static void +linux_continue_one_thread (struct inferior_list_entry *entry) +{ + struct process_info *process; + struct thread_info *thread; + int step; + + thread = (struct thread_info *) entry; + process = get_thread_process (thread); + + if (process->resume->leave_stopped) + return; + + if (process->resume->thread == -1) + step = process->stepping || process->resume->step; + else + step = process->resume->step; + + linux_resume_one_process (&process->head, step, process->resume->sig, NULL); + + process->resume = NULL; +} + +/* This function is called once per thread. We check the thread's resume + request, which will tell us whether to resume, step, or leave the thread + stopped; and what signal, if any, it should be sent. We queue any needed + signals, since we won't actually resume. We already have a pending event + to report, so we don't need to preserve any step requests; they should + be re-issued if necessary. */ + +static void +linux_queue_one_thread (struct inferior_list_entry *entry) +{ + struct process_info *process; + struct thread_info *thread; + + thread = (struct thread_info *) entry; + process = get_thread_process (thread); + + if (process->resume->leave_stopped) + return; + + /* If we have a new signal, enqueue the signal. */ + if (process->resume->sig != 0) + { + struct pending_signals *p_sig; + p_sig = malloc (sizeof (*p_sig)); + p_sig->prev = process->pending_signals; + p_sig->signal = process->resume->sig; + memset (&p_sig->info, 0, sizeof (siginfo_t)); + + /* If this is the same signal we were previously stopped by, + make sure to queue its siginfo. We can ignore the return + value of ptrace; if it fails, we'll skip + PTRACE_SETSIGINFO. */ + if (WIFSTOPPED (process->last_status) + && WSTOPSIG (process->last_status) == process->resume->sig) + ptrace (PTRACE_GETSIGINFO, process->lwpid, 0, &p_sig->info); + + process->pending_signals = p_sig; + } + + process->resume = NULL; +} + +/* Set DUMMY if this process has an interesting status pending. */ +static int +resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p) +{ + struct process_info *process = (struct process_info *) entry; + + /* Processes which will not be resumed are not interesting, because + we might not wait for them next time through linux_wait. */ + if (process->resume->leave_stopped) + return 0; + + /* If this thread has a removed breakpoint, we won't have any + events to report later, so check now. check_removed_breakpoint + may clear status_pending_p. We avoid calling check_removed_breakpoint + for any thread that we are not otherwise going to resume - this + lets us preserve stopped status when two threads hit a breakpoint. + GDB removes the breakpoint to single-step a particular thread + past it, then re-inserts it and resumes all threads. We want + to report the second thread without resuming it in the interim. */ + if (process->status_pending_p) + check_removed_breakpoint (process); + + if (process->status_pending_p) + * (int *) flag_p = 1; + + return 0; +} + +static void +linux_resume (struct thread_resume *resume_info) +{ + int pending_flag; + + /* Yes, the use of a global here is rather ugly. */ + resume_ptr = resume_info; + + for_each_inferior (&all_threads, linux_set_resume_request); + + /* If there is a thread which would otherwise be resumed, which + has a pending status, then don't resume any threads - we can just + report the pending status. Make sure to queue any signals + that would otherwise be sent. */ + pending_flag = 0; + find_inferior (&all_processes, resume_status_pending_p, &pending_flag); + + if (debug_threads) + { + if (pending_flag) + fprintf (stderr, "Not resuming, pending status\n"); + else + fprintf (stderr, "Resuming, no pending status\n"); + } + + if (pending_flag) + for_each_inferior (&all_threads, linux_queue_one_thread); + else + for_each_inferior (&all_threads, linux_continue_one_thread); +} + +#ifdef HAVE_LINUX_USRREGS + +int +register_addr (int regnum) +{ + int addr; + + if (regnum < 0 || regnum >= the_low_target.num_regs) + error ("Invalid register number %d.", regnum); + + addr = the_low_target.regmap[regnum]; + + return addr; +} + +/* Fetch one register. */ +static void +fetch_register (int regno) +{ + CORE_ADDR regaddr; + int i, size; + char *buf; + + if (regno >= the_low_target.num_regs) + return; + if ((*the_low_target.cannot_fetch_register) (regno)) + return; + + regaddr = register_addr (regno); + if (regaddr == -1) + return; + size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1) + & - sizeof (PTRACE_XFER_TYPE); + buf = alloca (size); + for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + *(PTRACE_XFER_TYPE *) (buf + i) = + ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0); + regaddr += sizeof (PTRACE_XFER_TYPE); + if (errno != 0) + { + /* Warning, not error, in case we are attached; sometimes the + kernel doesn't let us at the registers. */ + char *err = strerror (errno); + char *msg = alloca (strlen (err) + 128); + sprintf (msg, "reading register %d: %s", regno, err); + error (msg); + goto error_exit; + } + } + if (the_low_target.left_pad_xfer + && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) + supply_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) + - register_size (regno))); + else + supply_register (regno, buf); + +error_exit:; +} + +/* Fetch all registers, or just one, from the child process. */ +static void +usr_fetch_inferior_registers (int regno) +{ + if (regno == -1 || regno == 0) + for (regno = 0; regno < the_low_target.num_regs; regno++) + fetch_register (regno); + else + fetch_register (regno); +} + +/* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ +static void +usr_store_inferior_registers (int regno) +{ + CORE_ADDR regaddr; + int i, size; + char *buf; + + if (regno >= 0) + { + if (regno >= the_low_target.num_regs) + return; + + if ((*the_low_target.cannot_store_register) (regno) == 1) + return; + + regaddr = register_addr (regno); + if (regaddr == -1) + return; + errno = 0; + size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1) + & - sizeof (PTRACE_XFER_TYPE); + buf = alloca (size); + memset (buf, 0, size); + if (the_low_target.left_pad_xfer + && register_size (regno) < sizeof (PTRACE_XFER_TYPE)) + collect_register (regno, (buf + sizeof (PTRACE_XFER_TYPE) + - register_size (regno))); + else + collect_register (regno, buf); + for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(PTRACE_XFER_TYPE *) (buf + i)); + if (errno != 0) + { + if ((*the_low_target.cannot_store_register) (regno) == 0) + { + char *err = strerror (errno); + char *msg = alloca (strlen (err) + 128); + sprintf (msg, "writing register %d: %s", + regno, err); + error (msg); + return; + } + } + regaddr += sizeof (PTRACE_XFER_TYPE); + } + } + else + for (regno = 0; regno < the_low_target.num_regs; regno++) + usr_store_inferior_registers (regno); +} +#endif /* HAVE_LINUX_USRREGS */ + + + +#ifdef HAVE_LINUX_REGSETS + +static int +regsets_fetch_inferior_registers () +{ + struct regset_info *regset; + int saw_general_regs = 0; + + regset = target_regsets; + + while (regset->size >= 0) + { + void *buf; + int res; + + if (regset->size == 0) + { + regset ++; + continue; + } + + buf = malloc (regset->size); + res = ptrace (regset->get_request, inferior_pid, 0, buf); + if (res < 0) + { + if (errno == EIO) + { + /* If we get EIO on the first regset, do not try regsets again. + If we get EIO on a later regset, disable that regset. */ + if (regset == target_regsets) + { + use_regsets_p = 0; + return -1; + } + else + { + regset->size = 0; + continue; + } + } + else + { + char s[256]; + sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%ld", + inferior_pid); + perror (s); + } + } + else if (regset->type == GENERAL_REGS) + saw_general_regs = 1; + regset->store_function (buf); + regset ++; + } + if (saw_general_regs) + return 0; + else + return 1; +} + +static int +regsets_store_inferior_registers () +{ + struct regset_info *regset; + int saw_general_regs = 0; + + regset = target_regsets; + + while (regset->size >= 0) + { + void *buf; + int res; + + if (regset->size == 0) + { + regset ++; + continue; + } + + buf = malloc (regset->size); + + /* First fill the buffer with the current register set contents, + in case there are any items in the kernel's regset that are + not in gdbserver's regcache. */ + res = ptrace (regset->get_request, inferior_pid, 0, buf); + + if (res == 0) + { + /* Then overlay our cached registers on that. */ + regset->fill_function (buf); + + /* Only now do we write the register set. */ + res = ptrace (regset->set_request, inferior_pid, 0, buf); + } + + if (res < 0) + { + if (errno == EIO) + { + /* If we get EIO on the first regset, do not try regsets again. + If we get EIO on a later regset, disable that regset. */ + if (regset == target_regsets) + { + use_regsets_p = 0; + return -1; + } + else + { + regset->size = 0; + continue; + } + } + else + { + perror ("Warning: ptrace(regsets_store_inferior_registers)"); + } + } + else if (regset->type == GENERAL_REGS) + saw_general_regs = 1; + regset ++; + free (buf); + } + if (saw_general_regs) + return 0; + else + return 1; + return 0; +} + +#endif /* HAVE_LINUX_REGSETS */ + + +void +linux_fetch_registers (int regno) +{ +#ifdef HAVE_LINUX_REGSETS + if (use_regsets_p) + { + if (regsets_fetch_inferior_registers () == 0) + return; + } +#endif +#ifdef HAVE_LINUX_USRREGS + usr_fetch_inferior_registers (regno); +#endif +} + +void +linux_store_registers (int regno) +{ +#ifdef HAVE_LINUX_REGSETS + if (use_regsets_p) + { + if (regsets_store_inferior_registers () == 0) + return; + } +#endif +#ifdef HAVE_LINUX_USRREGS + usr_store_inferior_registers (regno); +#endif +} + + +/* Copy LEN bytes from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. */ + +static int +linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) + / sizeof (PTRACE_XFER_TYPE); + /* Allocate buffer of that many longwords. */ + register PTRACE_XFER_TYPE *buffer + = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); + int fd; + char filename[64]; + + /* Try using /proc. Don't bother for one word. */ + if (len >= 3 * sizeof (long)) + { + /* We could keep this file open and cache it - possibly one per + thread. That requires some juggling, but is even faster. */ + sprintf (filename, "/proc/%ld/mem", inferior_pid); + fd = open (filename, O_RDONLY | O_LARGEFILE); + if (fd == -1) + goto no_proc; + + /* If pread64 is available, use it. It's faster if the kernel + supports it (only one syscall), and it's 64-bit safe even on + 32-bit platforms (for instance, SPARC debugging a SPARC64 + application). */ +#ifdef HAVE_PREAD64 + if (pread64 (fd, myaddr, len, memaddr) != len) +#else + if (lseek (fd, memaddr, SEEK_SET) == -1 || read (fd, memaddr, len) != len) +#endif + { + close (fd); + goto no_proc; + } + + close (fd); + return 0; + } + + no_proc: + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); + if (errno) + return errno; + } + + /* Copy appropriate bytes out of the buffer. */ + memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); + + return 0; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. + On failure (cannot write the inferior) + returns the value of errno. */ + +static int +linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len) +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE); + /* Allocate buffer of that many longwords. */ + register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); + extern int errno; + + if (debug_threads) + { + fprintf (stderr, "Writing %02x to %08lx\n", (unsigned)myaddr[0], (long)memaddr); + } + + /* Fill start and end extra bytes of buffer with existing memory data. */ + + buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, + (PTRACE_ARG3_TYPE) addr, 0); + + if (count > 1) + { + buffer[count - 1] + = ptrace (PTRACE_PEEKTEXT, inferior_pid, + (PTRACE_ARG3_TYPE) (addr + (count - 1) + * sizeof (PTRACE_XFER_TYPE)), + 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) + { + errno = 0; + ptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]); + if (errno) + return errno; + } + + return 0; +} + +static int linux_supports_tracefork_flag; + +/* Helper functions for linux_test_for_tracefork, called via clone (). */ + +static int +linux_tracefork_grandchild (void *arg) +{ + _exit (0); +} + +#define STACK_SIZE 4096 + +static int +linux_tracefork_child (void *arg) +{ + ptrace (PTRACE_TRACEME, 0, 0, 0); + kill (getpid (), SIGSTOP); +#ifdef __ia64__ + __clone2 (linux_tracefork_grandchild, arg, STACK_SIZE, + CLONE_VM | SIGCHLD, NULL); +#else + clone (linux_tracefork_grandchild, arg + STACK_SIZE, + CLONE_VM | SIGCHLD, NULL); +#endif + _exit (0); +} + +/* Wrapper function for waitpid which handles EINTR. */ + +static int +my_waitpid (int pid, int *status, int flags) +{ + int ret; + do + { + ret = waitpid (pid, status, flags); + } + while (ret == -1 && errno == EINTR); + + return ret; +} + +/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events. Make + sure that we can enable the option, and that it had the desired + effect. */ + +static void +linux_test_for_tracefork (void) +{ + int child_pid, ret, status; + long second_pid; + char *stack = malloc (STACK_SIZE * 4); + + linux_supports_tracefork_flag = 0; + + /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */ +#ifdef __ia64__ + child_pid = __clone2 (linux_tracefork_child, stack, STACK_SIZE, + CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2); +#else + child_pid = clone (linux_tracefork_child, stack + STACK_SIZE, + CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2); +#endif + if (child_pid == -1) + perror_with_name ("clone"); + + ret = my_waitpid (child_pid, &status, 0); + if (ret == -1) + perror_with_name ("waitpid"); + else if (ret != child_pid) + error ("linux_test_for_tracefork: waitpid: unexpected result %d.", ret); + if (! WIFSTOPPED (status)) + error ("linux_test_for_tracefork: waitpid: unexpected status %d.", status); + + ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK); + if (ret != 0) + { + ret = ptrace (PTRACE_KILL, child_pid, 0, 0); + if (ret != 0) + { + warning ("linux_test_for_tracefork: failed to kill child"); + return; + } + + ret = my_waitpid (child_pid, &status, 0); + if (ret != child_pid) + warning ("linux_test_for_tracefork: failed to wait for killed child"); + else if (!WIFSIGNALED (status)) + warning ("linux_test_for_tracefork: unexpected wait status 0x%x from " + "killed child", status); + + return; + } + + ret = ptrace (PTRACE_CONT, child_pid, 0, 0); + if (ret != 0) + warning ("linux_test_for_tracefork: failed to resume child"); + + ret = my_waitpid (child_pid, &status, 0); + + if (ret == child_pid && WIFSTOPPED (status) + && status >> 16 == PTRACE_EVENT_FORK) + { + second_pid = 0; + ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid); + if (ret == 0 && second_pid != 0) + { + int second_status; + + linux_supports_tracefork_flag = 1; + my_waitpid (second_pid, &second_status, 0); + ret = ptrace (PTRACE_KILL, second_pid, 0, 0); + if (ret != 0) + warning ("linux_test_for_tracefork: failed to kill second child"); + my_waitpid (second_pid, &status, 0); + } + } + else + warning ("linux_test_for_tracefork: unexpected result from waitpid " + "(%d, status 0x%x)", ret, status); + + do + { + ret = ptrace (PTRACE_KILL, child_pid, 0, 0); + if (ret != 0) + warning ("linux_test_for_tracefork: failed to kill child"); + my_waitpid (child_pid, &status, 0); + } + while (WIFSTOPPED (status)); + + free (stack); +} + + +static void +linux_look_up_symbols (void) +{ +#ifdef USE_THREAD_DB + if (thread_db_active) + return; + + thread_db_active = thread_db_init (!linux_supports_tracefork_flag); +#endif +} + +static void +linux_request_interrupt (void) +{ + extern unsigned long signal_pid; + + if (cont_thread != 0 && cont_thread != -1) + { + struct process_info *process; + + process = get_thread_process (current_inferior); + kill_lwp (process->lwpid, SIGINT); + } + else + kill_lwp (signal_pid, SIGINT); +} + +/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET + to debugger memory starting at MYADDR. */ + +static int +linux_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len) +{ + char filename[PATH_MAX]; + int fd, n; + + snprintf (filename, sizeof filename, "/proc/%ld/auxv", inferior_pid); + + fd = open (filename, O_RDONLY); + if (fd < 0) + return -1; + + if (offset != (CORE_ADDR) 0 + && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) + n = -1; + else + n = read (fd, myaddr, len); + + close (fd); + + return n; +} + +/* These watchpoint related wrapper functions simply pass on the function call + if the target has registered a corresponding function. */ + +static int +linux_insert_watchpoint (char type, CORE_ADDR addr, int len) +{ + if (the_low_target.insert_watchpoint != NULL) + return the_low_target.insert_watchpoint (type, addr, len); + else + /* Unsupported (see target.h). */ + return 1; +} + +static int +linux_remove_watchpoint (char type, CORE_ADDR addr, int len) +{ + if (the_low_target.remove_watchpoint != NULL) + return the_low_target.remove_watchpoint (type, addr, len); + else + /* Unsupported (see target.h). */ + return 1; +} + +static int +linux_stopped_by_watchpoint (void) +{ + if (the_low_target.stopped_by_watchpoint != NULL) + return the_low_target.stopped_by_watchpoint (); + else + return 0; +} + +static CORE_ADDR +linux_stopped_data_address (void) +{ + if (the_low_target.stopped_data_address != NULL) + return the_low_target.stopped_data_address (); + else + return 0; +} + +#if defined(__UCLIBC__) && defined(HAS_NOMMU) +#if defined(__mcoldfire__) +/* These should really be defined in the kernel's ptrace.h header. */ +#define PT_TEXT_ADDR 49*4 +#define PT_DATA_ADDR 50*4 +#define PT_TEXT_END_ADDR 51*4 +#endif + +/* Under uClinux, programs are loaded at non-zero offsets, which we need + to tell gdb about. */ + +static int +linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p) +{ +#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_END_ADDR) + unsigned long text, text_end, data; + int pid = get_thread_process (current_inferior)->head.id; + + errno = 0; + + text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0); + text_end = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_END_ADDR, 0); + data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0); + + if (errno == 0) + { + /* Both text and data offsets produced at compile-time (and so + used by gdb) are relative to the beginning of the program, + with the data segment immediately following the text segment. + However, the actual runtime layout in memory may put the data + somewhere else, so when we send gdb a data base-address, we + use the real data base address and subtract the compile-time + data base-address from it (which is just the length of the + text segment). BSS immediately follows data in both + cases. */ + *text_p = text; + *data_p = data - (text_end - text); + + return 1; + } +#endif + return 0; +} +#endif + +static const char * +linux_arch_string (void) +{ + return the_low_target.arch_string; +} + +static struct target_ops linux_target_ops = { + linux_create_inferior, + linux_attach, + linux_kill, + linux_detach, + linux_join, + linux_thread_alive, + linux_resume, + linux_wait, + linux_fetch_registers, + linux_store_registers, + linux_read_memory, + linux_write_memory, + linux_look_up_symbols, + linux_request_interrupt, + linux_read_auxv, + linux_insert_watchpoint, + linux_remove_watchpoint, + linux_stopped_by_watchpoint, + linux_stopped_data_address, +#if defined(__UCLIBC__) && defined(HAS_NOMMU) + linux_read_offsets, +#else + NULL, +#endif +#ifdef USE_THREAD_DB + thread_db_get_tls_address, +#else + NULL, +#endif + linux_arch_string, + NULL, + hostio_last_error_from_errno, +}; + +static void +linux_init_signals () +{ + /* FIXME drow/2002-06-09: As above, we should check with LinuxThreads + to find what the cancel signal actually is. */ + signal (__SIGRTMIN+1, SIG_IGN); +} + +void +initialize_low (void) +{ + thread_db_active = 0; + set_target_ops (&linux_target_ops); + set_breakpoint_data (the_low_target.breakpoint, + the_low_target.breakpoint_len); + init_registers (); + linux_init_signals (); + linux_test_for_tracefork (); +}
linux-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-ia64-low.c =================================================================== --- linux-ia64-low.c (nonexistent) +++ linux-ia64-low.c (revision 816) @@ -0,0 +1,283 @@ +/* GNU/Linux/IA64 specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#define ia64_num_regs 462 + +#include + +static int ia64_regmap[] = + { + /* general registers */ + -1, /* gr0 not available; i.e, it's always zero */ + PT_R1, + PT_R2, + PT_R3, + PT_R4, + PT_R5, + PT_R6, + PT_R7, + PT_R8, + PT_R9, + PT_R10, + PT_R11, + PT_R12, + PT_R13, + PT_R14, + PT_R15, + PT_R16, + PT_R17, + PT_R18, + PT_R19, + PT_R20, + PT_R21, + PT_R22, + PT_R23, + PT_R24, + PT_R25, + PT_R26, + PT_R27, + PT_R28, + PT_R29, + PT_R30, + PT_R31, + /* gr32 through gr127 not directly available via the ptrace interface */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* Floating point registers */ + -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */ + PT_F2, + PT_F3, + PT_F4, + PT_F5, + PT_F6, + PT_F7, + PT_F8, + PT_F9, + PT_F10, + PT_F11, + PT_F12, + PT_F13, + PT_F14, + PT_F15, + PT_F16, + PT_F17, + PT_F18, + PT_F19, + PT_F20, + PT_F21, + PT_F22, + PT_F23, + PT_F24, + PT_F25, + PT_F26, + PT_F27, + PT_F28, + PT_F29, + PT_F30, + PT_F31, + PT_F32, + PT_F33, + PT_F34, + PT_F35, + PT_F36, + PT_F37, + PT_F38, + PT_F39, + PT_F40, + PT_F41, + PT_F42, + PT_F43, + PT_F44, + PT_F45, + PT_F46, + PT_F47, + PT_F48, + PT_F49, + PT_F50, + PT_F51, + PT_F52, + PT_F53, + PT_F54, + PT_F55, + PT_F56, + PT_F57, + PT_F58, + PT_F59, + PT_F60, + PT_F61, + PT_F62, + PT_F63, + PT_F64, + PT_F65, + PT_F66, + PT_F67, + PT_F68, + PT_F69, + PT_F70, + PT_F71, + PT_F72, + PT_F73, + PT_F74, + PT_F75, + PT_F76, + PT_F77, + PT_F78, + PT_F79, + PT_F80, + PT_F81, + PT_F82, + PT_F83, + PT_F84, + PT_F85, + PT_F86, + PT_F87, + PT_F88, + PT_F89, + PT_F90, + PT_F91, + PT_F92, + PT_F93, + PT_F94, + PT_F95, + PT_F96, + PT_F97, + PT_F98, + PT_F99, + PT_F100, + PT_F101, + PT_F102, + PT_F103, + PT_F104, + PT_F105, + PT_F106, + PT_F107, + PT_F108, + PT_F109, + PT_F110, + PT_F111, + PT_F112, + PT_F113, + PT_F114, + PT_F115, + PT_F116, + PT_F117, + PT_F118, + PT_F119, + PT_F120, + PT_F121, + PT_F122, + PT_F123, + PT_F124, + PT_F125, + PT_F126, + PT_F127, + /* predicate registers - we don't fetch these individually */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* branch registers */ + PT_B0, + PT_B1, + PT_B2, + PT_B3, + PT_B4, + PT_B5, + PT_B6, + PT_B7, + /* virtual frame pointer and virtual return address pointer */ + -1, -1, + /* other registers */ + PT_PR, + PT_CR_IIP, /* ip */ + PT_CR_IPSR, /* psr */ + PT_CFM, /* cfm */ + /* kernel registers not visible via ptrace interface (?) */ + -1, -1, -1, -1, -1, -1, -1, -1, + /* hole */ + -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_RSC, + PT_AR_BSP, + PT_AR_BSPSTORE, + PT_AR_RNAT, + -1, + -1, /* Not available: FCR, IA32 floating control register */ + -1, -1, + -1, /* Not available: EFLAG */ + -1, /* Not available: CSD */ + -1, /* Not available: SSD */ + -1, /* Not available: CFLG */ + -1, /* Not available: FSR */ + -1, /* Not available: FIR */ + -1, /* Not available: FDR */ + -1, + PT_AR_CCV, + -1, -1, -1, + PT_AR_UNAT, + -1, -1, -1, + PT_AR_FPSR, + -1, -1, -1, + -1, /* Not available: ITC */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_PFS, + PT_AR_LC, + -1, /* Not available: EC, the Epilog Count register */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, + }; + +static int +ia64_cannot_store_register (int regno) +{ + return 0; +} + +static int +ia64_cannot_fetch_register (int regno) +{ + return 0; +} + +struct linux_target_ops the_low_target = { + ia64_num_regs, + ia64_regmap, + ia64_cannot_fetch_register, + ia64_cannot_store_register, +};
linux-ia64-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: utils.c =================================================================== --- utils.c (nonexistent) +++ utils.c (revision 816) @@ -0,0 +1,98 @@ +/* General utility routines for the remote server for GDB. + Copyright (C) 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002, 2003, + 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include +#include +#include +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_MALLOC_H +#include +#endif + +/* Generally useful subroutines used throughout the program. */ + +/* Print the system error message for errno, and also mention STRING + as the file name for which the error was encountered. + Then return to command level. */ + +void +perror_with_name (char *string) +{ + const char *err; + char *combined; + + err = strerror (errno); + if (err == NULL) + err = "unknown error"; + + combined = (char *) alloca (strlen (err) + strlen (string) + 3); + strcpy (combined, string); + strcat (combined, ": "); + strcat (combined, err); + + error ("%s.", combined); +} + +/* Print an error message and return to command level. + STRING is the error message, used as a fprintf string, + and ARG is passed as an argument to it. */ + +void +error (const char *string,...) +{ + extern jmp_buf toplevel; + va_list args; + va_start (args, string); + fflush (stdout); + vfprintf (stderr, string, args); + fprintf (stderr, "\n"); + longjmp (toplevel, 1); +} + +/* Print an error message and exit reporting failure. + This is for a error that we cannot continue from. + STRING and ARG are passed to fprintf. */ + +/* VARARGS */ +void +fatal (const char *string,...) +{ + va_list args; + va_start (args, string); + fprintf (stderr, "gdbserver: "); + vfprintf (stderr, string, args); + fprintf (stderr, "\n"); + va_end (args); + exit (1); +} + +/* VARARGS */ +void +warning (const char *string,...) +{ + va_list args; + va_start (args, string); + fprintf (stderr, "gdbserver: "); + vfprintf (stderr, string, args); + fprintf (stderr, "\n"); + va_end (args); +}
utils.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: regcache.c =================================================================== --- regcache.c (nonexistent) +++ regcache.c (revision 816) @@ -0,0 +1,238 @@ +/* Register support routines for the remote server for GDB. + Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "regdef.h" + +#include +#include + +/* The private data for the register cache. Note that we have one + per inferior; this is primarily for simplicity, as the performance + benefit is minimal. */ + +struct inferior_regcache_data +{ + int registers_valid; + unsigned char *registers; +}; + +static int register_bytes; + +static struct reg *reg_defs; +static int num_registers; + +const char **gdbserver_expedite_regs; + +static struct inferior_regcache_data * +get_regcache (struct thread_info *inf, int fetch) +{ + struct inferior_regcache_data *regcache; + + regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf); + + if (regcache == NULL) + fatal ("no register cache"); + + /* FIXME - fetch registers for INF */ + if (fetch && regcache->registers_valid == 0) + { + fetch_inferior_registers (0); + regcache->registers_valid = 1; + } + + return regcache; +} + +void +regcache_invalidate_one (struct inferior_list_entry *entry) +{ + struct thread_info *thread = (struct thread_info *) entry; + struct inferior_regcache_data *regcache; + + regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread); + + if (regcache->registers_valid) + { + struct thread_info *saved_inferior = current_inferior; + + current_inferior = thread; + store_inferior_registers (-1); + current_inferior = saved_inferior; + } + + regcache->registers_valid = 0; +} + +void +regcache_invalidate () +{ + for_each_inferior (&all_threads, regcache_invalidate_one); +} + +int +registers_length (void) +{ + return 2 * register_bytes; +} + +void * +new_register_cache (void) +{ + struct inferior_regcache_data *regcache; + + regcache = malloc (sizeof (*regcache)); + + /* Make sure to zero-initialize the register cache when it is created, + in case there are registers the target never fetches. This way they'll + read as zero instead of garbage. */ + regcache->registers = calloc (1, register_bytes); + if (regcache->registers == NULL) + fatal ("Could not allocate register cache."); + + regcache->registers_valid = 0; + + return regcache; +} + +void +free_register_cache (void *regcache_p) +{ + struct inferior_regcache_data *regcache + = (struct inferior_regcache_data *) regcache_p; + + free (regcache->registers); + free (regcache); +} + +void +set_register_cache (struct reg *regs, int n) +{ + int offset, i; + + reg_defs = regs; + num_registers = n; + + offset = 0; + for (i = 0; i < n; i++) + { + regs[i].offset = offset; + offset += regs[i].size; + } + + register_bytes = offset / 8; +} + +void +registers_to_string (char *buf) +{ + unsigned char *registers = get_regcache (current_inferior, 1)->registers; + + convert_int_to_ascii (registers, buf, register_bytes); +} + +void +registers_from_string (char *buf) +{ + int len = strlen (buf); + unsigned char *registers = get_regcache (current_inferior, 1)->registers; + + if (len != register_bytes * 2) + { + warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len); + if (len > register_bytes * 2) + len = register_bytes * 2; + } + convert_ascii_to_int (buf, registers, len / 2); +} + +struct reg * +find_register_by_name (const char *name) +{ + int i; + + for (i = 0; i < num_registers; i++) + if (!strcmp (name, reg_defs[i].name)) + return ®_defs[i]; + fatal ("Unknown register %s requested", name); + return 0; +} + +int +find_regno (const char *name) +{ + int i; + + for (i = 0; i < num_registers; i++) + if (!strcmp (name, reg_defs[i].name)) + return i; + fatal ("Unknown register %s requested", name); + return -1; +} + +struct reg * +find_register_by_number (int n) +{ + return ®_defs[n]; +} + +int +register_size (int n) +{ + return reg_defs[n].size / 8; +} + +static unsigned char * +register_data (int n, int fetch) +{ + unsigned char *registers + = get_regcache (current_inferior, fetch)->registers; + + return registers + (reg_defs[n].offset / 8); +} + +void +supply_register (int n, const void *buf) +{ + memcpy (register_data (n, 0), buf, register_size (n)); +} + +void +supply_register_by_name (const char *name, const void *buf) +{ + supply_register (find_regno (name), buf); +} + +void +collect_register (int n, void *buf) +{ + memcpy (buf, register_data (n, 1), register_size (n)); +} + +void +collect_register_as_string (int n, char *buf) +{ + convert_int_to_ascii (register_data (n, 1), buf, register_size (n)); +} + +void +collect_register_by_name (const char *name, void *buf) +{ + collect_register (find_regno (name), buf); +}
regcache.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: win32-low.c =================================================================== --- win32-low.c (nonexistent) +++ win32-low.c (revision 816) @@ -0,0 +1,1744 @@ +/* Low level interface to Windows debugging, for gdbserver. + Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + + Contributed by Leo Zayas. Based on "win32-nat.c" from GDB. + + 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 3 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, see . */ + +#include "server.h" +#include "regcache.h" +#include "gdb/signals.h" +#include "gdb/fileio.h" +#include "mem-break.h" +#include "win32-low.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef USE_WIN32API +#include +#endif + +#define LOG 0 + +#define OUTMSG(X) do { printf X; fflush (stdout); } while (0) +#if LOG +#define OUTMSG2(X) do { printf X; fflush (stdout); } while (0) +#else +#define OUTMSG2(X) do ; while (0) +#endif + +#ifndef _T +#define _T(x) TEXT (x) +#endif + +#ifndef COUNTOF +#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0])) +#endif + +#ifdef _WIN32_WCE +# define GETPROCADDRESS(DLL, PROC) \ + ((winapi_ ## PROC) GetProcAddress (DLL, TEXT (#PROC))) +#else +# define GETPROCADDRESS(DLL, PROC) \ + ((winapi_ ## PROC) GetProcAddress (DLL, #PROC)) +#endif + +int using_threads = 1; + +/* Globals. */ +static int attaching = 0; +static HANDLE current_process_handle = NULL; +static DWORD current_process_id = 0; +static DWORD main_thread_id = 0; +static enum target_signal last_sig = TARGET_SIGNAL_0; + +/* The current debug event from WaitForDebugEvent. */ +static DEBUG_EVENT current_event; + +/* Non zero if an interrupt request is to be satisfied by suspending + all threads. */ +static int soft_interrupt_requested = 0; + +/* Non zero if the inferior is stopped in a simulated breakpoint done + by suspending all the threads. */ +static int faked_breakpoint = 0; + +#define NUM_REGS (the_low_target.num_regs) + +typedef BOOL WINAPI (*winapi_DebugActiveProcessStop) (DWORD dwProcessId); +typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit); +typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE); +typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD); + +static void win32_resume (struct thread_resume *resume_info); + +/* Get the thread ID from the current selected inferior (the current + thread). */ +static DWORD +current_inferior_tid (void) +{ + win32_thread_info *th = inferior_target_data (current_inferior); + return th->tid; +} + +/* Get the thread context of the thread associated with TH. */ + +static void +win32_get_thread_context (win32_thread_info *th) +{ + memset (&th->context, 0, sizeof (CONTEXT)); + (*the_low_target.get_thread_context) (th, ¤t_event); +#ifdef _WIN32_WCE + memcpy (&th->base_context, &th->context, sizeof (CONTEXT)); +#endif +} + +/* Set the thread context of the thread associated with TH. */ + +static void +win32_set_thread_context (win32_thread_info *th) +{ +#ifdef _WIN32_WCE + /* Calling SuspendThread on a thread that is running kernel code + will report that the suspending was successful, but in fact, that + will often not be true. In those cases, the context returned by + GetThreadContext will not be correct by the time the thread + stops, hence we can't set that context back into the thread when + resuming - it will most likelly crash the inferior. + Unfortunately, there is no way to know when the thread will + really stop. To work around it, we'll only write the context + back to the thread when either the user or GDB explicitly change + it between stopping and resuming. */ + if (memcmp (&th->context, &th->base_context, sizeof (CONTEXT)) != 0) +#endif + (*the_low_target.set_thread_context) (th, ¤t_event); +} + +/* Find a thread record given a thread id. If GET_CONTEXT is set then + also retrieve the context for this thread. */ +static win32_thread_info * +thread_rec (DWORD id, int get_context) +{ + struct thread_info *thread; + win32_thread_info *th; + + thread = (struct thread_info *) find_inferior_id (&all_threads, id); + if (thread == NULL) + return NULL; + + th = inferior_target_data (thread); + if (get_context && th->context.ContextFlags == 0) + { + if (!th->suspended) + { + if (SuspendThread (th->h) == (DWORD) -1) + { + DWORD err = GetLastError (); + OUTMSG (("warning: SuspendThread failed in thread_rec, " + "(error %d): %s\n", (int) err, strwinerror (err))); + } + else + th->suspended = 1; + } + + win32_get_thread_context (th); + } + + return th; +} + +/* Add a thread to the thread list. */ +static win32_thread_info * +child_add_thread (DWORD tid, HANDLE h) +{ + win32_thread_info *th; + + if ((th = thread_rec (tid, FALSE))) + return th; + + th = calloc (1, sizeof (*th)); + th->tid = tid; + th->h = h; + + add_thread (tid, th, (unsigned int) tid); + set_inferior_regcache_data ((struct thread_info *) + find_inferior_id (&all_threads, tid), + new_register_cache ()); + + if (the_low_target.thread_added != NULL) + (*the_low_target.thread_added) (th); + + return th; +} + +/* Delete a thread from the list of threads. */ +static void +delete_thread_info (struct inferior_list_entry *thread) +{ + win32_thread_info *th = inferior_target_data ((struct thread_info *) thread); + + remove_thread ((struct thread_info *) thread); + CloseHandle (th->h); + free (th); +} + +/* Delete a thread from the list of threads. */ +static void +child_delete_thread (DWORD id) +{ + struct inferior_list_entry *thread; + + /* If the last thread is exiting, just return. */ + if (all_threads.head == all_threads.tail) + return; + + thread = find_inferior_id (&all_threads, id); + if (thread == NULL) + return; + + delete_thread_info (thread); +} + +/* Transfer memory from/to the debugged process. */ +static int +child_xfer_memory (CORE_ADDR memaddr, char *our, int len, + int write, struct target_ops *target) +{ + SIZE_T done; + long addr = (long) memaddr; + + if (write) + { + WriteProcessMemory (current_process_handle, (LPVOID) addr, + (LPCVOID) our, len, &done); + FlushInstructionCache (current_process_handle, (LPCVOID) addr, len); + } + else + { + ReadProcessMemory (current_process_handle, (LPCVOID) addr, (LPVOID) our, + len, &done); + } + return done; +} + +/* Generally, what has the program done? */ +enum target_waitkind +{ + /* The program has exited. The exit status is in value.integer. */ + TARGET_WAITKIND_EXITED, + + /* The program has stopped with a signal. Which signal is in + value.sig. */ + TARGET_WAITKIND_STOPPED, + + /* The program is letting us know that it dynamically loaded + or unloaded something. */ + TARGET_WAITKIND_LOADED, + + /* The program has exec'ed a new executable file. The new file's + pathname is pointed to by value.execd_pathname. */ + TARGET_WAITKIND_EXECD, + + /* Nothing interesting happened, but we stopped anyway. We take the + chance to check if GDB requested an interrupt. */ + TARGET_WAITKIND_SPURIOUS, +}; + +struct target_waitstatus +{ + enum target_waitkind kind; + + /* Forked child pid, execd pathname, exit status or signal number. */ + union + { + int integer; + enum target_signal sig; + int related_pid; + char *execd_pathname; + int syscall_id; + } + value; +}; + +/* Clear out any old thread list and reinitialize it to a pristine + state. */ +static void +child_init_thread_list (void) +{ + for_each_inferior (&all_threads, delete_thread_info); +} + +static void +do_initial_child_stuff (HANDLE proch, DWORD pid) +{ + last_sig = TARGET_SIGNAL_0; + + current_process_handle = proch; + current_process_id = pid; + main_thread_id = 0; + + soft_interrupt_requested = 0; + faked_breakpoint = 0; + + memset (¤t_event, 0, sizeof (current_event)); + + child_init_thread_list (); + + if (the_low_target.initial_stuff != NULL) + (*the_low_target.initial_stuff) (); +} + +/* Resume all artificially suspended threads if we are continuing + execution. */ +static int +continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr) +{ + struct thread_info *thread = (struct thread_info *) this_thread; + int thread_id = * (int *) id_ptr; + win32_thread_info *th = inferior_target_data (thread); + + if ((thread_id == -1 || thread_id == th->tid) + && th->suspended) + { + if (th->context.ContextFlags) + { + win32_set_thread_context (th); + th->context.ContextFlags = 0; + } + + if (ResumeThread (th->h) == (DWORD) -1) + { + DWORD err = GetLastError (); + OUTMSG (("warning: ResumeThread failed in continue_one_thread, " + "(error %d): %s\n", (int) err, strwinerror (err))); + } + th->suspended = 0; + } + + return 0; +} + +static BOOL +child_continue (DWORD continue_status, int thread_id) +{ + /* The inferior will only continue after the ContinueDebugEvent + call. */ + find_inferior (&all_threads, continue_one_thread, &thread_id); + faked_breakpoint = 0; + + if (!ContinueDebugEvent (current_event.dwProcessId, + current_event.dwThreadId, + continue_status)) + return FALSE; + + return TRUE; +} + +/* Fetch register(s) from the current thread context. */ +static void +child_fetch_inferior_registers (int r) +{ + int regno; + win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE); + if (r == -1 || r == 0 || r > NUM_REGS) + child_fetch_inferior_registers (NUM_REGS); + else + for (regno = 0; regno < r; regno++) + (*the_low_target.fetch_inferior_register) (th, regno); +} + +/* Store a new register value into the current thread context. We don't + change the program's context until later, when we resume it. */ +static void +child_store_inferior_registers (int r) +{ + int regno; + win32_thread_info *th = thread_rec (current_inferior_tid (), TRUE); + if (r == -1 || r == 0 || r > NUM_REGS) + child_store_inferior_registers (NUM_REGS); + else + for (regno = 0; regno < r; regno++) + (*the_low_target.store_inferior_register) (th, regno); +} + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ + +char * +strwinerror (DWORD error) +{ + static char buf[1024]; + TCHAR *msgbuf; + DWORD lasterr = GetLastError (); + DWORD chars = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) + { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' + && msgbuf[chars - 1] == '\n') + { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > ((COUNTOF (buf)) - 1)) + { + chars = COUNTOF (buf) - 1; + msgbuf [chars] = 0; + } + +#ifdef UNICODE + wcstombs (buf, msgbuf, chars + 1); +#else + strncpy (buf, msgbuf, chars + 1); +#endif + LocalFree (msgbuf); + } + else + sprintf (buf, "unknown win32 error (%ld)", error); + + SetLastError (lasterr); + return buf; +} + +static BOOL +create_process (const char *program, char *args, + DWORD flags, PROCESS_INFORMATION *pi) +{ + BOOL ret; + +#ifdef _WIN32_WCE + wchar_t *p, *wprogram, *wargs; + size_t argslen; + + wprogram = alloca ((strlen (program) + 1) * sizeof (wchar_t)); + mbstowcs (wprogram, program, strlen (program) + 1); + + for (p = wprogram; *p; ++p) + if (L'/' == *p) + *p = L'\\'; + + argslen = strlen (args); + wargs = alloca ((argslen + 1) * sizeof (wchar_t)); + mbstowcs (wargs, args, argslen + 1); + + ret = CreateProcessW (wprogram, /* image name */ + wargs, /* command line */ + NULL, /* security, not supported */ + NULL, /* thread, not supported */ + FALSE, /* inherit handles, not supported */ + flags, /* start flags */ + NULL, /* environment, not supported */ + NULL, /* current directory, not supported */ + NULL, /* start info, not supported */ + pi); /* proc info */ +#else + STARTUPINFOA si = { sizeof (STARTUPINFOA) }; + + ret = CreateProcessA (program, /* image name */ + args, /* command line */ + NULL, /* security */ + NULL, /* thread */ + TRUE, /* inherit handles */ + flags, /* start flags */ + NULL, /* environment */ + NULL, /* current directory */ + &si, /* start info */ + pi); /* proc info */ +#endif + + return ret; +} + +/* Start a new process. + PROGRAM is a path to the program to execute. + ARGS is a standard NULL-terminated array of arguments, + to be passed to the inferior as ``argv''. + Returns the new PID on success, -1 on failure. Registers the new + process with the process list. */ +static int +win32_create_inferior (char *program, char **program_args) +{ +#ifndef USE_WIN32API + char real_path[MAXPATHLEN]; + char *orig_path, *new_path, *path_ptr; +#endif + BOOL ret; + DWORD flags; + char *args; + int argslen; + int argc; + PROCESS_INFORMATION pi; + DWORD err; + + /* win32_wait needs to know we're not attaching. */ + attaching = 0; + + if (!program) + error ("No executable specified, specify executable to debug.\n"); + + flags = DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS; + +#ifndef USE_WIN32API + orig_path = NULL; + path_ptr = getenv ("PATH"); + if (path_ptr) + { + orig_path = alloca (strlen (path_ptr) + 1); + new_path = alloca (cygwin_posix_to_win32_path_list_buf_size (path_ptr)); + strcpy (orig_path, path_ptr); + cygwin_posix_to_win32_path_list (path_ptr, new_path); + setenv ("PATH", new_path, 1); + } + cygwin_conv_to_win32_path (program, real_path); + program = real_path; +#endif + + argslen = 1; + for (argc = 1; program_args[argc]; argc++) + argslen += strlen (program_args[argc]) + 1; + args = alloca (argslen); + args[0] = '\0'; + for (argc = 1; program_args[argc]; argc++) + { + /* FIXME: Can we do better about quoting? How does Cygwin + handle this? */ + strcat (args, " "); + strcat (args, program_args[argc]); + } + OUTMSG2 (("Command line is \"%s\"\n", args)); + +#ifdef CREATE_NEW_PROCESS_GROUP + flags |= CREATE_NEW_PROCESS_GROUP; +#endif + + ret = create_process (program, args, flags, &pi); + err = GetLastError (); + if (!ret && err == ERROR_FILE_NOT_FOUND) + { + char *exename = alloca (strlen (program) + 5); + strcat (strcpy (exename, program), ".exe"); + ret = create_process (exename, args, flags, &pi); + err = GetLastError (); + } + +#ifndef USE_WIN32API + if (orig_path) + setenv ("PATH", orig_path, 1); +#endif + + if (!ret) + { + error ("Error creating process \"%s%s\", (error %d): %s\n", + program, args, (int) err, strwinerror (err)); + } + else + { + OUTMSG2 (("Process created: %s\n", (char *) args)); + } + +#ifndef _WIN32_WCE + /* On Windows CE this handle can't be closed. The OS reuses + it in the debug events, while the 9x/NT versions of Windows + probably use a DuplicateHandle'd one. */ + CloseHandle (pi.hThread); +#endif + + do_initial_child_stuff (pi.hProcess, pi.dwProcessId); + + return current_process_id; +} + +/* Attach to a running process. + PID is the process ID to attach to, specified by the user + or a higher layer. */ +static int +win32_attach (unsigned long pid) +{ + HANDLE h; + winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; + DWORD err; +#ifdef _WIN32_WCE + HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); +#else + HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); +#endif + DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); + + h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); + if (h != NULL) + { + if (DebugActiveProcess (pid)) + { + if (DebugSetProcessKillOnExit != NULL) + DebugSetProcessKillOnExit (FALSE); + + /* win32_wait needs to know we're attaching. */ + attaching = 1; + do_initial_child_stuff (h, pid); + return 0; + } + + CloseHandle (h); + } + + err = GetLastError (); + error ("Attach to process failed (error %d): %s\n", + (int) err, strwinerror (err)); +} + +/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. */ +static void +handle_output_debug_string (struct target_waitstatus *ourstatus) +{ +#define READ_BUFFER_LEN 1024 + CORE_ADDR addr; + char s[READ_BUFFER_LEN + 1] = { 0 }; + DWORD nbytes = current_event.u.DebugString.nDebugStringLength; + + if (nbytes == 0) + return; + + if (nbytes > READ_BUFFER_LEN) + nbytes = READ_BUFFER_LEN; + + addr = (CORE_ADDR) (size_t) current_event.u.DebugString.lpDebugStringData; + + if (current_event.u.DebugString.fUnicode) + { + /* The event tells us how many bytes, not chars, even + in Unicode. */ + WCHAR buffer[(READ_BUFFER_LEN + 1) / sizeof (WCHAR)] = { 0 }; + if (read_inferior_memory (addr, (unsigned char *) buffer, nbytes) != 0) + return; + wcstombs (s, buffer, (nbytes + 1) / sizeof (WCHAR)); + } + else + { + if (read_inferior_memory (addr, (unsigned char *) s, nbytes) != 0) + return; + } + + if (strncmp (s, "cYg", 3) != 0) + { + if (!server_waiting) + { + OUTMSG2(("%s", s)); + return; + } + + monitor_output (s); + } +#undef READ_BUFFER_LEN +} + +static void +win32_clear_inferiors (void) +{ + if (current_process_handle != NULL) + CloseHandle (current_process_handle); + + for_each_inferior (&all_threads, delete_thread_info); + clear_inferiors (); +} + +/* Kill all inferiors. */ +static void +win32_kill (void) +{ + if (current_process_handle == NULL) + return; + + TerminateProcess (current_process_handle, 0); + for (;;) + { + if (!child_continue (DBG_CONTINUE, -1)) + break; + if (!WaitForDebugEvent (¤t_event, INFINITE)) + break; + if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) + break; + else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) + { + struct target_waitstatus our_status = { 0 }; + handle_output_debug_string (&our_status); + } + } + + win32_clear_inferiors (); +} + +/* Detach from all inferiors. */ +static int +win32_detach (void) +{ + winapi_DebugActiveProcessStop DebugActiveProcessStop = NULL; + winapi_DebugSetProcessKillOnExit DebugSetProcessKillOnExit = NULL; +#ifdef _WIN32_WCE + HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); +#else + HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); +#endif + DebugActiveProcessStop = GETPROCADDRESS (dll, DebugActiveProcessStop); + DebugSetProcessKillOnExit = GETPROCADDRESS (dll, DebugSetProcessKillOnExit); + + if (DebugSetProcessKillOnExit == NULL + || DebugActiveProcessStop == NULL) + return -1; + + { + struct thread_resume resume; + resume.thread = -1; + resume.step = 0; + resume.sig = 0; + resume.leave_stopped = 0; + win32_resume (&resume); + } + + if (!DebugActiveProcessStop (current_process_id)) + return -1; + + DebugSetProcessKillOnExit (FALSE); + + win32_clear_inferiors (); + return 0; +} + +/* Wait for inferiors to end. */ +static void +win32_join (void) +{ + extern unsigned long signal_pid; + + HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, signal_pid); + if (h != NULL) + { + WaitForSingleObject (h, INFINITE); + CloseHandle (h); + } +} + +/* Return 1 iff the thread with thread ID TID is alive. */ +static int +win32_thread_alive (unsigned long tid) +{ + int res; + + /* Our thread list is reliable; don't bother to poll target + threads. */ + if (find_inferior_id (&all_threads, tid) != NULL) + res = 1; + else + res = 0; + return res; +} + +/* Resume the inferior process. RESUME_INFO describes how we want + to resume. */ +static void +win32_resume (struct thread_resume *resume_info) +{ + DWORD tid; + enum target_signal sig; + int step; + win32_thread_info *th; + DWORD continue_status = DBG_CONTINUE; + + /* This handles the very limited set of resume packets that GDB can + currently produce. */ + + if (resume_info[0].thread == -1) + tid = -1; + else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped) + tid = -1; + else + /* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make + the Windows resume code do the right thing for thread switching. */ + tid = current_event.dwThreadId; + + if (resume_info[0].thread != -1) + { + sig = resume_info[0].sig; + step = resume_info[0].step; + } + else + { + sig = 0; + step = 0; + } + + if (sig != TARGET_SIGNAL_0) + { + if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) + { + OUTMSG (("Cannot continue with signal %d here.\n", sig)); + } + else if (sig == last_sig) + continue_status = DBG_EXCEPTION_NOT_HANDLED; + else + OUTMSG (("Can only continue with recieved signal %d.\n", last_sig)); + } + + last_sig = TARGET_SIGNAL_0; + + /* Get context for the currently selected thread. */ + th = thread_rec (current_event.dwThreadId, FALSE); + if (th) + { + if (th->context.ContextFlags) + { + /* Move register values from the inferior into the thread + context structure. */ + regcache_invalidate (); + + if (step) + { + if (the_low_target.single_step != NULL) + (*the_low_target.single_step) (th); + else + error ("Single stepping is not supported " + "in this configuration.\n"); + } + + win32_set_thread_context (th); + th->context.ContextFlags = 0; + } + } + + /* Allow continuing with the same signal that interrupted us. + Otherwise complain. */ + + child_continue (continue_status, tid); +} + +static void +win32_add_one_solib (const char *name, CORE_ADDR load_addr) +{ + char buf[MAX_PATH + 1]; + char buf2[MAX_PATH + 1]; + +#ifdef _WIN32_WCE + WIN32_FIND_DATA w32_fd; + WCHAR wname[MAX_PATH + 1]; + mbstowcs (wname, name, MAX_PATH); + HANDLE h = FindFirstFile (wname, &w32_fd); +#else + WIN32_FIND_DATAA w32_fd; + HANDLE h = FindFirstFileA (name, &w32_fd); +#endif + + if (h == INVALID_HANDLE_VALUE) + strcpy (buf, name); + else + { + FindClose (h); + strcpy (buf, name); +#ifndef _WIN32_WCE + { + char cwd[MAX_PATH + 1]; + char *p; + if (GetCurrentDirectoryA (MAX_PATH + 1, cwd)) + { + p = strrchr (buf, '\\'); + if (p) + p[1] = '\0'; + SetCurrentDirectoryA (buf); + GetFullPathNameA (w32_fd.cFileName, MAX_PATH, buf, &p); + SetCurrentDirectoryA (cwd); + } + } +#endif + } + +#ifdef __CYGWIN__ + cygwin_conv_to_posix_path (buf, buf2); +#else + strcpy (buf2, buf); +#endif + + loaded_dll (buf2, load_addr); +} + +static char * +get_image_name (HANDLE h, void *address, int unicode) +{ + static char buf[(2 * MAX_PATH) + 1]; + DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); + char *address_ptr; + int len = 0; + char b[2]; + DWORD done; + + /* Attempt to read the name of the dll that was detected. + This is documented to work only when actively debugging + a program. It will not work for attached processes. */ + if (address == NULL) + return NULL; + +#ifdef _WIN32_WCE + /* Windows CE reports the address of the image name, + instead of an address of a pointer into the image name. */ + address_ptr = address; +#else + /* See if we could read the address of a string, and that the + address isn't null. */ + if (!ReadProcessMemory (h, address, &address_ptr, + sizeof (address_ptr), &done) + || done != sizeof (address_ptr) + || !address_ptr) + return NULL; +#endif + + /* Find the length of the string */ + while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) + && (b[0] != 0 || b[size - 1] != 0) && done == size) + continue; + + if (!unicode) + ReadProcessMemory (h, address_ptr, buf, len, &done); + else + { + WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR)); + ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), + &done); + + WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0); + } + + return buf; +} + +typedef BOOL (WINAPI *winapi_EnumProcessModules) (HANDLE, HMODULE *, + DWORD, LPDWORD); +typedef BOOL (WINAPI *winapi_GetModuleInformation) (HANDLE, HMODULE, + LPMODULEINFO, DWORD); +typedef DWORD (WINAPI *winapi_GetModuleFileNameExA) (HANDLE, HMODULE, + LPSTR, DWORD); + +static winapi_EnumProcessModules win32_EnumProcessModules; +static winapi_GetModuleInformation win32_GetModuleInformation; +static winapi_GetModuleFileNameExA win32_GetModuleFileNameExA; + +static BOOL +load_psapi (void) +{ + static int psapi_loaded = 0; + static HMODULE dll = NULL; + + if (!psapi_loaded) + { + psapi_loaded = 1; + dll = LoadLibrary (TEXT("psapi.dll")); + if (!dll) + return FALSE; + win32_EnumProcessModules = + GETPROCADDRESS (dll, EnumProcessModules); + win32_GetModuleInformation = + GETPROCADDRESS (dll, GetModuleInformation); + win32_GetModuleFileNameExA = + GETPROCADDRESS (dll, GetModuleFileNameExA); + } + + return (win32_EnumProcessModules != NULL + && win32_GetModuleInformation != NULL + && win32_GetModuleFileNameExA != NULL); +} + +static int +psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret) +{ + DWORD len; + MODULEINFO mi; + size_t i; + HMODULE dh_buf[1]; + HMODULE *DllHandle = dh_buf; + DWORD cbNeeded; + BOOL ok; + + if (!load_psapi ()) + goto failed; + + cbNeeded = 0; + ok = (*win32_EnumProcessModules) (current_process_handle, + DllHandle, + sizeof (HMODULE), + &cbNeeded); + + if (!ok || !cbNeeded) + goto failed; + + DllHandle = (HMODULE *) alloca (cbNeeded); + if (!DllHandle) + goto failed; + + ok = (*win32_EnumProcessModules) (current_process_handle, + DllHandle, + cbNeeded, + &cbNeeded); + if (!ok) + goto failed; + + for (i = 0; i < ((size_t) cbNeeded / sizeof (HMODULE)); i++) + { + if (!(*win32_GetModuleInformation) (current_process_handle, + DllHandle[i], + &mi, + sizeof (mi))) + { + DWORD err = GetLastError (); + error ("Can't get module info: (error %d): %s\n", + (int) err, strwinerror (err)); + } + + if ((DWORD) (mi.lpBaseOfDll) == BaseAddress) + { + len = (*win32_GetModuleFileNameExA) (current_process_handle, + DllHandle[i], + dll_name_ret, + MAX_PATH); + if (len == 0) + { + DWORD err = GetLastError (); + error ("Error getting dll name: (error %d): %s\n", + (int) err, strwinerror (err)); + } + return 1; + } + } + +failed: + dll_name_ret[0] = '\0'; + return 0; +} + +typedef HANDLE (WINAPI *winapi_CreateToolhelp32Snapshot) (DWORD, DWORD); +typedef BOOL (WINAPI *winapi_Module32First) (HANDLE, LPMODULEENTRY32); +typedef BOOL (WINAPI *winapi_Module32Next) (HANDLE, LPMODULEENTRY32); + +static winapi_CreateToolhelp32Snapshot win32_CreateToolhelp32Snapshot; +static winapi_Module32First win32_Module32First; +static winapi_Module32Next win32_Module32Next; +#ifdef _WIN32_WCE +typedef BOOL (WINAPI *winapi_CloseToolhelp32Snapshot) (HANDLE); +static winapi_CloseToolhelp32Snapshot win32_CloseToolhelp32Snapshot; +#endif + +static BOOL +load_toolhelp (void) +{ + static int toolhelp_loaded = 0; + static HMODULE dll = NULL; + + if (!toolhelp_loaded) + { + toolhelp_loaded = 1; +#ifndef _WIN32_WCE + dll = GetModuleHandle (_T("KERNEL32.DLL")); +#else + dll = LoadLibrary (L"TOOLHELP.DLL"); +#endif + if (!dll) + return FALSE; + + win32_CreateToolhelp32Snapshot = + GETPROCADDRESS (dll, CreateToolhelp32Snapshot); + win32_Module32First = GETPROCADDRESS (dll, Module32First); + win32_Module32Next = GETPROCADDRESS (dll, Module32Next); +#ifdef _WIN32_WCE + win32_CloseToolhelp32Snapshot = + GETPROCADDRESS (dll, CloseToolhelp32Snapshot); +#endif + } + + return (win32_CreateToolhelp32Snapshot != NULL + && win32_Module32First != NULL + && win32_Module32Next != NULL +#ifdef _WIN32_WCE + && win32_CloseToolhelp32Snapshot != NULL +#endif + ); +} + +static int +toolhelp_get_dll_name (DWORD BaseAddress, char *dll_name_ret) +{ + HANDLE snapshot_module; + MODULEENTRY32 modEntry = { sizeof (MODULEENTRY32) }; + int found = 0; + + if (!load_toolhelp ()) + return 0; + + snapshot_module = win32_CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, + current_event.dwProcessId); + if (snapshot_module == INVALID_HANDLE_VALUE) + return 0; + + /* Ignore the first module, which is the exe. */ + if (win32_Module32First (snapshot_module, &modEntry)) + while (win32_Module32Next (snapshot_module, &modEntry)) + if ((DWORD) modEntry.modBaseAddr == BaseAddress) + { +#ifdef UNICODE + wcstombs (dll_name_ret, modEntry.szExePath, MAX_PATH + 1); +#else + strcpy (dll_name_ret, modEntry.szExePath); +#endif + found = 1; + break; + } + +#ifdef _WIN32_WCE + win32_CloseToolhelp32Snapshot (snapshot_module); +#else + CloseHandle (snapshot_module); +#endif + return found; +} + +static void +handle_load_dll (void) +{ + LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; + char dll_buf[MAX_PATH + 1]; + char *dll_name = NULL; + DWORD load_addr; + + dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; + + /* Windows does not report the image name of the dlls in the debug + event on attaches. We resort to iterating over the list of + loaded dlls looking for a match by image base. */ + if (!psapi_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf)) + { + if (!server_waiting) + /* On some versions of Windows and Windows CE, we can't create + toolhelp snapshots while the inferior is stopped in a + LOAD_DLL_DEBUG_EVENT due to a dll load, but we can while + Windows is reporting the already loaded dlls. */ + toolhelp_get_dll_name ((DWORD) event->lpBaseOfDll, dll_buf); + } + + dll_name = dll_buf; + + if (*dll_name == '\0') + dll_name = get_image_name (current_process_handle, + event->lpImageName, event->fUnicode); + if (!dll_name) + return; + + /* The symbols in a dll are offset by 0x1000, which is the + the offset from 0 of the first byte in an image - because + of the file header and the section alignment. */ + + load_addr = (DWORD) event->lpBaseOfDll + 0x1000; + win32_add_one_solib (dll_name, load_addr); +} + +static void +handle_unload_dll (void) +{ + CORE_ADDR load_addr = + (CORE_ADDR) (DWORD) current_event.u.UnloadDll.lpBaseOfDll; + load_addr += 0x1000; + unloaded_dll (NULL, load_addr); +} + +static void +handle_exception (struct target_waitstatus *ourstatus) +{ + DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; + + ourstatus->kind = TARGET_WAITKIND_STOPPED; + + switch (code) + { + case EXCEPTION_ACCESS_VIOLATION: + OUTMSG2 (("EXCEPTION_ACCESS_VIOLATION")); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case STATUS_STACK_OVERFLOW: + OUTMSG2 (("STATUS_STACK_OVERFLOW")); + ourstatus->value.sig = TARGET_SIGNAL_SEGV; + break; + case STATUS_FLOAT_DENORMAL_OPERAND: + OUTMSG2 (("STATUS_FLOAT_DENORMAL_OPERAND")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + OUTMSG2 (("EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_INEXACT_RESULT: + OUTMSG2 (("STATUS_FLOAT_INEXACT_RESULT")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_INVALID_OPERATION: + OUTMSG2 (("STATUS_FLOAT_INVALID_OPERATION")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_OVERFLOW: + OUTMSG2 (("STATUS_FLOAT_OVERFLOW")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_STACK_CHECK: + OUTMSG2 (("STATUS_FLOAT_STACK_CHECK")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_UNDERFLOW: + OUTMSG2 (("STATUS_FLOAT_UNDERFLOW")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_FLOAT_DIVIDE_BY_ZERO: + OUTMSG2 (("STATUS_FLOAT_DIVIDE_BY_ZERO")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_INTEGER_DIVIDE_BY_ZERO: + OUTMSG2 (("STATUS_INTEGER_DIVIDE_BY_ZERO")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case STATUS_INTEGER_OVERFLOW: + OUTMSG2 (("STATUS_INTEGER_OVERFLOW")); + ourstatus->value.sig = TARGET_SIGNAL_FPE; + break; + case EXCEPTION_BREAKPOINT: + OUTMSG2 (("EXCEPTION_BREAKPOINT")); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; +#ifdef _WIN32_WCE + /* Remove the initial breakpoint. */ + check_breakpoints ((CORE_ADDR) (long) current_event + .u.Exception.ExceptionRecord.ExceptionAddress); +#endif + break; + case DBG_CONTROL_C: + OUTMSG2 (("DBG_CONTROL_C")); + ourstatus->value.sig = TARGET_SIGNAL_INT; + break; + case DBG_CONTROL_BREAK: + OUTMSG2 (("DBG_CONTROL_BREAK")); + ourstatus->value.sig = TARGET_SIGNAL_INT; + break; + case EXCEPTION_SINGLE_STEP: + OUTMSG2 (("EXCEPTION_SINGLE_STEP")); + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + OUTMSG2 (("EXCEPTION_ILLEGAL_INSTRUCTION")); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + case EXCEPTION_PRIV_INSTRUCTION: + OUTMSG2 (("EXCEPTION_PRIV_INSTRUCTION")); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + OUTMSG2 (("EXCEPTION_NONCONTINUABLE_EXCEPTION")); + ourstatus->value.sig = TARGET_SIGNAL_ILL; + break; + default: + if (current_event.u.Exception.dwFirstChance) + { + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + return; + } + OUTMSG2 (("gdbserver: unknown target exception 0x%08lx at 0x%08lx", + current_event.u.Exception.ExceptionRecord.ExceptionCode, + (DWORD) current_event.u.Exception.ExceptionRecord. + ExceptionAddress)); + ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN; + break; + } + OUTMSG2 (("\n")); + last_sig = ourstatus->value.sig; +} + + +static void +suspend_one_thread (struct inferior_list_entry *entry) +{ + struct thread_info *thread = (struct thread_info *) entry; + win32_thread_info *th = inferior_target_data (thread); + + if (!th->suspended) + { + if (SuspendThread (th->h) == (DWORD) -1) + { + DWORD err = GetLastError (); + OUTMSG (("warning: SuspendThread failed in suspend_one_thread, " + "(error %d): %s\n", (int) err, strwinerror (err))); + } + else + th->suspended = 1; + } +} + +static void +fake_breakpoint_event (void) +{ + OUTMSG2(("fake_breakpoint_event\n")); + + faked_breakpoint = 1; + + memset (¤t_event, 0, sizeof (current_event)); + current_event.dwThreadId = main_thread_id; + current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT; + current_event.u.Exception.ExceptionRecord.ExceptionCode + = EXCEPTION_BREAKPOINT; + + for_each_inferior (&all_threads, suspend_one_thread); +} + +#ifdef _WIN32_WCE +static int +auto_delete_breakpoint (CORE_ADDR stop_pc) +{ + return 1; +} +#endif + +/* Get the next event from the child. */ + +static int +get_child_debug_event (struct target_waitstatus *ourstatus) +{ + last_sig = TARGET_SIGNAL_0; + ourstatus->kind = TARGET_WAITKIND_SPURIOUS; + + /* Check if GDB sent us an interrupt request. */ + check_remote_input_interrupt_request (); + + if (soft_interrupt_requested) + { + soft_interrupt_requested = 0; + fake_breakpoint_event (); + goto gotevent; + } + +#ifndef _WIN32_WCE + attaching = 0; +#else + if (attaching) + { + /* WinCE doesn't set an initial breakpoint automatically. To + stop the inferior, we flush all currently pending debug + events -- the thread list and the dll list are always + reported immediatelly without delay, then, we suspend all + threads and pretend we saw a trap at the current PC of the + main thread. + + Contrary to desktop Windows, Windows CE *does* report the dll + names on LOAD_DLL_DEBUG_EVENTs resulting from a + DebugActiveProcess call. This limits the way we can detect + if all the dlls have already been reported. If we get a real + debug event before leaving attaching, the worst that will + happen is the user will see a spurious breakpoint. */ + + current_event.dwDebugEventCode = 0; + if (!WaitForDebugEvent (¤t_event, 0)) + { + OUTMSG2(("no attach events left\n")); + fake_breakpoint_event (); + attaching = 0; + } + else + OUTMSG2(("got attach event\n")); + } + else +#endif + { + /* Keep the wait time low enough for confortable remote + interruption, but high enough so gdbserver doesn't become a + bottleneck. */ + if (!WaitForDebugEvent (¤t_event, 250)) + return 0; + } + + gotevent: + + current_inferior = + (struct thread_info *) find_inferior_id (&all_threads, + current_event.dwThreadId); + + switch (current_event.dwDebugEventCode) + { + case CREATE_THREAD_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT " + "for pid=%d tid=%x)\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + + /* Record the existence of this thread. */ + child_add_thread (current_event.dwThreadId, + current_event.u.CreateThread.hThread); + break; + + case EXIT_THREAD_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + child_delete_thread (current_event.dwThreadId); + break; + + case CREATE_PROCESS_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + CloseHandle (current_event.u.CreateProcessInfo.hFile); + + current_process_handle = current_event.u.CreateProcessInfo.hProcess; + main_thread_id = current_event.dwThreadId; + + ourstatus->kind = TARGET_WAITKIND_EXECD; + ourstatus->value.execd_pathname = "Main executable"; + + /* Add the main thread. */ + child_add_thread (main_thread_id, + current_event.u.CreateProcessInfo.hThread); + + ourstatus->value.related_pid = current_event.dwThreadId; +#ifdef _WIN32_WCE + if (!attaching) + { + /* Windows CE doesn't set the initial breakpoint + automatically like the desktop versions of Windows do. + We add it explicitly here. It will be removed as soon as + it is hit. */ + set_breakpoint_at ((CORE_ADDR) (long) current_event.u + .CreateProcessInfo.lpStartAddress, + auto_delete_breakpoint); + } +#endif + break; + + case EXIT_PROCESS_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + ourstatus->kind = TARGET_WAITKIND_EXITED; + ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; + CloseHandle (current_process_handle); + current_process_handle = NULL; + break; + + case LOAD_DLL_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + CloseHandle (current_event.u.LoadDll.hFile); + handle_load_dll (); + + ourstatus->kind = TARGET_WAITKIND_LOADED; + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + + case UNLOAD_DLL_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + handle_unload_dll (); + ourstatus->kind = TARGET_WAITKIND_LOADED; + ourstatus->value.sig = TARGET_SIGNAL_TRAP; + break; + + case EXCEPTION_DEBUG_EVENT: + OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + handle_exception (ourstatus); + break; + + case OUTPUT_DEBUG_STRING_EVENT: + /* A message from the kernel (or Cygwin). */ + OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT " + "for pid=%d tid=%x\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId)); + handle_output_debug_string (ourstatus); + break; + + default: + OUTMSG2 (("gdbserver: kernel event unknown " + "for pid=%d tid=%x code=%ld\n", + (unsigned) current_event.dwProcessId, + (unsigned) current_event.dwThreadId, + current_event.dwDebugEventCode)); + break; + } + + current_inferior = + (struct thread_info *) find_inferior_id (&all_threads, + current_event.dwThreadId); + return 1; +} + +/* Wait for the inferior process to change state. + STATUS will be filled in with a response code to send to GDB. + Returns the signal which caused the process to stop. */ +static unsigned char +win32_wait (char *status) +{ + struct target_waitstatus our_status; + + *status = 'T'; + + while (1) + { + if (!get_child_debug_event (&our_status)) + continue; + + switch (our_status.kind) + { + case TARGET_WAITKIND_EXITED: + OUTMSG2 (("Child exited with retcode = %x\n", + our_status.value.integer)); + + *status = 'W'; + win32_clear_inferiors (); + return our_status.value.integer; + case TARGET_WAITKIND_STOPPED: + case TARGET_WAITKIND_LOADED: + OUTMSG2 (("Child Stopped with signal = %d \n", + our_status.value.sig)); + + *status = 'T'; + + child_fetch_inferior_registers (-1); + + if (our_status.kind == TARGET_WAITKIND_LOADED + && !server_waiting) + { + /* When gdb connects, we want to be stopped at the + initial breakpoint, not in some dll load event. */ + child_continue (DBG_CONTINUE, -1); + break; + } + + return our_status.value.sig; + default: + OUTMSG (("Ignoring unknown internal event, %d\n", our_status.kind)); + /* fall-through */ + case TARGET_WAITKIND_SPURIOUS: + case TARGET_WAITKIND_EXECD: + /* do nothing, just continue */ + child_continue (DBG_CONTINUE, -1); + break; + } + } +} + +/* Fetch registers from the inferior process. + If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ +static void +win32_fetch_inferior_registers (int regno) +{ + child_fetch_inferior_registers (regno); +} + +/* Store registers to the inferior process. + If REGNO is -1, store all registers; otherwise, store at least REGNO. */ +static void +win32_store_inferior_registers (int regno) +{ + child_store_inferior_registers (regno); +} + +/* Read memory from the inferior process. This should generally be + called through read_inferior_memory, which handles breakpoint shadowing. + Read LEN bytes at MEMADDR into a buffer at MYADDR. */ +static int +win32_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + return child_xfer_memory (memaddr, (char *) myaddr, len, 0, 0) != len; +} + +/* Write memory to the inferior process. This should generally be + called through write_inferior_memory, which handles breakpoint shadowing. + Write LEN bytes from the buffer at MYADDR to MEMADDR. + Returns 0 on success and errno on failure. */ +static int +win32_write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, + int len) +{ + return child_xfer_memory (memaddr, (char *) myaddr, len, 1, 0) != len; +} + +/* Send an interrupt request to the inferior process. */ +static void +win32_request_interrupt (void) +{ + winapi_DebugBreakProcess DebugBreakProcess; + winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent; + +#ifdef _WIN32_WCE + HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); +#else + HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); +#endif + + GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent); + + if (GenerateConsoleCtrlEvent != NULL + && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id)) + return; + + /* GenerateConsoleCtrlEvent can fail if process id being debugged is + not a process group id. + Fallback to XP/Vista 'DebugBreakProcess', which generates a + breakpoint exception in the interior process. */ + + DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess); + + if (DebugBreakProcess != NULL + && DebugBreakProcess (current_process_handle)) + return; + + /* Last resort, suspend all threads manually. */ + soft_interrupt_requested = 1; +} + +static const char * +win32_arch_string (void) +{ + return the_low_target.arch_string; +} + +#ifdef _WIN32_WCE +int +win32_error_to_fileio_error (DWORD err) +{ + switch (err) + { + case ERROR_BAD_PATHNAME: + case ERROR_FILE_NOT_FOUND: + case ERROR_INVALID_NAME: + case ERROR_PATH_NOT_FOUND: + return FILEIO_ENOENT; + case ERROR_CRC: + case ERROR_IO_DEVICE: + case ERROR_OPEN_FAILED: + return FILEIO_EIO; + case ERROR_INVALID_HANDLE: + return FILEIO_EBADF; + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + return FILEIO_EACCES; + case ERROR_NOACCESS: + return FILEIO_EFAULT; + case ERROR_BUSY: + return FILEIO_EBUSY; + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + return FILEIO_EEXIST; + case ERROR_BAD_DEVICE: + return FILEIO_ENODEV; + case ERROR_DIRECTORY: + return FILEIO_ENOTDIR; + case ERROR_FILENAME_EXCED_RANGE: + case ERROR_INVALID_DATA: + case ERROR_INVALID_PARAMETER: + case ERROR_NEGATIVE_SEEK: + return FILEIO_EINVAL; + case ERROR_TOO_MANY_OPEN_FILES: + return FILEIO_EMFILE; + case ERROR_HANDLE_DISK_FULL: + case ERROR_DISK_FULL: + return FILEIO_ENOSPC; + case ERROR_WRITE_PROTECT: + return FILEIO_EROFS; + case ERROR_NOT_SUPPORTED: + return FILEIO_ENOSYS; + } + + return FILEIO_EUNKNOWN; +} + +static void +wince_hostio_last_error (char *buf) +{ + DWORD winerr = GetLastError (); + int fileio_err = win32_error_to_fileio_error (winerr); + sprintf (buf, "F-1,%x", fileio_err); +} +#endif + +static struct target_ops win32_target_ops = { + win32_create_inferior, + win32_attach, + win32_kill, + win32_detach, + win32_join, + win32_thread_alive, + win32_resume, + win32_wait, + win32_fetch_inferior_registers, + win32_store_inferior_registers, + win32_read_inferior_memory, + win32_write_inferior_memory, + NULL, + win32_request_interrupt, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + win32_arch_string, + NULL, +#ifdef _WIN32_WCE + wince_hostio_last_error, +#else + hostio_last_error_from_errno, +#endif +}; + +/* Initialize the Win32 backend. */ +void +initialize_low (void) +{ + set_target_ops (&win32_target_ops); + if (the_low_target.breakpoint != NULL) + set_breakpoint_data (the_low_target.breakpoint, + the_low_target.breakpoint_len); + init_registers (); +}
win32-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-low.h =================================================================== --- linux-low.h (nonexistent) +++ linux-low.h (revision 816) @@ -0,0 +1,147 @@ +/* Internal interfaces for the GNU/Linux specific target code for gdbserver. + Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifdef HAVE_THREAD_DB_H +#include +#endif + +#ifdef HAVE_LINUX_REGSETS +typedef void (*regset_fill_func) (void *); +typedef void (*regset_store_func) (const void *); +enum regset_type { + GENERAL_REGS, + FP_REGS, + EXTENDED_REGS, +}; + +struct regset_info +{ + int get_request, set_request; + int size; + enum regset_type type; + regset_fill_func fill_function; + regset_store_func store_function; +}; +extern struct regset_info target_regsets[]; +#endif + +struct linux_target_ops +{ + int num_regs; + int *regmap; + int (*cannot_fetch_register) (int); + + /* Returns 0 if we can store the register, 1 if we can not + store the register, and 2 if failure to store the register + is acceptable. */ + int (*cannot_store_register) (int); + CORE_ADDR (*get_pc) (void); + void (*set_pc) (CORE_ADDR newpc); + const unsigned char *breakpoint; + int breakpoint_len; + CORE_ADDR (*breakpoint_reinsert_addr) (void); + + + int decr_pc_after_break; + int (*breakpoint_at) (CORE_ADDR pc); + + /* Watchpoint related functions. See target.h for comments. */ + int (*insert_watchpoint) (char type, CORE_ADDR addr, int len); + int (*remove_watchpoint) (char type, CORE_ADDR addr, int len); + int (*stopped_by_watchpoint) (void); + CORE_ADDR (*stopped_data_address) (void); + + /* Whether to left-pad registers for PEEKUSR/POKEUSR if they are smaller + than an xfer unit. */ + int left_pad_xfer; + + /* What string to report to GDB when it asks for the architecture, + or NULL not to answer. */ + const char *arch_string; +}; + +extern struct linux_target_ops the_low_target; + +#define get_process(inf) ((struct process_info *)(inf)) +#define get_thread_process(thr) (get_process (inferior_target_data (thr))) +#define get_process_thread(proc) ((struct thread_info *) \ + find_inferior_id (&all_threads, \ + get_process (proc)->lwpid)) + +struct process_info +{ + struct inferior_list_entry head; + unsigned long lwpid; + + /* If this flag is set, the next SIGSTOP will be ignored (the + process will be immediately resumed). This means that either we + sent the SIGSTOP to it ourselves and got some other pending event + (so the SIGSTOP is still pending), or that we stopped the + inferior implicitly via PTRACE_ATTACH and have not waited for it + yet. */ + int stop_expected; + + /* If this flag is set, the process is known to be stopped right now (stop + event already received in a wait()). */ + int stopped; + + /* When stopped is set, the last wait status recorded for this process. */ + int last_status; + + /* If this flag is set, STATUS_PENDING is a waitstatus that has not yet + been reported. */ + int status_pending_p; + int status_pending; + + /* If this flag is set, the pending status is a (GDB-placed) breakpoint. */ + int pending_is_breakpoint; + CORE_ADDR pending_stop_pc; + + /* If this is non-zero, it is a breakpoint to be reinserted at our next + stop (SIGTRAP stops only). */ + CORE_ADDR bp_reinsert; + + /* If this flag is set, the last continue operation on this process + was a single-step. */ + int stepping; + + /* If this is non-zero, it points to a chain of signals which need to + be delivered to this process. */ + struct pending_signals *pending_signals; + + /* A link used when resuming. It is initialized from the resume request, + and then processed and cleared in linux_resume_one_process. */ + + struct thread_resume *resume; + + int thread_known; + unsigned long tid; +#ifdef HAVE_THREAD_DB_H + /* The thread handle, used for e.g. TLS access. Only valid if + THREAD_KNOWN is set. */ + td_thrhandle_t th; +#endif +}; + +extern struct inferior_list all_processes; + +void linux_attach_lwp (unsigned long pid); + +int thread_db_init (int use_events); +int thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset, + CORE_ADDR load_module, CORE_ADDR *address);
linux-low.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-mips-low.c =================================================================== --- linux-mips-low.c (nonexistent) +++ linux-mips-low.c (revision 816) @@ -0,0 +1,343 @@ +/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007, + 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#include +#include + +#include "gdb_proc_service.h" + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 25 +#endif + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#define mips_num_regs 73 + +#include + +union mips_register +{ + unsigned char buf[8]; + + /* Deliberately signed, for proper sign extension. */ + int reg32; + long long reg64; +}; + +/* Return the ptrace ``address'' of register REGNO. */ + +static int mips_regmap[] = { + -1, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + + -1, MMLO, MMHI, BADVADDR, CAUSE, PC, + + FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, + FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, + FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11, + FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, + FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, + FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, + FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, + FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, + FPC_CSR, FPC_EIR, + + 0 +}; + +/* From mips-linux-nat.c. */ + +/* Pseudo registers can not be read. ptrace does not provide a way to + read (or set) PS_REGNUM, and there's no point in reading or setting + ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via + ptrace(). */ + +static int +mips_cannot_fetch_register (int regno) +{ + if (mips_regmap[regno] == -1) + return 1; + + if (find_regno ("r0") == regno) + return 1; + + return 0; +} + +static int +mips_cannot_store_register (int regno) +{ + if (mips_regmap[regno] == -1) + return 1; + + if (find_regno ("r0") == regno) + return 1; + + if (find_regno ("cause") == regno) + return 1; + + if (find_regno ("badvaddr") == regno) + return 1; + + if (find_regno ("fir") == regno) + return 1; + + return 0; +} + +static CORE_ADDR +mips_get_pc () +{ + union mips_register pc; + collect_register_by_name ("pc", pc.buf); + return register_size (0) == 4 ? pc.reg32 : pc.reg64; +} + +static void +mips_set_pc (CORE_ADDR pc) +{ + union mips_register newpc; + if (register_size (0) == 4) + newpc.reg32 = pc; + else + newpc.reg64 = pc; + + supply_register_by_name ("pc", newpc.buf); +} + +/* Correct in either endianness. */ +static const unsigned int mips_breakpoint = 0x0005000d; +#define mips_breakpoint_len 4 + +/* We only place breakpoints in empty marker functions, and thread locking + is outside of the function. So rather than importing software single-step, + we can just run until exit. */ +static CORE_ADDR +mips_reinsert_addr () +{ + union mips_register ra; + collect_register_by_name ("r31", ra.buf); + return register_size (0) == 4 ? ra.reg32 : ra.reg64; +} + +static int +mips_breakpoint_at (CORE_ADDR where) +{ + unsigned int insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, 4); + if (insn == mips_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + one. */ + return 0; +} + +/* Fetch the thread-local storage pointer for libthread_db. */ + +ps_err_e +ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base) +{ + if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) + return PS_ERR; + + /* IDX is the bias from the thread pointer to the beginning of the + thread descriptor. It has to be subtracted due to implementation + quirks in libthread_db. */ + *base = (void *) ((char *)*base - idx); + + return PS_OK; +} + +#ifdef HAVE_PTRACE_GETREGS + +static void +mips_collect_register (int use_64bit, int regno, union mips_register *reg) +{ + union mips_register tmp_reg; + + if (use_64bit) + { + collect_register (regno, &tmp_reg.reg64); + *reg = tmp_reg; + } + else + { + collect_register (regno, &tmp_reg.reg32); + reg->reg64 = tmp_reg.reg32; + } +} + +static void +mips_supply_register (int use_64bit, int regno, const union mips_register *reg) +{ + int offset = 0; + + /* For big-endian 32-bit targets, ignore the high four bytes of each + eight-byte slot. */ + if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit) + offset = 4; + + supply_register (regno, reg->buf + offset); +} + +static void +mips_collect_register_32bit (int use_64bit, int regno, unsigned char *buf) +{ + union mips_register tmp_reg; + int reg32; + + mips_collect_register (use_64bit, regno, &tmp_reg); + reg32 = tmp_reg.reg64; + memcpy (buf, ®32, 4); +} + +static void +mips_supply_register_32bit (int use_64bit, int regno, const unsigned char *buf) +{ + union mips_register tmp_reg; + int reg32; + + memcpy (®32, buf, 4); + tmp_reg.reg64 = reg32; + mips_supply_register (use_64bit, regno, &tmp_reg); +} + +static void +mips_fill_gregset (void *buf) +{ + union mips_register *regset = buf; + int i, use_64bit; + + use_64bit = (register_size (0) == 8); + + for (i = 1; i < 32; i++) + mips_collect_register (use_64bit, i, regset + i); + + mips_collect_register (use_64bit, find_regno ("lo"), regset + 32); + mips_collect_register (use_64bit, find_regno ("hi"), regset + 33); + mips_collect_register (use_64bit, find_regno ("pc"), regset + 34); + mips_collect_register (use_64bit, find_regno ("badvaddr"), regset + 35); + mips_collect_register (use_64bit, find_regno ("status"), regset + 36); + mips_collect_register (use_64bit, find_regno ("cause"), regset + 37); + + mips_collect_register (use_64bit, find_regno ("restart"), regset + 0); +} + +static void +mips_store_gregset (const void *buf) +{ + const union mips_register *regset = buf; + int i, use_64bit; + + use_64bit = (register_size (0) == 8); + + for (i = 0; i < 32; i++) + mips_supply_register (use_64bit, i, regset + i); + + mips_supply_register (use_64bit, find_regno ("lo"), regset + 32); + mips_supply_register (use_64bit, find_regno ("hi"), regset + 33); + mips_supply_register (use_64bit, find_regno ("pc"), regset + 34); + mips_supply_register (use_64bit, find_regno ("badvaddr"), regset + 35); + mips_supply_register (use_64bit, find_regno ("status"), regset + 36); + mips_supply_register (use_64bit, find_regno ("cause"), regset + 37); + + mips_supply_register (use_64bit, find_regno ("restart"), regset + 0); +} + +static void +mips_fill_fpregset (void *buf) +{ + union mips_register *regset = buf; + int i, use_64bit, first_fp, big_endian; + + use_64bit = (register_size (0) == 8); + first_fp = find_regno ("f0"); + big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + + /* See GDB for a discussion of this peculiar layout. */ + for (i = 0; i < 32; i++) + if (use_64bit) + collect_register (first_fp + i, regset[i].buf); + else + collect_register (first_fp + i, + regset[i & ~1].buf + 4 * (big_endian != (i & 1))); + + mips_collect_register_32bit (use_64bit, find_regno ("fcsr"), regset[32].buf); + mips_collect_register_32bit (use_64bit, find_regno ("fir"), + regset[32].buf + 4); +} + +static void +mips_store_fpregset (const void *buf) +{ + const union mips_register *regset = buf; + int i, use_64bit, first_fp, big_endian; + + use_64bit = (register_size (0) == 8); + first_fp = find_regno ("f0"); + big_endian = (__BYTE_ORDER == __BIG_ENDIAN); + + /* See GDB for a discussion of this peculiar layout. */ + for (i = 0; i < 32; i++) + if (use_64bit) + supply_register (first_fp + i, regset[i].buf); + else + supply_register (first_fp + i, + regset[i & ~1].buf + 4 * (big_endian != (i & 1))); + + mips_supply_register_32bit (use_64bit, find_regno ("fcsr"), regset[32].buf); + mips_supply_register_32bit (use_64bit, find_regno ("fir"), + regset[32].buf + 4); +} +#endif /* HAVE_PTRACE_GETREGS */ + +struct regset_info target_regsets[] = { +#ifdef HAVE_PTRACE_GETREGS + { PTRACE_GETREGS, PTRACE_SETREGS, 38 * 8, GENERAL_REGS, + mips_fill_gregset, mips_store_gregset }, + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 33 * 8, FP_REGS, + mips_fill_fpregset, mips_store_fpregset }, +#endif /* HAVE_PTRACE_GETREGS */ + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + mips_num_regs, + mips_regmap, + mips_cannot_fetch_register, + mips_cannot_store_register, + mips_get_pc, + mips_set_pc, + (const unsigned char *) &mips_breakpoint, + mips_breakpoint_len, + mips_reinsert_addr, + 0, + mips_breakpoint_at, +};
linux-mips-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gdb_proc_service.h =================================================================== --- gdb_proc_service.h (nonexistent) +++ gdb_proc_service.h (revision 816) @@ -0,0 +1,73 @@ +/* replacement for systems that don't have it. + Copyright (C) 2000, 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifndef GDB_PROC_SERVICE_H +#define GDB_PROC_SERVICE_H + +#include + +#ifdef HAVE_PROC_SERVICE_H +#include +#else + +#ifdef HAVE_SYS_PROCFS_H +#include +#endif + +/* Not all platforms bring in via . If + wasn't enough to find elf_fpregset_t, try the kernel + headers also (but don't if we don't need to). */ +#ifndef HAVE_ELF_FPREGSET_T +# ifdef HAVE_LINUX_ELF_H +# include +# endif +#endif + +typedef enum +{ + PS_OK, /* Success. */ + PS_ERR, /* Generic error. */ + PS_BADPID, /* Bad process handle. */ + PS_BADLID, /* Bad LWP id. */ + PS_BADADDR, /* Bad address. */ + PS_NOSYM, /* Symbol not found. */ + PS_NOFREGS /* FPU register set not available. */ +} ps_err_e; + +#ifndef HAVE_LWPID_T +typedef unsigned int lwpid_t; +#endif + +#ifndef HAVE_PSADDR_T +typedef unsigned long psaddr_t; +#endif + +#ifndef HAVE_PRGREGSET_T +typedef elf_gregset_t prgregset_t; +#endif + +#endif /* HAVE_PROC_SERVICE_H */ + +/* Structure that identifies the target process. */ +struct ps_prochandle +{ + /* The process id is all we need. */ + pid_t pid; +}; + +#endif /* gdb_proc_service.h */
gdb_proc_service.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: regcache.h =================================================================== --- regcache.h (nonexistent) +++ regcache.h (revision 816) @@ -0,0 +1,70 @@ +/* Register support routines for the remote server for GDB. + Copyright (C) 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifndef REGCACHE_H +#define REGCACHE_H + +struct inferior_list_entry; + +/* Create a new register cache for INFERIOR. */ + +void *new_register_cache (void); + +/* Release all memory associated with the register cache for INFERIOR. */ + +void free_register_cache (void *regcache); + +/* Invalidate cached registers for one or all threads. */ + +void regcache_invalidate_one (struct inferior_list_entry *); +void regcache_invalidate (void); + +/* Convert all registers to a string in the currently specified remote + format. */ + +void registers_to_string (char *buf); + +/* Convert a string to register values and fill our register cache. */ + +void registers_from_string (char *buf); + +/* Return the size in bytes of a string-encoded register packet. */ + +int registers_length (void); + +/* Return a pointer to the description of register ``n''. */ + +struct reg *find_register_by_number (int n); + +int register_size (int n); + +int find_regno (const char *name); + +extern const char **gdbserver_expedite_regs; + +void supply_register (int n, const void *buf); + +void supply_register_by_name (const char *name, const void *buf); + +void collect_register (int n, void *buf); + +void collect_register_as_string (int n, char *buf); + +void collect_register_by_name (const char *name, void *buf); + +#endif /* REGCACHE_H */
regcache.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: win32-low.h =================================================================== --- win32-low.h (nonexistent) +++ win32-low.h (revision 816) @@ -0,0 +1,91 @@ +/* Internal interfaces for the Win32 specific target code for gdbserver. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include + +/* Thread information structure used to track extra information about + each thread. */ +typedef struct win32_thread_info +{ + /* The Win32 thread identifier. */ + DWORD tid; + + /* The handle to the thread. */ + HANDLE h; + + /* Non zero if SuspendThread was called on this thread. */ + int suspended; + +#ifdef _WIN32_WCE + /* The context as retrieved right after suspending the thread. */ + CONTEXT base_context; +#endif + + /* The context of the thread, including any manipulations. */ + CONTEXT context; +} win32_thread_info; + +struct win32_target_ops +{ + /* The number of target registers. */ + int num_regs; + + /* Perform initializations on startup. */ + void (*initial_stuff) (void); + + /* Fetch the context from the inferior. */ + void (*get_thread_context) (win32_thread_info *th, DEBUG_EVENT *current_event); + + /* Flush the context back to the inferior. */ + void (*set_thread_context) (win32_thread_info *th, DEBUG_EVENT *current_event); + + /* Called when a thread was added. */ + void (*thread_added) (win32_thread_info *th); + + /* Fetch register from gdbserver regcache data. */ + void (*fetch_inferior_register) (win32_thread_info *th, int r); + + /* Store a new register value into the thread context of TH. */ + void (*store_inferior_register) (win32_thread_info *th, int r); + + void (*single_step) (win32_thread_info *th); + + const unsigned char *breakpoint; + int breakpoint_len; + + /* What string to report to GDB when it asks for the architecture, + or NULL not to answer. */ + const char *arch_string; +}; + +extern struct win32_target_ops the_low_target; + +/* Map the Windows error number in ERROR to a locale-dependent error + message string and return a pointer to it. Typically, the values + for ERROR come from GetLastError. + + The string pointed to shall not be modified by the application, + but may be overwritten by a subsequent call to strwinerror + + The strwinerror function does not change the current setting + of GetLastError. */ +extern char * strwinerror (DWORD error); + +/* in wincecompat.c */ + +extern void to_back_slashes (char *);
win32-low.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: configure.srv =================================================================== --- configure.srv (nonexistent) +++ configure.srv (revision 816) @@ -0,0 +1,180 @@ +# Mappings from configuration triplets to gdbserver build options. +# This is invoked from the autoconf-generated configure script, to +# produce the appropriate Makefile substitutions. + +# This file sets the following shell variables: +# srv_regobj The register protocol appropriate for this target. +# srv_tgtobj Any other target-specific modules appropriate +# for this target. +# srv_hostio_err The object implementing the hostio_last_error +# target method. +# srv_xmltarget The XML source file to use for target.xml, if any. +# srv_xmlfiles Any other XML files which should be available for +# gdbserver in this configuration. +# +# In addition, on GNU/Linux the following shell variables will be set: +# srv_linux_regsets Set to "yes" if ptrace(PTRACE_GETREGS) and friends +# may be available on this platform; unset otherwise. +# They will only be used if defines +# PTRACE_GETREGS. +# srv_linux_usrregs Set to "yes" if we can get at registers via +# PTRACE_PEEKUSR / PTRACE_POKEUSR. + +# Default hostio_last_error implementation +srv_hostio_err_objs="hostio-errno.o" + +# Input is taken from the "${target}" variable. + +case "${target}" in + arm*-*-linux*) srv_tgtobj="linux-low.o linux-arm-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + if test $gdb_cv_arm_iwmmxt = yes; then + srv_regobj=arm-with-iwmmxt.o + srv_xmltarget=arm-with-iwmmxt.xml + srv_xmlfiles="arm-core.xml xscale-iwmmxt.xml" + else + srv_regobj=reg-arm.o + fi + ;; + arm*-*-mingw32ce*) srv_regobj=reg-arm.o + srv_tgtobj="win32-low.o win32-arm-low.o" + srv_tgtobj="${srv_tgtobj} wincecompat.o" + # hostio_last_error implementation is in win32-low.c + srv_hostio_err_objs="" + srv_mingw=yes + srv_mingwce=yes + ;; + crisv32-*-linux*) srv_regobj=reg-crisv32.o + srv_tgtobj="linux-low.o linux-crisv32-low.o" + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + cris-*-linux*) srv_regobj=reg-cris.o + srv_tgtobj="linux-low.o linux-cris-low.o" + srv_linux_usrregs=yes + srv_linux_thread_db=yes + ;; + i[34567]86-*-cygwin*) srv_regobj=reg-i386.o + srv_tgtobj="win32-low.o win32-i386-low.o" + ;; + i[34567]86-*-linux*) srv_regobj=reg-i386-linux.o + srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + i[34567]86-*-mingw*) srv_regobj=reg-i386.o + srv_tgtobj="win32-low.o win32-i386-low.o" + srv_mingw=yes + ;; + ia64-*-linux*) srv_regobj=reg-ia64.o + srv_tgtobj="linux-low.o linux-ia64-low.o" + srv_linux_usrregs=yes + ;; + m32r*-*-linux*) srv_regobj=reg-m32r.o + srv_tgtobj="linux-low.o linux-m32r-low.o" + srv_linux_usrregs=yes + srv_linux_thread_db=yes + ;; + m68*-*-linux*) srv_regobj=reg-m68k.o + srv_tgtobj="linux-low.o linux-m68k-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + m68*-*-uclinux*) srv_regobj=reg-m68k.o + srv_tgtobj="linux-low.o linux-m68k-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + mips*64*-*-linux*) srv_regobj=mips64-linux.o + srv_xmltarget=mips64-linux.xml + srv_xmlfiles="mips64-cpu.xml mips64-cp0.xml mips64-fpu.xml" + srv_tgtobj="linux-low.o linux-mips-low.o" + srv_linux_regsets=yes + srv_linux_usrregs=yes + srv_linux_thread_db=yes + ;; + mips*-*-linux*) srv_regobj=mips-linux.o + srv_xmltarget=mips-linux.xml + srv_xmlfiles="mips-cpu.xml mips-cp0.xml mips-fpu.xml" + srv_tgtobj="linux-low.o linux-mips-low.o" + srv_linux_regsets=yes + srv_linux_usrregs=yes + srv_linux_thread_db=yes + ;; + powerpc64-*-linux*) srv_tgtobj="linux-low.o linux-ppc64-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + if test $gdb_cv_ppc_altivec = yes; then + srv_regobj=powerpc-64.o + srv_xmltarget=rs6000/powerpc-64.xml + srv_xmlfiles="rs6000/power-altivec.xml" + srv_xmlfiles="$srv_xmlfiles rs6000/power64-core.xml" + srv_xmlfiles="$srv_xmlfiles rs6000/power-fpu.xml" + else + srv_regobj=reg-ppc64.o + fi + ;; + powerpc-*-linux*) srv_tgtobj="linux-low.o linux-ppc-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + if test $gdb_cv_ppc_altivec = yes; then + srv_regobj=powerpc-32.o + srv_xmltarget=rs6000/powerpc-32.xml + srv_xmlfiles="rs6000/power-altivec.xml" + srv_xmlfiles="$srv_xmlfiles rs6000/power-core.xml" + srv_xmlfiles="$srv_xmlfiles rs6000/power-fpu.xml" + elif test $gdb_cv_ppc_spe = yes; then + srv_regobj=powerpc-e500.o + srv_xmltarget=rs6000/powerpc-e500.xml + srv_xmlfiles="rs6000/power-spe.xml" + srv_xmlfiles="$srv_xmlfiles rs6000/power-core.xml" + else + srv_regobj=reg-ppc.o + fi + ;; + s390-*-linux*) srv_regobj=reg-s390.o + srv_tgtobj="linux-low.o linux-s390-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + s390x-*-linux*) srv_regobj=reg-s390x.o + srv_tgtobj="linux-low.o linux-s390-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + sh*-*-linux*) srv_regobj=reg-sh.o + srv_tgtobj="linux-low.o linux-sh-low.o" + srv_linux_usrregs=yes + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + spu*-*-*) srv_regobj=reg-spu.o + srv_tgtobj="spu-low.o" + ;; + x86_64-*-linux*) srv_regobj=reg-x86-64-linux.o + srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o" + srv_linux_regsets=yes + srv_linux_thread_db=yes + ;; + xscale*-*-linux*) srv_regobj=reg-arm.o + srv_tgtobj="linux-low.o linux-arm-low.o" + srv_linux_usrregs=yes + srv_linux_thread_db=yes + ;; + xtensa*-*-linux*) srv_regobj=reg-xtensa.o + srv_tgtobj="linux-low.o linux-xtensa-low.o" + srv_linux_regsets=yes + ;; + *) echo "Error: target not supported by gdbserver." + exit 1 + ;; +esac Index: wincecompat.c =================================================================== --- wincecompat.c (nonexistent) +++ wincecompat.c (revision 816) @@ -0,0 +1,39 @@ +/* Compatibility routines for Windows CE. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" + +#include +#include + +void +perror (const char *s) +{ + if (s && *s) + fprintf (stderr, "%s: %s\n", s, strwinerror (GetLastError ())); + else + fprintf (stderr, "%s\n", strwinerror (GetLastError ())); +} + +void +to_back_slashes (char *path) +{ + for (; *path; ++path) + if ('/' == *path) + *path = '\\'; +}
wincecompat.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-arm-low.c =================================================================== --- linux-arm-low.c (nonexistent) +++ linux-arm-low.c (revision 816) @@ -0,0 +1,218 @@ +/* GNU/Linux/ARM specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#include + +#include "gdb_proc_service.h" + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 22 +#endif + +#ifndef PTRACE_GETWMMXREGS +# define PTRACE_GETWMMXREGS 18 +# define PTRACE_SETWMMXREGS 19 +#endif + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#define arm_num_regs 26 + +static int arm_regmap[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + 64 +}; + +static int +arm_cannot_store_register (int regno) +{ + return (regno >= arm_num_regs); +} + +static int +arm_cannot_fetch_register (int regno) +{ + return (regno >= arm_num_regs); +} + +static void +arm_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < arm_num_regs; i++) + if (arm_regmap[i] != -1) + collect_register (i, ((char *) buf) + arm_regmap[i]); +} + +static void +arm_store_gregset (const void *buf) +{ + int i; + char zerobuf[8]; + + memset (zerobuf, 0, 8); + for (i = 0; i < arm_num_regs; i++) + if (arm_regmap[i] != -1) + supply_register (i, ((char *) buf) + arm_regmap[i]); + else + supply_register (i, zerobuf); +} + +#ifdef __IWMMXT__ + +static void +arm_fill_wmmxregset (void *buf) +{ + int i; + + for (i = 0; i < 16; i++) + collect_register (arm_num_regs + i, (char *) buf + i * 8); + + /* We only have access to wcssf, wcasf, and wcgr0-wcgr3. */ + for (i = 0; i < 6; i++) + collect_register (arm_num_regs + i + 16, (char *) buf + 16 * 8 + i * 4); +} + +static void +arm_store_wmmxregset (const void *buf) +{ + int i; + + for (i = 0; i < 16; i++) + supply_register (arm_num_regs + i, (char *) buf + i * 8); + + /* We only have access to wcssf, wcasf, and wcgr0-wcgr3. */ + for (i = 0; i < 6; i++) + supply_register (arm_num_regs + i + 16, (char *) buf + 16 * 8 + i * 4); +} + +#endif /* __IWMMXT__ */ + +extern int debug_threads; + +static CORE_ADDR +arm_get_pc () +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + if (debug_threads) + fprintf (stderr, "stop pc is %08lx\n", pc); + return pc; +} + +static void +arm_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +/* Correct in either endianness. We do not support Thumb yet. */ +static const unsigned long arm_breakpoint = 0xef9f0001; +#define arm_breakpoint_len 4 + +/* For new EABI binaries. We recognize it regardless of which ABI + is used for gdbserver, so single threaded debugging should work + OK, but for multi-threaded debugging we only insert the current + ABI's breakpoint instruction. For now at least. */ +static const unsigned long arm_eabi_breakpoint = 0xe7f001f0; + +static int +arm_breakpoint_at (CORE_ADDR where) +{ + unsigned long insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, 4); + if (insn == arm_breakpoint) + return 1; + + if (insn == arm_eabi_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + two. */ + + return 0; +} + +/* We only place breakpoints in empty marker functions, and thread locking + is outside of the function. So rather than importing software single-step, + we can just run until exit. */ +static CORE_ADDR +arm_reinsert_addr () +{ + unsigned long pc; + collect_register_by_name ("lr", &pc); + return pc; +} + +/* Fetch the thread-local storage pointer for libthread_db. */ + +ps_err_e +ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base) +{ + if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) + return PS_ERR; + + /* IDX is the bias from the thread pointer to the beginning of the + thread descriptor. It has to be subtracted due to implementation + quirks in libthread_db. */ + *base = (void *) ((char *)*base - idx); + + return PS_OK; +} + +struct regset_info target_regsets[] = { + { PTRACE_GETREGS, PTRACE_SETREGS, 18 * 4, + GENERAL_REGS, + arm_fill_gregset, arm_store_gregset }, +#ifdef __IWMMXT__ + { PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS, 16 * 8 + 6 * 4, + EXTENDED_REGS, + arm_fill_wmmxregset, arm_store_wmmxregset }, +#endif + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + arm_num_regs, + arm_regmap, + arm_cannot_fetch_register, + arm_cannot_store_register, + arm_get_pc, + arm_set_pc, +#ifndef __ARM_EABI__ + (const unsigned char *) &arm_breakpoint, +#else + (const unsigned char *) &arm_eabi_breakpoint, +#endif + arm_breakpoint_len, + arm_reinsert_addr, + 0, + arm_breakpoint_at, +};
linux-arm-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: wincecompat.h =================================================================== --- wincecompat.h (nonexistent) +++ wincecompat.h (revision 816) @@ -0,0 +1,30 @@ +/* Compatibility routines for Windows CE. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifndef WINCECOMPAT_H +#define WINCECOMPAT_H + +#include + +#define errno (GetLastError ()) + +/* in win32-low.c */ +extern char * strwinerror (DWORD error); +#define strerror strwinerror + +#endif
wincecompat.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-ppc-low.c =================================================================== --- linux-ppc-low.c (nonexistent) +++ linux-ppc-low.c (revision 816) @@ -0,0 +1,245 @@ +/* GNU/Linux/PowerPC specific low level interface, for the remote server for + GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#include + +#define ppc_num_regs 71 + +/* Currently, don't check/send MQ. */ +static int ppc_regmap[] = + {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4, + PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4, + PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4, + PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4, + PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4, + PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4, + PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4, + PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4, +#ifdef __SPE__ + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, +#else + PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24, + PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56, + PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88, + PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120, + PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152, + PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184, + 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, +#endif + PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, +#ifdef __SPE__ + PT_CTR * 4, PT_XER * 4, -1 +#else + PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4 +#endif + }; + +static int +ppc_cannot_store_register (int regno) +{ +#ifndef __SPE__ + /* Some kernels do not allow us to store fpscr. */ + if (regno == find_regno ("fpscr")) + return 2; +#endif + + return 0; +} + +static int +ppc_cannot_fetch_register (int regno) +{ + return 0; +} + +static CORE_ADDR +ppc_get_pc (void) +{ + 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; + + supply_register_by_name ("pc", &newpc); +} + +/* Correct in either endianness. Note that this file is + for PowerPC only, not PowerPC64. + This instruction is "twge r2, r2", which GDB uses as a software + breakpoint. */ +static const unsigned long ppc_breakpoint = 0x7d821008; +#define ppc_breakpoint_len 4 + +static int +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. */ + return 0; +} + +/* Provide only a fill function for the general register set. ps_lgetregs + will use this for NPTL support. */ + +static void ppc_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < 32; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); + + for (i = 64; i < 70; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); +} + +#ifdef __ALTIVEC__ + +#ifndef PTRACE_GETVRREGS +#define PTRACE_GETVRREGS 18 +#define PTRACE_SETVRREGS 19 +#endif + +#define SIZEOF_VRREGS 33*16+4 + +static void +ppc_fill_vrregset (void *buf) +{ + int i, base; + char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + collect_register (base + i, ®set[i * 16]); + + collect_register_by_name ("vscr", ®set[32 * 16 + 12]); + collect_register_by_name ("vrsave", ®set[33 * 16]); +} + +static void +ppc_store_vrregset (const void *buf) +{ + int i, base; + const char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + supply_register (base + i, ®set[i * 16]); + + supply_register_by_name ("vscr", ®set[32 * 16 + 12]); + supply_register_by_name ("vrsave", ®set[33 * 16]); +} + +#endif /* __ALTIVEC__ */ + +#ifdef __SPE__ + +#ifndef PTRACE_GETEVRREGS +#define PTRACE_GETEVRREGS 20 +#define PTRACE_SETEVRREGS 21 +#endif + +struct gdb_evrregset_t +{ + unsigned long evr[32]; + unsigned long long acc; + unsigned long spefscr; +}; + +static void +ppc_fill_evrregset (void *buf) +{ + int i, ev0; + struct gdb_evrregset_t *regset = buf; + + ev0 = find_regno ("ev0h"); + for (i = 0; i < 32; i++) + collect_register (ev0 + i, ®set->evr[i]); + + collect_register_by_name ("acc", ®set->acc); + collect_register_by_name ("spefscr", ®set->spefscr); +} + +static void +ppc_store_evrregset (const void *buf) +{ + int i, ev0; + const struct gdb_evrregset_t *regset = buf; + + ev0 = find_regno ("ev0h"); + for (i = 0; i < 32; i++) + supply_register (ev0 + i, ®set->evr[i]); + + supply_register_by_name ("acc", ®set->acc); + supply_register_by_name ("spefscr", ®set->spefscr); +} +#endif /* __SPE__ */ + +struct regset_info target_regsets[] = { + /* List the extra register sets before GENERAL_REGS. That way we will + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ +#ifdef __ALTIVEC__ + { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS, + ppc_fill_vrregset, ppc_store_vrregset }, +#endif +#ifdef __SPE__ + { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 32 * 4 + 8 + 4, EXTENDED_REGS, + ppc_fill_evrregset, ppc_store_evrregset }, +#endif + { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL }, + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + ppc_num_regs, + ppc_regmap, + ppc_cannot_fetch_register, + ppc_cannot_store_register, + ppc_get_pc, + ppc_set_pc, + (const unsigned char *) &ppc_breakpoint, + ppc_breakpoint_len, + NULL, + 0, + ppc_breakpoint_at, +};
linux-ppc-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: win32-arm-low.c =================================================================== --- win32-arm-low.c (nonexistent) +++ win32-arm-low.c (revision 816) @@ -0,0 +1,121 @@ +/* Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "win32-low.h" + +#ifndef CONTEXT_FLOATING_POINT +#define CONTEXT_FLOATING_POINT 0 +#endif + +static void +arm_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + th->context.ContextFlags = \ + CONTEXT_FULL | \ + CONTEXT_FLOATING_POINT; + + GetThreadContext (th->h, &th->context); +} + +static void +arm_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + SetThreadContext (th->h, &th->context); +} + +#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) +static const int mappings[] = { + context_offset (R0), + context_offset (R1), + context_offset (R2), + context_offset (R3), + context_offset (R4), + context_offset (R5), + context_offset (R6), + context_offset (R7), + context_offset (R8), + context_offset (R9), + context_offset (R10), + context_offset (R11), + context_offset (R12), + context_offset (Sp), + context_offset (Lr), + context_offset (Pc), + -1, /* f0 */ + -1, /* f1 */ + -1, /* f2 */ + -1, /* f3 */ + -1, /* f4 */ + -1, /* f5 */ + -1, /* f6 */ + -1, /* f7 */ + -1, /* fps */ + context_offset (Psr), +}; +#undef context_offset + +/* Return a pointer into a CONTEXT field indexed by gdb register number. + Return a pointer to an dummy register holding zero if there is no + corresponding CONTEXT field for the given register number. */ +static char * +regptr (CONTEXT* c, int r) +{ + if (mappings[r] < 0) + { + static ULONG zero; + /* Always force value to zero, in case the user tried to write + to this register before. */ + zero = 0; + return (char *) &zero; + } + else + return (char *) c + mappings[r]; +} + +/* Fetch register from gdbserver regcache data. */ +static void +arm_fetch_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = regptr (&th->context, r); + supply_register (r, context_offset); +} + +/* Store a new register value into the thread context of TH. */ +static void +arm_store_inferior_register (win32_thread_info *th, int r) +{ + collect_register (r, regptr (&th->context, r)); +} + +/* Correct in either endianness. We do not support Thumb yet. */ +static const unsigned long arm_wince_breakpoint = 0xe6000010; +#define arm_wince_breakpoint_len 4 + +struct win32_target_ops the_low_target = { + sizeof (mappings) / sizeof (mappings[0]), + NULL, /* initial_stuff */ + arm_get_thread_context, + arm_set_thread_context, + NULL, /* thread_added */ + arm_fetch_inferior_register, + arm_store_inferior_register, + NULL, /* single_step */ + (const unsigned char *) &arm_wince_breakpoint, + arm_wince_breakpoint_len, + "arm" /* arch_string */ +};
win32-arm-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-m32r-low.c =================================================================== --- linux-m32r-low.c (nonexistent) +++ linux-m32r-low.c (revision 816) @@ -0,0 +1,97 @@ +/* GNU/Linux/m32r specific low level interface, for the remote server for GDB. + Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#define m32r_num_regs 25 + +static int m32r_regmap[] = { +#ifdef PT_R0 + PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7, + PT_R8, PT_R9, PT_R10, PT_R11, PT_R12, PT_FP, PT_LR, PT_SPU, + PT_PSW, PT_CBR, PT_SPI, PT_SPU, PT_BPC, PT_PC, PT_ACCL, PT_ACCH, PT_EVB +#else + 4 * 4, 4 * 5, 4 * 6, 4 * 7, 4 * 0, 4 * 1, 4 * 2, 4 * 8, + 4 * 9, 4 * 10, 4 * 11, 4 * 12, 4 * 13, 4 * 24, 4 * 25, 4 * 23, + 4 * 19, 4 * 31, 4 * 26, 4 * 23, 4 * 20, 4 * 30, 4 * 16, 4 * 15, 4 * 32 +#endif +}; + +static int +m32r_cannot_store_register (int regno) +{ + return (regno >= m32r_num_regs); +} + +static int +m32r_cannot_fetch_register (int regno) +{ + return (regno >= m32r_num_regs); +} + +static CORE_ADDR +m32r_get_pc () +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + return pc; +} + +static void +m32r_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +static const unsigned short m32r_breakpoint = 0x10f1; +#define m32r_breakpoint_len 2 + +static int +m32r_breakpoint_at (CORE_ADDR where) +{ + unsigned short insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, + m32r_breakpoint_len); + if (insn == m32r_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + one. */ + return 0; +} + +struct linux_target_ops the_low_target = { + m32r_num_regs, + m32r_regmap, + m32r_cannot_fetch_register, + m32r_cannot_store_register, + m32r_get_pc, + m32r_set_pc, + (const unsigned char *) &m32r_breakpoint, + m32r_breakpoint_len, + NULL, + 0, + m32r_breakpoint_at, +};
linux-m32r-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-m68k-low.c =================================================================== --- linux-m68k-low.c (nonexistent) +++ linux-m68k-low.c (revision 816) @@ -0,0 +1,166 @@ +/* GNU/Linux/m68k specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#define m68k_num_regs 29 +#define m68k_num_gregs 18 + +/* This table must line up with REGISTER_NAMES in tm-m68k.h */ +static int m68k_regmap[] = +{ +#ifdef PT_D0 + PT_D0 * 4, PT_D1 * 4, PT_D2 * 4, PT_D3 * 4, + PT_D4 * 4, PT_D5 * 4, PT_D6 * 4, PT_D7 * 4, + PT_A0 * 4, PT_A1 * 4, PT_A2 * 4, PT_A3 * 4, + PT_A4 * 4, PT_A5 * 4, PT_A6 * 4, PT_USP * 4, + PT_SR * 4, PT_PC * 4, +#else + 14 * 4, 0 * 4, 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, + 7 * 4, 8 * 4, 9 * 4, 10 * 4, 11 * 4, 12 * 4, 13 * 4, 15 * 4, + 17 * 4, 18 * 4, +#endif +#ifdef PT_FP0 + PT_FP0 * 4, PT_FP1 * 4, PT_FP2 * 4, PT_FP3 * 4, + PT_FP4 * 4, PT_FP5 * 4, PT_FP6 * 4, PT_FP7 * 4, + PT_FPCR * 4, PT_FPSR * 4, PT_FPIAR * 4 +#else + 21 * 4, 24 * 4, 27 * 4, 30 * 4, 33 * 4, 36 * 4, + 39 * 4, 42 * 4, 45 * 4, 46 * 4, 47 * 4 +#endif +}; + +static int +m68k_cannot_store_register (int regno) +{ + return (regno >= m68k_num_regs); +} + +static int +m68k_cannot_fetch_register (int regno) +{ + return (regno >= m68k_num_regs); +} + +#ifdef HAVE_PTRACE_GETREGS +#include +#include + +static void +m68k_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < m68k_num_gregs; i++) + collect_register (i, (char *) buf + m68k_regmap[i]); +} + +static void +m68k_store_gregset (const void *buf) +{ + int i; + + for (i = 0; i < m68k_num_gregs; i++) + supply_register (i, (const char *) buf + m68k_regmap[i]); +} + +static void +m68k_fill_fpregset (void *buf) +{ + int i; + + for (i = m68k_num_gregs; i < m68k_num_regs; i++) + collect_register (i, ((char *) buf + + (m68k_regmap[i] - m68k_regmap[m68k_num_gregs]))); +} + +static void +m68k_store_fpregset (const void *buf) +{ + int i; + + for (i = m68k_num_gregs; i < m68k_num_regs; i++) + supply_register (i, ((const char *) buf + + (m68k_regmap[i] - m68k_regmap[m68k_num_gregs]))); +} + +#endif /* HAVE_PTRACE_GETREGS */ + +struct regset_info target_regsets[] = { +#ifdef HAVE_PTRACE_GETREGS + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), + GENERAL_REGS, + m68k_fill_gregset, m68k_store_gregset }, + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), + FP_REGS, + m68k_fill_fpregset, m68k_store_fpregset }, +#endif /* HAVE_PTRACE_GETREGS */ + { 0, 0, -1, -1, NULL, NULL } +}; + +static const unsigned char m68k_breakpoint[] = { 0x4E, 0x4F }; +#define m68k_breakpoint_len 2 + +static CORE_ADDR +m68k_get_pc () +{ + unsigned long pc; + + collect_register_by_name ("pc", &pc); + return pc; +} + +static void +m68k_set_pc (CORE_ADDR value) +{ + unsigned long newpc = value; + + supply_register_by_name ("pc", &newpc); +} + +static int +m68k_breakpoint_at (CORE_ADDR pc) +{ + unsigned char c[2]; + + read_inferior_memory (pc, c, 2); + if (c[0] == 0x4E && c[1] == 0x4F) + return 1; + + return 0; +} + +struct linux_target_ops the_low_target = { + m68k_num_regs, + m68k_regmap, + m68k_cannot_fetch_register, + m68k_cannot_store_register, + m68k_get_pc, + m68k_set_pc, + m68k_breakpoint, + m68k_breakpoint_len, + NULL, + 2, + m68k_breakpoint_at, +};
linux-m68k-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: configure.ac =================================================================== --- configure.ac (nonexistent) +++ configure.ac (revision 816) @@ -0,0 +1,232 @@ +dnl Autoconf configure script for GDB server. +dnl Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006 +dnl Free Software Foundation, Inc. +dnl +dnl This file is part of GDB. +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see . + +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59)dnl + +AC_INIT(server.c) +AC_CONFIG_HEADER(config.h:config.in) + +AC_PROG_CC +AC_GNU_SOURCE + +AC_CANONICAL_SYSTEM + +AC_PROG_INSTALL + +AC_ARG_PROGRAM + +AC_HEADER_STDC + +AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h dnl + proc_service.h sys/procfs.h thread_db.h linux/elf.h dnl + stdlib.h unistd.h dnl + errno.h fcntl.h signal.h sys/file.h malloc.h dnl + sys/ioctl.h netinet/in.h sys/socket.h netdb.h dnl + netinet/tcp.h arpa/inet.h sys/wait.h) +AC_CHECK_FUNCS(pread pwrite pread64) + +have_errno=no +AC_MSG_CHECKING(for errno) +AC_TRY_LINK([ +#if HAVE_ERRNO_H +#include +#endif], [static int x; x = errno;], + [AC_MSG_RESULT(yes - in errno.h); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) have_errno=yes]) +if test $have_errno = no; then +AC_TRY_LINK([ +#if HAVE_ERRNO_H +#include +#endif], [extern int errno; static int x; x = errno;], + [AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_ERRNO, 1, [Define if errno is available]) AC_DEFINE(MUST_DEFINE_ERRNO, 1, [Checking if errno must be defined])], + [AC_MSG_RESULT(no)]) +fi + +AC_CHECK_DECLS([strerror, perror]) + +AC_CHECK_TYPES(socklen_t, [], [], +[#include +#include +]) + +# Check for various supplementary target information (beyond the +# triplet) which might affect the choices in configure.srv. +case "${target}" in + arm*-*-linux*) + AC_CACHE_CHECK([if iWMMXt is selected], [gdb_cv_arm_iwmmxt], + [save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $CFLAGS" + AC_EGREP_CPP([got it], [ +#ifdef __IWMMXT__ +got it +#endif + ], [gdb_cv_arm_iwmmxt=yes], + [gdb_cv_arm_iwmmxt=no]) + CPPFLAGS="$save_CPPFLAGS"]) + ;; + powerpc*-*-*) + AC_CACHE_CHECK([if Altivec is selected], [gdb_cv_ppc_altivec], + [save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $CFLAGS" + AC_EGREP_CPP([got it], [ +#ifdef __ALTIVEC__ +got it +#endif + ], [gdb_cv_ppc_altivec=yes], + [gdb_cv_ppc_altivec=no]) + CPPFLAGS="$save_CPPFLAGS"]) + AC_CACHE_CHECK([if SPE is selected], [gdb_cv_ppc_spe], + [save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $CFLAGS" + AC_EGREP_CPP([got it], [ +#ifdef __SPE__ +got it +#endif + ], [gdb_cv_ppc_spe=yes], + [gdb_cv_ppc_spe=no]) + CPPFLAGS="$save_CPPFLAGS"]) + ;; +esac + +. ${srcdir}/configure.srv + +if test "${srv_mingwce}" = "yes"; then + LIBS="$LIBS -lws2" +elif test "${srv_mingw}" = "yes"; then + LIBS="$LIBS -lwsock32" +fi + +if test "${srv_mingw}" = "yes"; then + AC_DEFINE(USE_WIN32API, 1, + [Define if we should use the Windows API, instead of the + POSIX API. On Windows, we use the Windows API when + building for MinGW, but the POSIX API when building + for Cygwin.]) +fi + +if test "${srv_linux_usrregs}" = "yes"; then + AC_DEFINE(HAVE_LINUX_USRREGS, 1, + [Define if the target supports PTRACE_PEEKUSR for register ] + [access.]) +fi + +if test "${srv_linux_regsets}" = "yes"; then + AC_DEFINE(HAVE_LINUX_REGSETS, 1, + [Define if the target supports register sets.]) + + AC_MSG_CHECKING(for PTRACE_GETREGS) + AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getregs, + [AC_TRY_COMPILE([#include ], + [PTRACE_GETREGS;], + [gdbsrv_cv_have_ptrace_getregs=yes], + [gdbsrv_cv_have_ptrace_getregs=no])]) + AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getregs) + if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then + AC_DEFINE(HAVE_PTRACE_GETREGS, 1, + [Define if the target supports PTRACE_GETREGS for register ] + [access.]) + fi + + AC_MSG_CHECKING(for PTRACE_GETFPXREGS) + AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getfpxregs, + [AC_TRY_COMPILE([#include ], + [PTRACE_GETFPXREGS;], + [gdbsrv_cv_have_ptrace_getfpxregs=yes], + [gdbsrv_cv_have_ptrace_getfpxregs=no])]) + AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getfpxregs) + if test "${gdbsrv_cv_have_ptrace_getfpxregs}" = "yes"; then + AC_DEFINE(HAVE_PTRACE_GETFPXREGS, 1, + [Define if the target supports PTRACE_GETFPXREGS for extended ] + [register access.]) + fi +fi + +if test "$ac_cv_header_sys_procfs_h" = yes; then + BFD_HAVE_SYS_PROCFS_TYPE(lwpid_t) + BFD_HAVE_SYS_PROCFS_TYPE(psaddr_t) + BFD_HAVE_SYS_PROCFS_TYPE(prgregset_t) + BFD_HAVE_SYS_PROCFS_TYPE(elf_fpregset_t) +fi + +srv_thread_depfiles= +srv_libs= +USE_THREAD_DB= + +if test "$srv_linux_thread_db" = "yes"; then + SRV_CHECK_THREAD_DB + if test "$srv_cv_thread_db" = no; then + AC_WARN([Could not find libthread_db.]) + AC_WARN([Disabling thread support in gdbserver.]) + srv_linux_thread_db=no + else + srv_libs="$srv_cv_thread_db" + SRV_CHECK_TLS_GET_ADDR + fi + old_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -rdynamic" + AC_TRY_LINK([], [], [RDYNAMIC=-rdynamic], [RDYNAMIC=]) + AC_SUBST(RDYNAMIC) + LDFLAGS="$old_LDFLAGS" +fi + +if test "$srv_linux_thread_db" = "yes"; then + srv_thread_depfiles="thread-db.o proc-service.o" + USE_THREAD_DB="-DUSE_THREAD_DB" + AC_CACHE_CHECK([for TD_VERSION], gdbsrv_cv_have_td_version, + [AC_TRY_COMPILE([#include ], [TD_VERSION;], + [gdbsrv_cv_have_td_version=yes], + [gdbsrv_cv_have_td_version=no])]) + if test $gdbsrv_cv_have_td_version = yes; then + AC_DEFINE(HAVE_TD_VERSION, 1, [Define if TD_VERSION is available.]) + fi + + if test "$srv_cv_tls_get_addr" = yes; then + AC_DEFINE(HAVE_TD_THR_TLS_GET_ADDR, 1, [Define if td_thr_tls_get_addr is available.]) + fi +fi + +if test "$srv_xmltarget" != ""; then + srv_xmltarget="\$(XML_DIR)/$srv_xmltarget" + srv_xmlbuiltin="xml-builtin.o" + AC_DEFINE(USE_XML, 1, [Define if an XML target description is available.]) + + tmp_xmlfiles=$srv_xmlfiles + srv_xmlfiles="target.xml" + for f in $tmp_xmlfiles; do + srv_xmlfiles="$srv_xmlfiles \$(XML_DIR)/$f" + done +fi + +GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj $srv_hostio_err_objs $srv_thread_depfiles" +GDBSERVER_LIBS="$srv_libs" + +AC_SUBST(GDBSERVER_DEPFILES) +AC_SUBST(GDBSERVER_LIBS) +AC_SUBST(USE_THREAD_DB) +AC_SUBST(srv_xmlbuiltin) +AC_SUBST(srv_xmlfiles) +AC_SUBST(srv_xmltarget) + +AC_OUTPUT(Makefile, +[case x$CONFIG_HEADERS in +xconfig.h:config.in) +echo > stamp-h ;; +esac +])
configure.ac Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-i386-low.c =================================================================== --- linux-i386-low.c (nonexistent) +++ linux-i386-low.c (revision 816) @@ -0,0 +1,205 @@ +/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, + 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" +#include "i387-fp.h" + +#include "gdb_proc_service.h" + +#include + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#ifndef PTRACE_GET_THREAD_AREA +#define PTRACE_GET_THREAD_AREA 25 +#endif + +/* This module only supports access to the general purpose registers. */ + +#define i386_num_regs 16 + +/* This stuff comes from i386-linux-nat.c. */ + +/* Mapping between the general-purpose registers in `struct user' + format and GDB's register array layout. */ +static int i386_regmap[] = +{ + EAX * 4, ECX * 4, EDX * 4, EBX * 4, + UESP * 4, EBP * 4, ESI * 4, EDI * 4, + EIP * 4, EFL * 4, CS * 4, SS * 4, + DS * 4, ES * 4, FS * 4, GS * 4 +}; + +/* Called by libthread_db. */ + +ps_err_e +ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base) +{ + unsigned int desc[4]; + + if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, + (void *) idx, (unsigned long) &desc) < 0) + return PS_ERR; + + *(int *)base = desc[1]; + return PS_OK; +} + +static int +i386_cannot_store_register (int regno) +{ + return (regno >= i386_num_regs); +} + +static int +i386_cannot_fetch_register (int regno) +{ + return (regno >= i386_num_regs); +} + + +#ifdef HAVE_PTRACE_GETREGS +#include +#include + +static void +i386_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < i386_num_regs; i++) + collect_register (i, ((char *) buf) + i386_regmap[i]); + + collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); +} + +static void +i386_store_gregset (const void *buf) +{ + int i; + + for (i = 0; i < i386_num_regs; i++) + supply_register (i, ((char *) buf) + i386_regmap[i]); + + supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4); +} + +static void +i386_fill_fpregset (void *buf) +{ + i387_cache_to_fsave (buf); +} + +static void +i386_store_fpregset (const void *buf) +{ + i387_fsave_to_cache (buf); +} + +static void +i386_fill_fpxregset (void *buf) +{ + i387_cache_to_fxsave (buf); +} + +static void +i386_store_fpxregset (const void *buf) +{ + i387_fxsave_to_cache (buf); +} + +#endif /* HAVE_PTRACE_GETREGS */ + +struct regset_info target_regsets[] = { +#ifdef HAVE_PTRACE_GETREGS + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), + GENERAL_REGS, + i386_fill_gregset, i386_store_gregset }, +# ifdef HAVE_PTRACE_GETFPXREGS + { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t), + EXTENDED_REGS, + i386_fill_fpxregset, i386_store_fpxregset }, +# endif + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), + FP_REGS, + i386_fill_fpregset, i386_store_fpregset }, +#endif /* HAVE_PTRACE_GETREGS */ + { 0, 0, -1, -1, NULL, NULL } +}; + +static const unsigned char i386_breakpoint[] = { 0xCC }; +#define i386_breakpoint_len 1 + +extern int debug_threads; + +static CORE_ADDR +i386_get_pc () +{ + unsigned long pc; + + collect_register_by_name ("eip", &pc); + + if (debug_threads) + fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); + return pc; +} + +static void +i386_set_pc (CORE_ADDR newpc) +{ + if (debug_threads) + fprintf (stderr, "set pc to %08lx\n", (long) newpc); + supply_register_by_name ("eip", &newpc); +} + +static int +i386_breakpoint_at (CORE_ADDR pc) +{ + unsigned char c; + + read_inferior_memory (pc, &c, 1); + if (c == 0xCC) + return 1; + + return 0; +} + +struct linux_target_ops the_low_target = { + i386_num_regs, + i386_regmap, + i386_cannot_fetch_register, + i386_cannot_store_register, + i386_get_pc, + i386_set_pc, + i386_breakpoint, + i386_breakpoint_len, + NULL, + 1, + i386_breakpoint_at, + NULL, + NULL, + NULL, + NULL, + 0, + "i386" +};
linux-i386-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-crisv32-low.c =================================================================== --- linux-crisv32-low.c (nonexistent) +++ linux-crisv32-low.c (revision 816) @@ -0,0 +1,378 @@ +/* GNU/Linux/CRIS specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" +#include + +/* CRISv32 */ +#define cris_num_regs 49 + +/* Note: Ignoring USP (having the stack pointer in two locations causes trouble + without any significant gain). */ + +/* Locations need to match . */ +static int cris_regmap[] = { + 1*4, 2*4, 3*4, 4*4, + 5*4, 6*4, 7*4, 8*4, + 9*4, 10*4, 11*4, 12*4, + 13*4, 14*4, 24*4, 15*4, + + -1, -1, -1, 16*4, + -1, 22*4, 23*4, 17*4, + -1, -1, 21*4, 20*4, + -1, 19*4, -1, 18*4, + + 25*4, + + 26*4, -1, -1, 29*4, + 30*4, 31*4, 32*4, 33*4, + 34*4, 35*4, 36*4, 37*4, + 38*4, 39*4, 40*4, -1 + +}; + +extern int debug_threads; + +static CORE_ADDR +cris_get_pc (void) +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + if (debug_threads) + fprintf (stderr, "stop pc is %08lx\n", pc); + return pc; +} + +static void +cris_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +static const unsigned short cris_breakpoint = 0xe938; +#define cris_breakpoint_len 2 + +static int +cris_breakpoint_at (CORE_ADDR where) +{ + unsigned short insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, + cris_breakpoint_len); + if (insn == cris_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + one. */ + return 0; +} + +/* We only place breakpoints in empty marker functions, and thread locking + is outside of the function. So rather than importing software single-step, + we can just run until exit. */ + +/* FIXME: This function should not be needed, since we have PTRACE_SINGLESTEP + for CRISv32. Without it, td_ta_event_getmsg in thread_db_create_event + will fail when debugging multi-threaded applications. */ + +static CORE_ADDR +cris_reinsert_addr (void) +{ + unsigned long pc; + collect_register_by_name ("srp", &pc); + return pc; +} + +static void +cris_write_data_breakpoint (int bp, unsigned long start, unsigned long end) +{ + switch (bp) + { + case 0: + supply_register_by_name ("s3", &start); + supply_register_by_name ("s4", &end); + break; + case 1: + supply_register_by_name ("s5", &start); + supply_register_by_name ("s6", &end); + break; + case 2: + supply_register_by_name ("s7", &start); + supply_register_by_name ("s8", &end); + break; + case 3: + supply_register_by_name ("s9", &start); + supply_register_by_name ("s10", &end); + break; + case 4: + supply_register_by_name ("s11", &start); + supply_register_by_name ("s12", &end); + break; + case 5: + supply_register_by_name ("s13", &start); + supply_register_by_name ("s14", &end); + break; + } +} + +static int +cris_insert_watchpoint (char type, CORE_ADDR addr, int len) +{ + int bp; + unsigned long bp_ctrl; + unsigned long start, end; + unsigned long ccs; + + /* Breakpoint/watchpoint types (GDB terminology): + 0 = memory breakpoint for instructions + (not supported; done via memory write instead) + 1 = hardware breakpoint for instructions (not supported) + 2 = write watchpoint (supported) + 3 = read watchpoint (supported) + 4 = access watchpoint (supported). */ + + if (type < '2' || type > '4') + { + /* Unsupported. */ + return 1; + } + + /* Read watchpoints are set as access watchpoints, because of GDB's + inability to deal with pure read watchpoints. */ + if (type == '3') + type = '4'; + + /* Get the configuration register. */ + collect_register_by_name ("s0", &bp_ctrl); + + /* The watchpoint allocation scheme is the simplest possible. + For example, if a region is watched for read and + a write watch is requested, a new watchpoint will + be used. Also, if a watch for a region that is already + covered by one or more existing watchpoints, a new + watchpoint will be used. */ + + /* First, find a free data watchpoint. */ + for (bp = 0; bp < 6; bp++) + { + /* Each data watchpoint's control registers occupy 2 bits + (hence the 3), starting at bit 2 for D0 (hence the 2) + with 4 bits between for each watchpoint (yes, the 4). */ + if (!(bp_ctrl & (0x3 << (2 + (bp * 4))))) + break; + } + + if (bp > 5) + { + /* We're out of watchpoints. */ + return -1; + } + + /* Configure the control register first. */ + if (type == '3' || type == '4') + { + /* Trigger on read. */ + bp_ctrl |= (1 << (2 + bp * 4)); + } + if (type == '2' || type == '4') + { + /* Trigger on write. */ + bp_ctrl |= (2 << (2 + bp * 4)); + } + + /* Setup the configuration register. */ + supply_register_by_name ("s0", &bp_ctrl); + + /* Setup the range. */ + start = addr; + end = addr + len - 1; + + /* Configure the watchpoint register. */ + cris_write_data_breakpoint (bp, start, end); + + collect_register_by_name ("ccs", &ccs); + /* Set the S1 flag to enable watchpoints. */ + ccs |= (1 << 19); + supply_register_by_name ("ccs", &ccs); + + return 0; +} + +static int +cris_remove_watchpoint (char type, CORE_ADDR addr, int len) +{ + int bp; + unsigned long bp_ctrl; + unsigned long start, end; + + /* Breakpoint/watchpoint types: + 0 = memory breakpoint for instructions + (not supported; done via memory write instead) + 1 = hardware breakpoint for instructions (not supported) + 2 = write watchpoint (supported) + 3 = read watchpoint (supported) + 4 = access watchpoint (supported). */ + if (type < '2' || type > '4') + return -1; + + /* Read watchpoints are set as access watchpoints, because of GDB's + inability to deal with pure read watchpoints. */ + if (type == '3') + type = '4'; + + /* Get the configuration register. */ + collect_register_by_name ("s0", &bp_ctrl); + + /* Try to find a watchpoint that is configured for the + specified range, then check that read/write also matches. */ + + /* Ugly pointer arithmetic, since I cannot rely on a + single switch (addr) as there may be several watchpoints with + the same start address for example. */ + + unsigned long bp_d_regs[12]; + + /* Get all range registers to simplify search. */ + collect_register_by_name ("s3", &bp_d_regs[0]); + collect_register_by_name ("s4", &bp_d_regs[1]); + collect_register_by_name ("s5", &bp_d_regs[2]); + collect_register_by_name ("s6", &bp_d_regs[3]); + collect_register_by_name ("s7", &bp_d_regs[4]); + collect_register_by_name ("s8", &bp_d_regs[5]); + collect_register_by_name ("s9", &bp_d_regs[6]); + collect_register_by_name ("s10", &bp_d_regs[7]); + collect_register_by_name ("s11", &bp_d_regs[8]); + collect_register_by_name ("s12", &bp_d_regs[9]); + collect_register_by_name ("s13", &bp_d_regs[10]); + collect_register_by_name ("s14", &bp_d_regs[11]); + + for (bp = 0; bp < 6; bp++) + { + if (bp_d_regs[bp * 2] == addr + && bp_d_regs[bp * 2 + 1] == (addr + len - 1)) { + /* Matching range. */ + int bitpos = 2 + bp * 4; + int rw_bits; + + /* Read/write bits for this BP. */ + rw_bits = (bp_ctrl & (0x3 << bitpos)) >> bitpos; + + if ((type == '3' && rw_bits == 0x1) + || (type == '2' && rw_bits == 0x2) + || (type == '4' && rw_bits == 0x3)) + { + /* Read/write matched. */ + break; + } + } + } + + if (bp > 5) + { + /* No watchpoint matched. */ + return -1; + } + + /* Found a matching watchpoint. Now, deconfigure it by + both disabling read/write in bp_ctrl and zeroing its + start/end addresses. */ + bp_ctrl &= ~(3 << (2 + (bp * 4))); + /* Setup the configuration register. */ + supply_register_by_name ("s0", &bp_ctrl); + + start = end = 0; + /* Configure the watchpoint register. */ + cris_write_data_breakpoint (bp, start, end); + + /* Note that we don't clear the S1 flag here. It's done when continuing. */ + return 0; +} + +static int +cris_stopped_by_watchpoint (void) +{ + unsigned long exs; + + collect_register_by_name ("exs", &exs); + + return (((exs & 0xff00) >> 8) == 0xc); +} + +static CORE_ADDR +cris_stopped_data_address (void) +{ + unsigned long eda; + + collect_register_by_name ("eda", &eda); + + /* FIXME: Possibly adjust to match watched range. */ + return eda; +} + +static void +cris_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < cris_num_regs; i++) + { + if (cris_regmap[i] != -1) + collect_register (i, ((char *) buf) + cris_regmap[i]); + } +} + +static void +cris_store_gregset (const void *buf) +{ + int i; + + for (i = 0; i < cris_num_regs; i++) + { + if (cris_regmap[i] != -1) + supply_register (i, ((char *) buf) + cris_regmap[i]); + } +} + +typedef unsigned long elf_gregset_t[cris_num_regs]; + +struct regset_info target_regsets[] = { + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), + GENERAL_REGS, cris_fill_gregset, cris_store_gregset }, + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + -1, + NULL, + NULL, + NULL, + cris_get_pc, + cris_set_pc, + (const unsigned char *) &cris_breakpoint, + cris_breakpoint_len, + cris_reinsert_addr, + 0, + cris_breakpoint_at, + cris_insert_watchpoint, + cris_remove_watchpoint, + cris_stopped_by_watchpoint, + cris_stopped_data_address, +};
linux-crisv32-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: hostio-errno.c =================================================================== --- hostio-errno.c (nonexistent) +++ hostio-errno.c (revision 816) @@ -0,0 +1,88 @@ +/* Host file transfer support for gdbserver. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + Contributed by CodeSourcery. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* This file implements the hostio_last_error target callback + on top of errno. */ + +#include +#include "server.h" +#include "gdb/fileio.h" + +static int +errno_to_fileio_error (int error) +{ + switch (error) + { + case EPERM: + return FILEIO_EPERM; + case ENOENT: + return FILEIO_ENOENT; + case EINTR: + return FILEIO_EINTR; + case EIO: + return FILEIO_EIO; + case EBADF: + return FILEIO_EBADF; + case EACCES: + return FILEIO_EACCES; + case EFAULT: + return FILEIO_EFAULT; + case EBUSY: + return FILEIO_EBUSY; + case EEXIST: + return FILEIO_EEXIST; + case ENODEV: + return FILEIO_ENODEV; + case ENOTDIR: + return FILEIO_ENOTDIR; + case EISDIR: + return FILEIO_EISDIR; + case EINVAL: + return FILEIO_EINVAL; + case ENFILE: + return FILEIO_ENFILE; + case EMFILE: + return FILEIO_EMFILE; + case EFBIG: + return FILEIO_EFBIG; + case ENOSPC: + return FILEIO_ENOSPC; + case ESPIPE: + return FILEIO_ESPIPE; + case EROFS: + return FILEIO_EROFS; + case ENOSYS: + return FILEIO_ENOSYS; + case ENAMETOOLONG: + return FILEIO_ENAMETOOLONG; + } + + return FILEIO_EUNKNOWN; +} + +void +hostio_last_error_from_errno (char *buf) +{ + int error = errno; + int fileio_error = errno_to_fileio_error (error); + sprintf (buf, "F-1,%x", fileio_error); +}
hostio-errno.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: config.in =================================================================== --- config.in (nonexistent) +++ config.in (revision 816) @@ -0,0 +1,176 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the declaration of `perror', and to 0 if you don't. + */ +#undef HAVE_DECL_PERROR + +/* Define to 1 if you have the declaration of `strerror', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR + +/* Define if has elf_fpregset_t. */ +#undef HAVE_ELF_FPREGSET_T + +/* Define if errno is available */ +#undef HAVE_ERRNO + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_ELF_H + +/* Define if the target supports register sets. */ +#undef HAVE_LINUX_REGSETS + +/* Define if the target supports PTRACE_PEEKUSR for register access. */ +#undef HAVE_LINUX_USRREGS + +/* Define if has lwpid_t. */ +#undef HAVE_LWPID_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the `pread' function. */ +#undef HAVE_PREAD + +/* Define to 1 if you have the `pread64' function. */ +#undef HAVE_PREAD64 + +/* Define if has prgregset_t. */ +#undef HAVE_PRGREGSET_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_PROC_SERVICE_H + +/* Define if has psaddr_t. */ +#undef HAVE_PSADDR_T + +/* Define if the target supports PTRACE_GETFPXREGS for extended register + access. */ +#undef HAVE_PTRACE_GETFPXREGS + +/* Define if the target supports PTRACE_GETREGS for register access. */ +#undef HAVE_PTRACE_GETREGS + +/* Define to 1 if you have the `pwrite' function. */ +#undef HAVE_PWRITE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SGTTY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if the system has the type `socklen_t'. */ +#undef HAVE_SOCKLEN_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_FILE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_REG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define if td_thr_tls_get_addr is available. */ +#undef HAVE_TD_THR_TLS_GET_ADDR + +/* Define if TD_VERSION is available. */ +#undef HAVE_TD_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TERMIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_THREAD_DB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Checking if errno must be defined */ +#undef MUST_DEFINE_ERRNO + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if we should use the Windows API, instead of the POSIX API. On + Windows, we use the Windows API when building for MinGW, but the POSIX API + when building for Cygwin. */ +#undef USE_WIN32API + +/* Define if an XML target description is available. */ +#undef USE_XML + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif Index: thread-db.c =================================================================== --- thread-db.c (nonexistent) +++ thread-db.c (revision 816) @@ -0,0 +1,459 @@ +/* Thread management interface, for the remote server for GDB. + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#include "server.h" + +#include "linux-low.h" + +extern int debug_threads; + +static int thread_db_use_events; + +#ifdef HAVE_THREAD_DB_H +#include +#endif + +#include "gdb_proc_service.h" + +#include + +/* Structure that identifies the child process for the + interface. */ +static struct ps_prochandle proc_handle; + +/* Connection to the libthread_db library. */ +static td_thragent_t *thread_agent; + +static int find_one_thread (int); +static int find_new_threads_callback (const td_thrhandle_t *th_p, void *data); + +static char * +thread_db_err_str (td_err_e err) +{ + static char buf[64]; + + switch (err) + { + case TD_OK: + return "generic 'call succeeded'"; + case TD_ERR: + return "generic error"; + case TD_NOTHR: + return "no thread to satisfy query"; + case TD_NOSV: + return "no sync handle to satisfy query"; + case TD_NOLWP: + return "no LWP to satisfy query"; + case TD_BADPH: + return "invalid process handle"; + case TD_BADTH: + return "invalid thread handle"; + case TD_BADSH: + return "invalid synchronization handle"; + case TD_BADTA: + return "invalid thread agent"; + case TD_BADKEY: + return "invalid key"; + case TD_NOMSG: + return "no event message for getmsg"; + case TD_NOFPREGS: + return "FPU register set not available"; + case TD_NOLIBTHREAD: + return "application not linked with libthread"; + case TD_NOEVENT: + return "requested event is not supported"; + case TD_NOCAPAB: + return "capability not available"; + case TD_DBERR: + return "debugger service failed"; + case TD_NOAPLIC: + return "operation not applicable to"; + case TD_NOTSD: + return "no thread-specific data for this thread"; + case TD_MALLOC: + return "malloc failed"; + case TD_PARTIALREG: + return "only part of register set was written/read"; + case TD_NOXREGS: + return "X register set not available for this thread"; +#ifdef HAVE_TD_VERSION + case TD_VERSION: + return "version mismatch between libthread_db and libpthread"; +#endif + default: + snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err); + return buf; + } +} + +#if 0 +static char * +thread_db_state_str (td_thr_state_e state) +{ + static char buf[64]; + + switch (state) + { + case TD_THR_STOPPED: + return "stopped by debugger"; + case TD_THR_RUN: + return "runnable"; + case TD_THR_ACTIVE: + return "active"; + case TD_THR_ZOMBIE: + return "zombie"; + case TD_THR_SLEEP: + return "sleeping"; + case TD_THR_STOPPED_ASLEEP: + return "stopped by debugger AND blocked"; + default: + snprintf (buf, sizeof (buf), "unknown thread_db state %d", state); + return buf; + } +} +#endif + +static int +thread_db_create_event (CORE_ADDR where) +{ + td_event_msg_t msg; + td_err_e err; + struct process_info *process; + + if (debug_threads) + fprintf (stderr, "Thread creation event.\n"); + + /* FIXME: This assumes we don't get another event. + In the LinuxThreads implementation, this is safe, + because all events come from the manager thread + (except for its own creation, of course). */ + err = td_ta_event_getmsg (thread_agent, &msg); + if (err != TD_OK) + fprintf (stderr, "thread getmsg err: %s\n", + thread_db_err_str (err)); + + /* If we do not know about the main thread yet, this would be a good time to + find it. We need to do this to pick up the main thread before any newly + created threads. */ + process = get_thread_process (current_inferior); + if (process->thread_known == 0) + find_one_thread (process->lwpid); + + /* msg.event == TD_EVENT_CREATE */ + + find_new_threads_callback (msg.th_p, NULL); + + return 0; +} + +#if 0 +static int +thread_db_death_event (CORE_ADDR where) +{ + if (debug_threads) + fprintf (stderr, "Thread death event.\n"); + + return 0; +} +#endif + +static int +thread_db_enable_reporting () +{ + td_thr_events_t events; + td_notify_t notify; + td_err_e err; + + /* Set the process wide mask saying which events we're interested in. */ + td_event_emptyset (&events); + td_event_addset (&events, TD_CREATE); + +#if 0 + /* This is reported to be broken in glibc 2.1.3. A different approach + will be necessary to support that. */ + td_event_addset (&events, TD_DEATH); +#endif + + err = td_ta_set_event (thread_agent, &events); + if (err != TD_OK) + { + warning ("Unable to set global thread event mask: %s", + thread_db_err_str (err)); + return 0; + } + + /* Get address for thread creation breakpoint. */ + err = td_ta_event_addr (thread_agent, TD_CREATE, ¬ify); + if (err != TD_OK) + { + warning ("Unable to get location for thread creation breakpoint: %s", + thread_db_err_str (err)); + return 0; + } + set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, + thread_db_create_event); + +#if 0 + /* Don't concern ourselves with reported thread deaths, only + with actual thread deaths (via wait). */ + + /* Get address for thread death breakpoint. */ + err = td_ta_event_addr (thread_agent, TD_DEATH, ¬ify); + if (err != TD_OK) + { + warning ("Unable to get location for thread death breakpoint: %s", + thread_db_err_str (err)); + return; + } + set_breakpoint_at ((CORE_ADDR) (unsigned long) notify.u.bptaddr, + thread_db_death_event); +#endif + + return 1; +} + +static int +find_one_thread (int lwpid) +{ + td_thrhandle_t th; + td_thrinfo_t ti; + td_err_e err; + struct thread_info *inferior; + struct process_info *process; + + inferior = (struct thread_info *) find_inferior_id (&all_threads, lwpid); + process = get_thread_process (inferior); + if (process->thread_known) + return 1; + + /* Get information about this thread. */ + err = td_ta_map_lwp2thr (thread_agent, process->lwpid, &th); + if (err != TD_OK) + error ("Cannot get thread handle for LWP %d: %s", + lwpid, thread_db_err_str (err)); + + err = td_thr_get_info (&th, &ti); + if (err != TD_OK) + error ("Cannot get thread info for LWP %d: %s", + lwpid, thread_db_err_str (err)); + + if (debug_threads) + fprintf (stderr, "Found thread %ld (LWP %d)\n", + ti.ti_tid, ti.ti_lid); + + if (process->lwpid != ti.ti_lid) + { + warning ("PID mismatch! Expected %ld, got %ld", + (long) process->lwpid, (long) ti.ti_lid); + return 0; + } + + if (thread_db_use_events) + { + err = td_thr_event_enable (&th, 1); + if (err != TD_OK) + error ("Cannot enable thread event reporting for %d: %s", + ti.ti_lid, thread_db_err_str (err)); + } + + /* If the new thread ID is zero, a final thread ID will be available + later. Do not enable thread debugging yet. */ + if (ti.ti_tid == 0) + return 0; + + process->thread_known = 1; + process->tid = ti.ti_tid; + process->th = th; + + return 1; +} + +static void +maybe_attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p) +{ + td_err_e err; + struct thread_info *inferior; + struct process_info *process; + + inferior = (struct thread_info *) find_inferior_id (&all_threads, + ti_p->ti_lid); + if (inferior != NULL) + return; + + if (debug_threads) + fprintf (stderr, "Attaching to thread %ld (LWP %d)\n", + ti_p->ti_tid, ti_p->ti_lid); + linux_attach_lwp (ti_p->ti_lid); + inferior = (struct thread_info *) find_inferior_id (&all_threads, + ti_p->ti_lid); + if (inferior == NULL) + { + warning ("Could not attach to thread %ld (LWP %d)\n", + ti_p->ti_tid, ti_p->ti_lid); + return; + } + + process = inferior_target_data (inferior); + + process->tid = ti_p->ti_tid; + process->thread_known = 1; + process->th = *th_p; + + if (thread_db_use_events) + { + err = td_thr_event_enable (th_p, 1); + if (err != TD_OK) + error ("Cannot enable thread event reporting for %d: %s", + ti_p->ti_lid, thread_db_err_str (err)); + } +} + +static int +find_new_threads_callback (const td_thrhandle_t *th_p, void *data) +{ + td_thrinfo_t ti; + td_err_e err; + + err = td_thr_get_info (th_p, &ti); + if (err != TD_OK) + error ("Cannot get thread info: %s", thread_db_err_str (err)); + + /* Check for zombies. */ + if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) + return 0; + + maybe_attach_thread (th_p, &ti); + + return 0; +} + +static void +thread_db_find_new_threads (void) +{ + td_err_e err; + + /* This function is only called when we first initialize thread_db. + First locate the initial thread. If it is not ready for + debugging yet, then stop. */ + if (find_one_thread (all_threads.head->id) == 0) + return; + + /* Iterate over all user-space threads to discover new threads. */ + err = td_ta_thr_iter (thread_agent, find_new_threads_callback, NULL, + TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, + TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); + if (err != TD_OK) + error ("Cannot find new threads: %s", thread_db_err_str (err)); +} + +/* Cache all future symbols that thread_db might request. We can not + request symbols at arbitrary states in the remote protocol, only + when the client tells us that new symbols are available. So when + we load the thread library, make sure to check the entire list. */ + +static void +thread_db_look_up_symbols (void) +{ + const char **sym_list = td_symbol_list (); + CORE_ADDR unused; + + for (sym_list = td_symbol_list (); *sym_list; sym_list++) + look_up_one_symbol (*sym_list, &unused); +} + +int +thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset, + CORE_ADDR load_module, CORE_ADDR *address) +{ +#if HAVE_TD_THR_TLS_GET_ADDR + psaddr_t addr; + td_err_e err; + struct process_info *process; + + process = get_thread_process (thread); + if (!process->thread_known) + find_one_thread (process->lwpid); + if (!process->thread_known) + return TD_NOTHR; + + /* Note the cast through uintptr_t: this interface only works if + a target address fits in a psaddr_t, which is a host pointer. + So a 32-bit debugger can not access 64-bit TLS through this. */ + err = td_thr_tls_get_addr (&process->th, (psaddr_t) (uintptr_t) load_module, + offset, &addr); + if (err == TD_OK) + { + *address = (CORE_ADDR) (uintptr_t) addr; + return 0; + } + else + return err; +#else + return -1; +#endif +} + +int +thread_db_init (int use_events) +{ + int err; + + /* FIXME drow/2004-10-16: This is the "overall process ID", which + GNU/Linux calls tgid, "thread group ID". When we support + attaching to threads, the original thread may not be the correct + thread. We would have to get the process ID from /proc for NPTL. + For LinuxThreads we could do something similar: follow the chain + of parent processes until we find the highest one we're attached + to, and use its tgid. + + This isn't the only place in gdbserver that assumes that the first + process in the list is the thread group leader. */ + proc_handle.pid = ((struct inferior_list_entry *)current_inferior)->id; + + /* Allow new symbol lookups. */ + all_symbols_looked_up = 0; + + thread_db_use_events = use_events; + + err = td_ta_new (&proc_handle, &thread_agent); + switch (err) + { + case TD_NOLIBTHREAD: + /* No thread library was detected. */ + return 0; + + case TD_OK: + /* The thread library was detected. */ + + if (use_events && thread_db_enable_reporting () == 0) + return 0; + thread_db_find_new_threads (); + thread_db_look_up_symbols (); + all_symbols_looked_up = 1; + return 1; + + default: + warning ("error initializing thread_db library: %s", + thread_db_err_str (err)); + } + + return 0; +}
thread-db.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-cris-low.c =================================================================== --- linux-cris-low.c (nonexistent) +++ linux-cris-low.c (revision 816) @@ -0,0 +1,123 @@ +/* GNU/Linux/CRIS specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" +#include + +/* CRISv10 */ +#define cris_num_regs 32 + +/* Locations need to match . */ +static int cris_regmap[] = { + 15*4, 14*4, 13*4, 12*4, + 11*4, 10*4, 9*4, 8*4, + 7*4, 6*4, 5*4, 4*4, + 3*4, 2*4, 23*4, 19*4, + + -1, -1, -1, -1, + -1, 17*4, -1, 16*4, + -1, -1, -1, 18*4, + -1, 17*4, -1, -1 + +}; + +static int +cris_cannot_store_register (int regno) +{ + if (cris_regmap[regno] == -1) + return 1; + + return (regno >= cris_num_regs); +} + +static int +cris_cannot_fetch_register (int regno) +{ + if (cris_regmap[regno] == -1) + return 1; + + return (regno >= cris_num_regs); +} + +extern int debug_threads; + +static CORE_ADDR +cris_get_pc (void) +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + if (debug_threads) + fprintf (stderr, "stop pc is %08lx\n", pc); + return pc; +} + +static void +cris_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +static const unsigned short cris_breakpoint = 0xe938; +#define cris_breakpoint_len 2 + +static int +cris_breakpoint_at (CORE_ADDR where) +{ + unsigned short insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, + cris_breakpoint_len); + if (insn == cris_breakpoint) + return 1; + + /* If necessary, recognize more trap instructions here. GDB only uses the + one. */ + return 0; +} + +/* We only place breakpoints in empty marker functions, and thread locking + is outside of the function. So rather than importing software single-step, + we can just run until exit. */ +static CORE_ADDR +cris_reinsert_addr (void) +{ + unsigned long pc; + collect_register_by_name ("srp", &pc); + return pc; +} + +struct linux_target_ops the_low_target = { + cris_num_regs, + cris_regmap, + cris_cannot_fetch_register, + cris_cannot_store_register, + cris_get_pc, + cris_set_pc, + (const unsigned char *) &cris_breakpoint, + cris_breakpoint_len, + cris_reinsert_addr, + 0, + cris_breakpoint_at, + 0, + 0, + 0, + 0, +};
linux-cris-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: i387-fp.c =================================================================== --- i387-fp.c (nonexistent) +++ i387-fp.c (revision 816) @@ -0,0 +1,292 @@ +/* i387-specific utility functions, for the remote server for GDB. + Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "i387-fp.h" + +int num_xmm_registers = 8; + +/* Note: These functions preserve the reserved bits in control registers. + However, gdbserver promptly throws away that information. */ + +/* These structs should have the proper sizes and alignment on both + i386 and x86-64 machines. */ + +struct i387_fsave { + /* All these are only sixteen bits, plus padding, except for fop (which + is only eleven bits), and fooff / fioff (which are 32 bits each). */ + unsigned short fctrl; + unsigned short pad1; + unsigned short fstat; + unsigned short pad2; + unsigned short ftag; + unsigned short pad3; + unsigned int fioff; + unsigned short fiseg; + unsigned short fop; + unsigned int fooff; + unsigned short foseg; + unsigned short pad4; + + /* Space for eight 80-bit FP values. */ + unsigned char st_space[80]; +}; + +struct i387_fxsave { + /* All these are only sixteen bits, plus padding, except for fop (which + is only eleven bits), and fooff / fioff (which are 32 bits each). */ + unsigned short fctrl; + unsigned short fstat; + unsigned short ftag; + unsigned short fop; + unsigned int fioff; + unsigned short fiseg; + unsigned short pad1; + unsigned int fooff; + unsigned short foseg; + unsigned short pad12; + + unsigned int mxcsr; + unsigned int pad3; + + /* Space for eight 80-bit FP values in 128-bit spaces. */ + unsigned char st_space[128]; + + /* Space for eight 128-bit XMM values, or 16 on x86-64. */ + unsigned char xmm_space[256]; +}; + +void +i387_cache_to_fsave (void *buf) +{ + struct i387_fsave *fp = (struct i387_fsave *) buf; + int i; + int st0_regnum = find_regno ("st0"); + unsigned long val, val2; + + for (i = 0; i < 8; i++) + collect_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10); + + collect_register_by_name ("fioff", &fp->fioff); + collect_register_by_name ("fooff", &fp->fooff); + + /* This one's 11 bits... */ + collect_register_by_name ("fop", &val2); + fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800); + + /* Some registers are 16-bit. */ + collect_register_by_name ("fctrl", &val); + fp->fctrl = val; + + collect_register_by_name ("fstat", &val); + val &= 0xFFFF; + fp->fstat = val; + + collect_register_by_name ("ftag", &val); + val &= 0xFFFF; + fp->ftag = val; + + collect_register_by_name ("fiseg", &val); + val &= 0xFFFF; + fp->fiseg = val; + + collect_register_by_name ("foseg", &val); + val &= 0xFFFF; + fp->foseg = val; +} + +void +i387_fsave_to_cache (const void *buf) +{ + struct i387_fsave *fp = (struct i387_fsave *) buf; + int i; + int st0_regnum = find_regno ("st0"); + unsigned long val; + + for (i = 0; i < 8; i++) + supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10); + + supply_register_by_name ("fioff", &fp->fioff); + supply_register_by_name ("fooff", &fp->fooff); + + /* Some registers are 16-bit. */ + val = fp->fctrl & 0xFFFF; + supply_register_by_name ("fctrl", &val); + + val = fp->fstat & 0xFFFF; + supply_register_by_name ("fstat", &val); + + val = fp->ftag & 0xFFFF; + supply_register_by_name ("ftag", &val); + + val = fp->fiseg & 0xFFFF; + supply_register_by_name ("fiseg", &val); + + val = fp->foseg & 0xFFFF; + supply_register_by_name ("foseg", &val); + + /* fop has only 11 valid bits. */ + val = (fp->fop) & 0x7FF; + supply_register_by_name ("fop", &val); +} + +void +i387_cache_to_fxsave (void *buf) +{ + struct i387_fxsave *fp = (struct i387_fxsave *) buf; + int i; + int st0_regnum = find_regno ("st0"); + int xmm0_regnum = find_regno ("xmm0"); + unsigned long val, val2; + + for (i = 0; i < 8; i++) + collect_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16); + for (i = 0; i < num_xmm_registers; i++) + collect_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16); + + collect_register_by_name ("fioff", &fp->fioff); + collect_register_by_name ("fooff", &fp->fooff); + collect_register_by_name ("mxcsr", &fp->mxcsr); + + /* This one's 11 bits... */ + collect_register_by_name ("fop", &val2); + fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800); + + /* Some registers are 16-bit. */ + collect_register_by_name ("fctrl", &val); + fp->fctrl = val; + + collect_register_by_name ("fstat", &val); + fp->fstat = val; + + /* Convert to the simplifed tag form stored in fxsave data. */ + collect_register_by_name ("ftag", &val); + val &= 0xFFFF; + val2 = 0; + for (i = 7; i >= 0; i--) + { + int tag = (val >> (i * 2)) & 3; + + if (tag != 3) + val2 |= (1 << i); + } + fp->ftag = val2; + + collect_register_by_name ("fiseg", &val); + fp->fiseg = val; + + collect_register_by_name ("foseg", &val); + fp->foseg = val; +} + +static int +i387_ftag (struct i387_fxsave *fp, int regno) +{ + unsigned char *raw = &fp->st_space[regno * 16]; + unsigned int exponent; + unsigned long fraction[2]; + int integer; + + integer = raw[7] & 0x80; + exponent = (((raw[9] & 0x7f) << 8) | raw[8]); + fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]); + fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16) + | (raw[5] << 8) | raw[4]); + + if (exponent == 0x7fff) + { + /* Special. */ + return (2); + } + else if (exponent == 0x0000) + { + if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer) + { + /* Zero. */ + return (1); + } + else + { + /* Special. */ + return (2); + } + } + else + { + if (integer) + { + /* Valid. */ + return (0); + } + else + { + /* Special. */ + return (2); + } + } +} + +void +i387_fxsave_to_cache (const void *buf) +{ + struct i387_fxsave *fp = (struct i387_fxsave *) buf; + int i, top; + int st0_regnum = find_regno ("st0"); + int xmm0_regnum = find_regno ("xmm0"); + unsigned long val; + + for (i = 0; i < 8; i++) + supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16); + for (i = 0; i < num_xmm_registers; i++) + supply_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16); + + supply_register_by_name ("fioff", &fp->fioff); + supply_register_by_name ("fooff", &fp->fooff); + supply_register_by_name ("mxcsr", &fp->mxcsr); + + /* Some registers are 16-bit. */ + val = fp->fctrl & 0xFFFF; + supply_register_by_name ("fctrl", &val); + + val = fp->fstat & 0xFFFF; + supply_register_by_name ("fstat", &val); + + /* Generate the form of ftag data that GDB expects. */ + top = (fp->fstat >> 11) & 0x7; + val = 0; + for (i = 7; i >= 0; i--) + { + int tag; + if (fp->ftag & (1 << i)) + tag = i387_ftag (fp, (i + 8 - top) % 8); + else + tag = 3; + val |= tag << (2 * i); + } + supply_register_by_name ("ftag", &val); + + val = fp->fiseg & 0xFFFF; + supply_register_by_name ("fiseg", &val); + + val = fp->foseg & 0xFFFF; + supply_register_by_name ("foseg", &val); + + val = (fp->fop) & 0x7FF; + supply_register_by_name ("fop", &val); +}
i387-fp.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: inferiors.c =================================================================== --- inferiors.c (nonexistent) +++ inferiors.c (revision 816) @@ -0,0 +1,334 @@ +/* Inferior process information for the remote server for GDB. + Copyright (C) 2002, 2005, 2007, 2008 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#include + +#include "server.h" + +struct thread_info +{ + struct inferior_list_entry entry; + void *target_data; + void *regcache_data; + unsigned int gdb_id; +}; + +struct inferior_list all_threads; +struct inferior_list all_dlls; +int dlls_changed; + +struct thread_info *current_inferior; + +#define get_thread(inf) ((struct thread_info *)(inf)) +#define get_dll(inf) ((struct dll_info *)(inf)) + +void +add_inferior_to_list (struct inferior_list *list, + struct inferior_list_entry *new_inferior) +{ + new_inferior->next = NULL; + if (list->tail != NULL) + list->tail->next = new_inferior; + else + list->head = new_inferior; + list->tail = new_inferior; +} + +void +for_each_inferior (struct inferior_list *list, + void (*action) (struct inferior_list_entry *)) +{ + struct inferior_list_entry *cur = list->head, *next; + + while (cur != NULL) + { + next = cur->next; + (*action) (cur); + cur = next; + } +} + +void +remove_inferior (struct inferior_list *list, + struct inferior_list_entry *entry) +{ + struct inferior_list_entry **cur; + + if (list->head == entry) + { + list->head = entry->next; + if (list->tail == entry) + list->tail = list->head; + return; + } + + cur = &list->head; + while (*cur && (*cur)->next != entry) + cur = &(*cur)->next; + + if (*cur == NULL) + return; + + (*cur)->next = entry->next; + + if (list->tail == entry) + list->tail = *cur; +} + +void +add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id) +{ + struct thread_info *new_thread = malloc (sizeof (*new_thread)); + + memset (new_thread, 0, sizeof (*new_thread)); + + new_thread->entry.id = thread_id; + + add_inferior_to_list (&all_threads, & new_thread->entry); + + if (current_inferior == NULL) + current_inferior = new_thread; + + new_thread->target_data = target_data; + set_inferior_regcache_data (new_thread, new_register_cache ()); + new_thread->gdb_id = gdb_id; +} + +unsigned int +thread_id_to_gdb_id (unsigned long thread_id) +{ + struct inferior_list_entry *inf = all_threads.head; + + while (inf != NULL) + { + struct thread_info *thread = get_thread (inf); + if (inf->id == thread_id) + return thread->gdb_id; + inf = inf->next; + } + + return 0; +} + +unsigned int +thread_to_gdb_id (struct thread_info *thread) +{ + return thread->gdb_id; +} + +struct thread_info * +gdb_id_to_thread (unsigned int gdb_id) +{ + struct inferior_list_entry *inf = all_threads.head; + + while (inf != NULL) + { + struct thread_info *thread = get_thread (inf); + if (thread->gdb_id == gdb_id) + return thread; + inf = inf->next; + } + + return NULL; +} + +unsigned long +gdb_id_to_thread_id (unsigned int gdb_id) +{ + struct thread_info *thread = gdb_id_to_thread (gdb_id); + + return thread ? thread->entry.id : 0; +} + +static void +free_one_thread (struct inferior_list_entry *inf) +{ + struct thread_info *thread = get_thread (inf); + free_register_cache (inferior_regcache_data (thread)); + free (thread); +} + +void +remove_thread (struct thread_info *thread) +{ + remove_inferior (&all_threads, (struct inferior_list_entry *) thread); + free_one_thread (&thread->entry); +} + +struct inferior_list_entry * +find_inferior (struct inferior_list *list, + int (*func) (struct inferior_list_entry *, void *), void *arg) +{ + struct inferior_list_entry *inf = list->head; + + while (inf != NULL) + { + if ((*func) (inf, arg)) + return inf; + inf = inf->next; + } + + return NULL; +} + +struct inferior_list_entry * +find_inferior_id (struct inferior_list *list, unsigned long id) +{ + struct inferior_list_entry *inf = list->head; + + while (inf != NULL) + { + if (inf->id == id) + return inf; + inf = inf->next; + } + + return NULL; +} + +void * +inferior_target_data (struct thread_info *inferior) +{ + return inferior->target_data; +} + +void +set_inferior_target_data (struct thread_info *inferior, void *data) +{ + inferior->target_data = data; +} + +void * +inferior_regcache_data (struct thread_info *inferior) +{ + return inferior->regcache_data; +} + +void +set_inferior_regcache_data (struct thread_info *inferior, void *data) +{ + inferior->regcache_data = data; +} + +static void +free_one_dll (struct inferior_list_entry *inf) +{ + struct dll_info *dll = get_dll (inf); + if (dll->name != NULL) + free (dll->name); + free (dll); +} + +/* Find a DLL with the same name and/or base address. A NULL name in + the key is ignored; so is an all-ones base address. */ + +static int +match_dll (struct inferior_list_entry *inf, void *arg) +{ + struct dll_info *iter = (void *) inf; + struct dll_info *key = arg; + + if (key->base_addr != ~(CORE_ADDR) 0 + && iter->base_addr == key->base_addr) + return 1; + else if (key->name != NULL + && iter->name != NULL + && strcmp (key->name, iter->name) == 0) + return 1; + + return 0; +} + +/* Record a newly loaded DLL at BASE_ADDR. */ + +void +loaded_dll (const char *name, CORE_ADDR base_addr) +{ + struct dll_info *new_dll = malloc (sizeof (*new_dll)); + memset (new_dll, 0, sizeof (*new_dll)); + + new_dll->entry.id = -1; + + new_dll->name = strdup (name); + new_dll->base_addr = base_addr; + + add_inferior_to_list (&all_dlls, &new_dll->entry); + dlls_changed = 1; +} + +/* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ + +void +unloaded_dll (const char *name, CORE_ADDR base_addr) +{ + struct dll_info *dll; + struct dll_info key_dll; + + /* Be careful not to put the key DLL in any list. */ + key_dll.name = (char *) name; + key_dll.base_addr = base_addr; + + dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll); + remove_inferior (&all_dlls, &dll->entry); + free_one_dll (&dll->entry); + dlls_changed = 1; +} + +#define clear_list(LIST) \ + do { (LIST)->head = (LIST)->tail = NULL; } while (0) + +void +clear_inferiors (void) +{ + for_each_inferior (&all_threads, free_one_thread); + for_each_inferior (&all_dlls, free_one_dll); + + clear_list (&all_threads); + clear_list (&all_dlls); +} + +/* Two utility functions for a truly degenerate inferior_list: a simple + PID listing. */ + +void +add_pid_to_list (struct inferior_list *list, unsigned long pid) +{ + struct inferior_list_entry *new_entry; + + new_entry = malloc (sizeof (struct inferior_list_entry)); + new_entry->id = pid; + add_inferior_to_list (list, new_entry); +} + +int +pull_pid_from_list (struct inferior_list *list, unsigned long pid) +{ + struct inferior_list_entry *new_entry; + + new_entry = find_inferior_id (list, pid); + if (new_entry == NULL) + return 0; + else + { + remove_inferior (list, new_entry); + free (new_entry); + return 1; + } +}
inferiors.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: mem-break.c =================================================================== --- mem-break.c (nonexistent) +++ mem-break.c (revision 816) @@ -0,0 +1,299 @@ +/* Memory breakpoint operations for the remote server for GDB. + Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#include "server.h" + +const unsigned char *breakpoint_data; +int breakpoint_len; + +#define MAX_BREAKPOINT_LEN 8 + +struct breakpoint +{ + struct breakpoint *next; + CORE_ADDR pc; + unsigned char old_data[MAX_BREAKPOINT_LEN]; + + /* Non-zero iff we are stepping over this breakpoint. */ + int reinserting; + + /* Non-NULL iff this breakpoint was inserted to step over + another one. Points to the other breakpoint (which is also + in the *next chain somewhere). */ + struct breakpoint *breakpoint_to_reinsert; + + /* Function to call when we hit this breakpoint. If it returns 1, + the breakpoint will be deleted; 0, it will be reinserted for + another round. */ + int (*handler) (CORE_ADDR); +}; + +struct breakpoint *breakpoints; + +void +set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR)) +{ + struct breakpoint *bp; + + if (breakpoint_data == NULL) + error ("Target does not support breakpoints."); + + bp = malloc (sizeof (struct breakpoint)); + memset (bp, 0, sizeof (struct breakpoint)); + + (*the_target->read_memory) (where, bp->old_data, + breakpoint_len); + (*the_target->write_memory) (where, breakpoint_data, + breakpoint_len); + + bp->pc = where; + bp->handler = handler; + + bp->next = breakpoints; + breakpoints = bp; +} + +static void +delete_breakpoint (struct breakpoint *bp) +{ + struct breakpoint *cur; + + if (breakpoints == bp) + { + breakpoints = bp->next; + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + free (bp); + return; + } + cur = breakpoints; + while (cur->next) + { + if (cur->next == bp) + { + cur->next = bp->next; + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + free (bp); + return; + } + } + warning ("Could not find breakpoint in list."); +} + +static struct breakpoint * +find_breakpoint_at (CORE_ADDR where) +{ + struct breakpoint *bp = breakpoints; + + while (bp != NULL) + { + if (bp->pc == where) + return bp; + bp = bp->next; + } + + return NULL; +} + +void +delete_breakpoint_at (CORE_ADDR addr) +{ + struct breakpoint *bp = find_breakpoint_at (addr); + if (bp != NULL) + delete_breakpoint (bp); +} + +static int +reinsert_breakpoint_handler (CORE_ADDR stop_pc) +{ + struct breakpoint *stop_bp, *orig_bp; + + stop_bp = find_breakpoint_at (stop_pc); + if (stop_bp == NULL) + error ("lost the stopping breakpoint."); + + orig_bp = stop_bp->breakpoint_to_reinsert; + if (orig_bp == NULL) + error ("no breakpoint to reinsert"); + + (*the_target->write_memory) (orig_bp->pc, breakpoint_data, + breakpoint_len); + orig_bp->reinserting = 0; + return 1; +} + +void +reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at) +{ + struct breakpoint *bp, *orig_bp; + + orig_bp = find_breakpoint_at (stop_pc); + if (orig_bp == NULL) + error ("Could not find original breakpoint in list."); + + set_breakpoint_at (stop_at, reinsert_breakpoint_handler); + + bp = find_breakpoint_at (stop_at); + if (bp == NULL) + error ("Could not find breakpoint in list (reinserting by breakpoint)."); + bp->breakpoint_to_reinsert = orig_bp; + + (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data, + breakpoint_len); + orig_bp->reinserting = 1; +} + +void +uninsert_breakpoint (CORE_ADDR stopped_at) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stopped_at); + if (bp == NULL) + error ("Could not find breakpoint in list (uninserting)."); + + (*the_target->write_memory) (bp->pc, bp->old_data, + breakpoint_len); + bp->reinserting = 1; +} + +void +reinsert_breakpoint (CORE_ADDR stopped_at) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stopped_at); + if (bp == NULL) + error ("Could not find breakpoint in list (uninserting)."); + if (! bp->reinserting) + error ("Breakpoint already inserted at reinsert time."); + + (*the_target->write_memory) (bp->pc, breakpoint_data, + breakpoint_len); + bp->reinserting = 0; +} + +int +check_breakpoints (CORE_ADDR stop_pc) +{ + struct breakpoint *bp; + + bp = find_breakpoint_at (stop_pc); + if (bp == NULL) + return 0; + if (bp->reinserting) + { + warning ("Hit a removed breakpoint?"); + return 0; + } + + if ((*bp->handler) (bp->pc)) + { + delete_breakpoint (bp); + return 2; + } + else + return 1; +} + +void +set_breakpoint_data (const unsigned char *bp_data, int bp_len) +{ + breakpoint_data = bp_data; + breakpoint_len = bp_len; +} + +void +check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len) +{ + struct breakpoint *bp = breakpoints; + CORE_ADDR mem_end = mem_addr + mem_len; + + for (; bp != NULL; bp = bp->next) + { + CORE_ADDR bp_end = bp->pc + breakpoint_len; + CORE_ADDR start, end; + int copy_offset, copy_len, buf_offset; + + if (mem_addr >= bp_end) + continue; + if (bp->pc >= mem_end) + continue; + + start = bp->pc; + if (mem_addr > start) + start = mem_addr; + + end = bp_end; + if (end > mem_end) + end = mem_end; + + copy_len = end - start; + copy_offset = start - bp->pc; + buf_offset = start - mem_addr; + + memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len); + } +} + +void +check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len) +{ + struct breakpoint *bp = breakpoints; + CORE_ADDR mem_end = mem_addr + mem_len; + + for (; bp != NULL; bp = bp->next) + { + CORE_ADDR bp_end = bp->pc + breakpoint_len; + CORE_ADDR start, end; + int copy_offset, copy_len, buf_offset; + + if (mem_addr >= bp_end) + continue; + if (bp->pc >= mem_end) + continue; + + start = bp->pc; + if (mem_addr > start) + start = mem_addr; + + end = bp_end; + if (end > mem_end) + end = mem_end; + + copy_len = end - start; + copy_offset = start - bp->pc; + buf_offset = start - mem_addr; + + memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len); + if (bp->reinserting == 0) + memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len); + } +} + +/* Delete all breakpoints. */ + +void +delete_all_breakpoints (void) +{ + while (breakpoints) + delete_breakpoint (breakpoints); +}
mem-break.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: proc-service.c =================================================================== --- proc-service.c (nonexistent) +++ proc-service.c (revision 816) @@ -0,0 +1,163 @@ +/* libthread_db helper functions for the remote server for GDB. + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#include "server.h" + +/* This file is currently tied to GNU/Linux. It should scale well to + another libthread_db implementation, with the approriate gdbserver + hooks, but for now this means we can use GNU/Linux's target data. */ + +#include "linux-low.h" + +#include "gdb_proc_service.h" + +typedef struct ps_prochandle *gdb_ps_prochandle_t; +typedef void *gdb_ps_read_buf_t; +typedef const void *gdb_ps_write_buf_t; +typedef size_t gdb_ps_size_t; + +#ifdef HAVE_LINUX_REGSETS +#define HAVE_REGSETS +#endif + +#ifdef HAVE_REGSETS +static struct regset_info * +gregset_info(void) +{ + int i = 0; + + while (target_regsets[i].size != -1) + { + if (target_regsets[i].type == GENERAL_REGS) + break; + i++; + } + + return &target_regsets[i]; +} +#endif + +/* Search for the symbol named NAME within the object named OBJ within + the target process PH. If the symbol is found the address of the + symbol is stored in SYM_ADDR. */ + +ps_err_e +ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj, + const char *name, psaddr_t *sym_addr) +{ + CORE_ADDR addr; + + if (look_up_one_symbol (name, &addr) == 0) + return PS_NOSYM; + + *sym_addr = (psaddr_t) (unsigned long) addr; + return PS_OK; +} + +/* Read SIZE bytes from the target process PH at address ADDR and copy + them into BUF. */ + +ps_err_e +ps_pdread (gdb_ps_prochandle_t ph, psaddr_t addr, + gdb_ps_read_buf_t buf, gdb_ps_size_t size) +{ + read_inferior_memory ((unsigned long) addr, buf, size); + return PS_OK; +} + +/* Write SIZE bytes from BUF into the target process PH at address ADDR. */ + +ps_err_e +ps_pdwrite (gdb_ps_prochandle_t ph, psaddr_t addr, + gdb_ps_write_buf_t buf, gdb_ps_size_t size) +{ + return write_inferior_memory ((unsigned long) addr, buf, size); +} + +/* Get the general registers of LWP LWPID within the target process PH + and store them in GREGSET. */ + +ps_err_e +ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) +{ +#ifdef HAVE_REGSETS + struct process_info *process; + struct thread_info *reg_inferior, *save_inferior; + + process = (struct process_info *) find_inferior_id (&all_processes, + lwpid); + if (process == NULL) + return PS_ERR; + + reg_inferior = get_process_thread (process); + save_inferior = current_inferior; + current_inferior = reg_inferior; + + the_target->fetch_registers (0); + gregset_info()->fill_function (gregset); + + current_inferior = save_inferior; + return PS_OK; +#else + return PS_ERR; +#endif +} + +/* Set the general registers of LWP LWPID within the target process PH + from GREGSET. */ + +ps_err_e +ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) +{ + /* Unneeded. */ + return PS_ERR; +} + +/* Get the floating-point registers of LWP LWPID within the target + process PH and store them in FPREGSET. */ + +ps_err_e +ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset) +{ + /* Unneeded. */ + return PS_ERR; +} + +/* Set the floating-point registers of LWP LWPID within the target + process PH from FPREGSET. */ + +ps_err_e +ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, void *fpregset) +{ + /* Unneeded. */ + return PS_ERR; +} + +/* Return overall process id of the target PH. Special for GNU/Linux + -- not used on Solaris. */ + +pid_t +ps_getpid (gdb_ps_prochandle_t ph) +{ + return ph->pid; +} + +
proc-service.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gdbserver.1 =================================================================== --- gdbserver.1 (nonexistent) +++ gdbserver.1 (revision 816) @@ -0,0 +1,116 @@ +.\" Copyright (C) 1993 Free Software Foundation, Inc. +.\" See section COPYING for conditions for redistribution +.TH gdbserver 1 "2 November 1993" "Cygnus Support" "GNU Development Tools" +.SH NAME +gdbserver \- Remote Server for the GNU Debugger +.SH SYNOPSIS +.na +.TP +.B gdbserver +.RB tty +.RB prog +.RB "[\|" args... "\|]" +.PP +.B gdbserver +.RB tty +.B --attach +.RB PID +.ad b +.SH DESCRIPTION +GDBSERVER is a program that allows you to run GDB on a different machine +than the one which is running the program being debugged. + +Usage (server (target) side): + +First, you need to have a copy of the program you want to debug put onto +the target system. The program can be stripped to save space if needed, as +GDBserver doesn't care about symbols. All symbol handling is taken care of by +the GDB running on the host system. + +To use the server, you log on to the target system, and run the `gdbserver' +program. You must tell it (a) how to communicate with GDB, (b) the name of +your program, and (c) its arguments. The general syntax is: + + target> gdbserver COMM PROGRAM [ARGS ...] + +For example, using a serial port, you might say: + + target> gdbserver /dev/com1 emacs foo.txt + +This tells gdbserver to debug emacs with an argument of foo.txt, and to +communicate with GDB via /dev/com1. Gdbserver now waits patiently for the +host GDB to communicate with it. + +To use a TCP connection, you could say: + + target> gdbserver host:2345 emacs foo.txt + +This says pretty much the same thing as the last example, except that we are +going to communicate with the host GDB via TCP. The `host:2345' argument means +that we are expecting to see a TCP connection from `host' to local TCP port +2345. (Currently, the `host' part is ignored.) You can choose any number you +want for the port number as long as it does not conflict with any existing TCP +ports on the target system. This same port number must be used in the host +GDBs `target remote' command, which will be described shortly. Note that if +you chose a port number that conflicts with another service, gdbserver will +print an error message and exit. + +On some targets, gdbserver can also attach to running programs. +This is accomplished via the --attach argument. The syntax is: + + target> gdbserver COMM --attach PID + +PID is the process ID of a currently running process. It isn't +necessary to point gdbserver at a binary for the running process. + +Usage (host side): + +You need an unstripped copy of the target program on your host system, since +GDB needs to examine it's symbol tables and such. Start up GDB as you normally +would, with the target program as the first argument. (You may need to use the +--baud option if the serial line is running at anything except 9600 baud.) +Ie: `gdb TARGET-PROG', or `gdb --baud BAUD TARGET-PROG'. After that, the only +new command you need to know about is `target remote'. It's argument is either +a device name (usually a serial device, like `/dev/ttyb'), or a HOST:PORT +descriptor. For example: + + (gdb) target remote /dev/ttyb + +communicates with the server via serial line /dev/ttyb, and: + + (gdb) target remote the-target:2345 + +communicates via a TCP connection to port 2345 on host `the-target', where +you previously started up gdbserver with the same port number. Note that for +TCP connections, you must start up gdbserver prior to using the `target remote' +command, otherwise you may get an error that looks something like +`Connection refused'. +.SH OPTIONS +You have to supply the name of the program to debug +and the tty to communicate on; the remote GDB will do everything else. +Any remaining arguments will be passed to the program verbatim. +.SH "SEE ALSO" +.RB "`\|" gdb "\|'" +entry in +.B info\c +\&; +.I +Using GDB: A Guide to the GNU Source-Level Debugger\c +, Richard M. Stallman and Roland H. Pesch, July 1991. +.SH COPYING +Copyright (c) 1993 Free Software Foundation, Inc. +.PP +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. +.PP +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. +.PP +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. Index: i387-fp.h =================================================================== --- i387-fp.h (nonexistent) +++ i387-fp.h (revision 816) @@ -0,0 +1,30 @@ +/* i387-specific utility functions, for the remote server for GDB. + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifndef I387_FP_H +#define I387_FP_H + +void i387_cache_to_fsave (void *buf); +void i387_fsave_to_cache (const void *buf); + +void i387_cache_to_fxsave (void *buf); +void i387_fxsave_to_cache (const void *buf); + +extern int num_xmm_registers; + +#endif /* I387_FP_H */
i387-fp.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: mem-break.h =================================================================== --- mem-break.h (nonexistent) +++ mem-break.h (revision 816) @@ -0,0 +1,78 @@ +/* Memory breakpoint interfaces for the remote server for GDB. + Copyright (C) 2002, 2005, 2007, 2008 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#ifndef MEM_BREAK_H +#define MEM_BREAK_H + +/* Breakpoints are opaque. */ + +/* Create a new breakpoint at WHERE, and call HANDLER when + it is hit. HANDLER should return 1 if the breakpoint + should be deleted, 0 otherwise. */ + +void set_breakpoint_at (CORE_ADDR where, + int (*handler) (CORE_ADDR)); + +/* Delete a breakpoint previously inserted at ADDR with + set_breakpoint_at. */ + +void delete_breakpoint_at (CORE_ADDR addr); + +/* Create a reinsertion breakpoint at STOP_AT for the breakpoint + currently at STOP_PC (and temporarily remove the breakpoint at + STOP_PC). */ + +void reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at); + +/* Change the status of the breakpoint at WHERE to inserted. */ + +void reinsert_breakpoint (CORE_ADDR where); + +/* Change the status of the breakpoint at WHERE to uninserted. */ + +void uninsert_breakpoint (CORE_ADDR where); + +/* See if any breakpoint claims ownership of STOP_PC. Call the handler for + the breakpoint, if found. */ + +int check_breakpoints (CORE_ADDR stop_pc); + +/* See if any breakpoints shadow the target memory area from MEM_ADDR + to MEM_ADDR + MEM_LEN. Update the data already read from the target + (in BUF) if necessary. */ + +void check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len); + +/* See if any breakpoints shadow the target memory area from MEM_ADDR + to MEM_ADDR + MEM_LEN. Update the data to be written to the target + (in BUF) if necessary, as well as the original data for any breakpoints. */ + +void check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len); + +/* Set the byte pattern to insert for memory breakpoints. This function + must be called before any breakpoints are set. */ + +void set_breakpoint_data (const unsigned char *bp_data, int bp_len); + +/* Delete all breakpoints. */ + +void delete_all_breakpoints (void); + +#endif /* MEM_BREAK_H */
mem-break.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: hostio.c =================================================================== --- hostio.c (nonexistent) +++ hostio.c (revision 816) @@ -0,0 +1,476 @@ +/* Host file transfer support for gdbserver. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + Contributed by CodeSourcery. + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "server.h" +#include "gdb/fileio.h" + +#include +#include +#include + +extern int remote_debug; + +struct fd_list +{ + int fd; + struct fd_list *next; +}; + +static struct fd_list *open_fds; + +static int +safe_fromhex (char a, int *nibble) +{ + if (a >= '0' && a <= '9') + *nibble = a - '0'; + else if (a >= 'a' && a <= 'f') + *nibble = a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + *nibble = a - 'A' + 10; + else + return -1; + + return 0; +} + +static int +require_filename (char **pp, char *filename) +{ + int count; + char *p; + + p = *pp; + count = 0; + + while (*p && *p != ',') + { + int nib1, nib2; + + /* Don't allow overflow. */ + if (count >= PATH_MAX - 1) + return -1; + + if (safe_fromhex (p[0], &nib1) + || safe_fromhex (p[1], &nib2)) + return -1; + + filename[count++] = nib1 * 16 + nib2; + p += 2; + } + + filename[count] = '\0'; + *pp = p; + return 0; +} + +static int +require_int (char **pp, int *value) +{ + char *p; + int count; + + p = *pp; + *value = 0; + count = 0; + + while (*p && *p != ',') + { + int nib; + + /* Don't allow overflow. */ + if (count >= 7) + return -1; + + if (safe_fromhex (p[0], &nib)) + return -1; + *value = *value * 16 + nib; + p++; + count++; + } + + *pp = p; + return 0; +} + +static int +require_data (char *p, int p_len, char **data, int *data_len) +{ + int input_index, output_index, escaped; + + *data = malloc (p_len); + + output_index = 0; + escaped = 0; + for (input_index = 0; input_index < p_len; input_index++) + { + char b = p[input_index]; + + if (escaped) + { + (*data)[output_index++] = b ^ 0x20; + escaped = 0; + } + else if (b == '}') + escaped = 1; + else + (*data)[output_index++] = b; + } + + if (escaped) + return -1; + + *data_len = output_index; + return 0; +} + +static int +require_comma (char **pp) +{ + if (**pp == ',') + { + (*pp)++; + return 0; + } + else + return -1; +} + +static int +require_end (char *p) +{ + if (*p == '\0') + return 0; + else + return -1; +} + +static int +require_valid_fd (int fd) +{ + struct fd_list *fd_ptr; + + for (fd_ptr = open_fds; fd_ptr != NULL; fd_ptr = fd_ptr->next) + if (fd_ptr->fd == fd) + return 0; + + return -1; +} + +/* Fill in own_buf with the last hostio error packet, however it + suitable for the target. */ +static void +hostio_error (char *own_buf) +{ + the_target->hostio_last_error (own_buf); +} + +static void +hostio_packet_error (char *own_buf) +{ + sprintf (own_buf, "F-1,%x", FILEIO_EINVAL); +} + +static void +hostio_reply (char *own_buf, int result) +{ + sprintf (own_buf, "F%x", result); +} + +static int +hostio_reply_with_data (char *own_buf, char *buffer, int len, + int *new_packet_len) +{ + int input_index, output_index, out_maxlen; + + sprintf (own_buf, "F%x;", len); + output_index = strlen (own_buf); + + out_maxlen = PBUFSIZ; + + for (input_index = 0; input_index < len; input_index++) + { + char b = buffer[input_index]; + + if (b == '$' || b == '#' || b == '}' || b == '*') + { + /* These must be escaped. */ + if (output_index + 2 > out_maxlen) + break; + own_buf[output_index++] = '}'; + own_buf[output_index++] = b ^ 0x20; + } + else + { + if (output_index + 1 > out_maxlen) + break; + own_buf[output_index++] = b; + } + } + + *new_packet_len = output_index; + return input_index; +} + +static int +fileio_open_flags_to_host (int fileio_open_flags, int *open_flags_p) +{ + int open_flags = 0; + + if (fileio_open_flags & ~FILEIO_O_SUPPORTED) + return -1; + + if (fileio_open_flags & FILEIO_O_CREAT) + open_flags |= O_CREAT; + if (fileio_open_flags & FILEIO_O_EXCL) + open_flags |= O_EXCL; + if (fileio_open_flags & FILEIO_O_TRUNC) + open_flags |= O_TRUNC; + if (fileio_open_flags & FILEIO_O_APPEND) + open_flags |= O_APPEND; + if (fileio_open_flags & FILEIO_O_RDONLY) + open_flags |= O_RDONLY; + if (fileio_open_flags & FILEIO_O_WRONLY) + open_flags |= O_WRONLY; + if (fileio_open_flags & FILEIO_O_RDWR) + open_flags |= O_RDWR; +/* On systems supporting binary and text mode, always open files in + binary mode. */ +#ifdef O_BINARY + open_flags |= O_BINARY; +#endif + + *open_flags_p = open_flags; + return 0; +} + +static void +handle_open (char *own_buf) +{ + char filename[PATH_MAX]; + char *p; + int fileio_flags, mode, flags, fd; + struct fd_list *new_fd; + + p = own_buf + strlen ("vFile:open:"); + + if (require_filename (&p, filename) + || require_comma (&p) + || require_int (&p, &fileio_flags) + || require_comma (&p) + || require_int (&p, &mode) + || require_end (p) + || fileio_open_flags_to_host (fileio_flags, &flags)) + { + hostio_packet_error (own_buf); + return; + } + + /* We do not need to convert MODE, since the fileio protocol + uses the standard values. */ + fd = open (filename, flags, mode); + + if (fd == -1) + { + hostio_error (own_buf); + return; + } + + /* Record the new file descriptor. */ + new_fd = malloc (sizeof (struct fd_list)); + new_fd->fd = fd; + new_fd->next = open_fds; + open_fds = new_fd; + + hostio_reply (own_buf, fd); +} + +static void +handle_pread (char *own_buf, int *new_packet_len) +{ + int fd, ret, len, offset, bytes_sent; + char *p, *data; + + p = own_buf + strlen ("vFile:pread:"); + + if (require_int (&p, &fd) + || require_comma (&p) + || require_valid_fd (fd) + || require_int (&p, &len) + || require_comma (&p) + || require_int (&p, &offset) + || require_end (p)) + { + hostio_packet_error (own_buf); + return; + } + + data = malloc (len); +#ifdef HAVE_PREAD + ret = pread (fd, data, len, offset); +#else + ret = lseek (fd, offset, SEEK_SET); + if (ret != -1) + ret = read (fd, data, len); +#endif + + if (ret == -1) + { + hostio_error (own_buf); + free (data); + return; + } + + bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len); + + /* If we were using read, and the data did not all fit in the reply, + we would have to back up using lseek here. With pread it does + not matter. But we still have a problem; the return value in the + packet might be wrong, so we must fix it. This time it will + definitely fit. */ + if (bytes_sent < ret) + bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent, + new_packet_len); + + free (data); +} + +static void +handle_pwrite (char *own_buf, int packet_len) +{ + int fd, ret, len, offset; + char *p, *data; + + p = own_buf + strlen ("vFile:pwrite:"); + + if (require_int (&p, &fd) + || require_comma (&p) + || require_valid_fd (fd) + || require_int (&p, &offset) + || require_comma (&p) + || require_data (p, packet_len - (p - own_buf), &data, &len)) + { + hostio_packet_error (own_buf); + return; + } + +#ifdef HAVE_PWRITE + ret = pwrite (fd, data, len, offset); +#else + ret = lseek (fd, offset, SEEK_SET); + if (ret != -1) + ret = write (fd, data, len); +#endif + + if (ret == -1) + { + hostio_error (own_buf); + free (data); + return; + } + + hostio_reply (own_buf, ret); + free (data); +} + +static void +handle_close (char *own_buf) +{ + int fd, ret; + char *p; + struct fd_list **open_fd_p, *old_fd; + + p = own_buf + strlen ("vFile:close:"); + + if (require_int (&p, &fd) + || require_valid_fd (fd) + || require_end (p)) + { + hostio_packet_error (own_buf); + return; + } + + ret = close (fd); + + if (ret == -1) + { + hostio_error (own_buf); + return; + } + + open_fd_p = &open_fds; + while (*open_fd_p && (*open_fd_p)->fd != fd) + open_fd_p = &(*open_fd_p)->next; + + old_fd = *open_fd_p; + *open_fd_p = (*open_fd_p)->next; + free (old_fd); + + hostio_reply (own_buf, ret); +} + +static void +handle_unlink (char *own_buf) +{ + char filename[PATH_MAX]; + char *p; + int ret; + + p = own_buf + strlen ("vFile:unlink:"); + + if (require_filename (&p, filename) + || require_end (p)) + { + hostio_packet_error (own_buf); + return; + } + + ret = unlink (filename); + + if (ret == -1) + { + hostio_error (own_buf); + return; + } + + hostio_reply (own_buf, ret); +} + +/* Handle all the 'F' file transfer packets. */ + +int +handle_vFile (char *own_buf, int packet_len, int *new_packet_len) +{ + if (strncmp (own_buf, "vFile:open:", 11) == 0) + handle_open (own_buf); + else if (strncmp (own_buf, "vFile:pread:", 11) == 0) + handle_pread (own_buf, new_packet_len); + else if (strncmp (own_buf, "vFile:pwrite:", 12) == 0) + handle_pwrite (own_buf, packet_len); + else if (strncmp (own_buf, "vFile:close:", 12) == 0) + handle_close (own_buf); + else if (strncmp (own_buf, "vFile:unlink:", 13) == 0) + handle_unlink (own_buf); + else + return 0; + + return 1; +}
hostio.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-sh-low.c =================================================================== --- linux-sh-low.c (nonexistent) +++ linux-sh-low.c (revision 816) @@ -0,0 +1,120 @@ +/* GNU/Linux/SH specific low level interface, for the remote server for GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, + 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#include + +#define sh_num_regs 41 + +/* Currently, don't check/send MQ. */ +static int sh_regmap[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + + REG_PC*4, REG_PR*4, REG_GBR*4, -1, + REG_MACH*4, REG_MACL*4, REG_SR*4, + REG_FPUL*4, REG_FPSCR*4, + + REG_FPREG0*4+0, REG_FPREG0*4+4, REG_FPREG0*4+8, REG_FPREG0*4+12, + REG_FPREG0*4+16, REG_FPREG0*4+20, REG_FPREG0*4+24, REG_FPREG0*4+28, + REG_FPREG0*4+32, REG_FPREG0*4+36, REG_FPREG0*4+40, REG_FPREG0*4+44, + REG_FPREG0*4+48, REG_FPREG0*4+52, REG_FPREG0*4+56, REG_FPREG0*4+60, +}; + +static int +sh_cannot_store_register (int regno) +{ + return 0; +} + +static int +sh_cannot_fetch_register (int regno) +{ + return 0; +} + +static CORE_ADDR +sh_get_pc () +{ + unsigned long pc; + collect_register_by_name ("pc", &pc); + return pc; +} + +static void +sh_set_pc (CORE_ADDR pc) +{ + unsigned long newpc = pc; + supply_register_by_name ("pc", &newpc); +} + +/* Correct in either endianness, obviously. */ +static const unsigned short sh_breakpoint = 0xc3c3; +#define sh_breakpoint_len 2 + +static int +sh_breakpoint_at (CORE_ADDR where) +{ + unsigned short insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, 2); + if (insn == sh_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. */ + +static void sh_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < 23; i++) + if (sh_regmap[i] != -1) + collect_register (i, (char *) buf + sh_regmap[i]); +} + +struct regset_info target_regsets[] = { + { 0, 0, 0, GENERAL_REGS, sh_fill_gregset, NULL }, + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + sh_num_regs, + sh_regmap, + sh_cannot_fetch_register, + sh_cannot_store_register, + sh_get_pc, + sh_set_pc, + (const unsigned char *) &sh_breakpoint, + sh_breakpoint_len, + NULL, + 0, + sh_breakpoint_at, +};
linux-sh-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: ChangeLog =================================================================== --- ChangeLog (nonexistent) +++ ChangeLog (revision 816) @@ -0,0 +1,2068 @@ +2008-02-19 Pedro Alves + + * server.c (handle_v_requests): When handling the vRun and vAttach + packets, if already debugging a process, don't kill it. Return an + error instead. + +2008-02-17 Daniel Jacobowitz + + * server.c (handle_query): Correct length check. + +2008-02-14 Pedro Alves + + * win32-low.c (do_initial_child_stuff): Add process handle + parameter. Set current_process_handle and current_process_id from the + parameters. Clear globals. + (win32_create_inferior): Don't set current_process_handle and + current_process_id here. Instead pass them on the call to + do_initial_child_stuff. + (win32_attach): Likewise. + (win32_clear_inferiors): New. + (win32_kill): Don't close the current process handle or the + current thread handle here. Instead call win32_clear_inferiors. + (win32_detach): Don't open a new handle to the process. Call + win32_clear_inferiors. + (win32_join): Don't rely on current_process_handle; open a new + handle using the process id. + (win32_wait): Call win32_clear_inferiors when the inferior process + has exited. + +2008-02-14 Daniel Jacobowitz + + * server.c (monitor_show_help): Add "exit". + +2008-02-11 Maxim Grigoriev + + * Makefile.in (SFILES): Add linux-xtensa-low.c. + (clean): Add reg-xtensa.c. + (linux-xtensa-low.o, reg-xtensa.o, reg-xtensa.c): New dependencies. + * configure.srv (xtensa*-*-linux*) New target. + * linux-xtensa-low.c: New. + * xtensa-xtregs.c: New. + +2008-02-01 Pedro Alves + + * hostio.c: Don't include errno.h. + (errno_to_fileio_errno): Move to hostio-errno. + * hostio.c: (hostio_error): Remove the error parameter. Defer the + error number outputting to the target->hostio_last_error callback. + (hostio_packet_error): Use FILEIO_EINVAL directly. + (handle_open, handle_pread, hostio_error, handle_unlink): Update + calls to hostio_error. + * hostio-errno.c: New. + * server.h (hostio_last_error_from_errno): Declare. + * target.h (target_ops): Add hostio_last_error member. + * linux-low.c (linux_target_op): Register hostio_last_error_from_errno + as hostio_last_error handler. + * spu-low.c (spu_target_ops): Likewise. + * win32-low.c [_WIN32_WCE] (win32_error_to_fileio_error) + (wince_hostio_last_error): New functions. + (win32_target_ops) [_WIN32_WCE]: Register wince_hostio_last_error + as hostio_last_error handler. + (win32_target_ops) [!_WIN32_WCE]: Register + hostio_last_error_from_errno as hostio_last_error handler. + * Makefile.in (SFILES): Add hostio.c and hostio-errno.c. + (hostio-errno.o): New rule. + * configure.ac (GDBSERVER_DEPFILES): Add $srv_hostio_err_objs. + * configure.srv (srv_hostio_err_objs): New variable. Default to + hostio-errno.o. + (arm*-*-mingw32ce*): Set srv_hostio_err_objs to "". + * configure: Regenerate. + +2008-01-29 Daniel Jacobowitz + + * linux-low.c (linux_attach_lwp): Do not _exit after errors. + (linux_kill, linux_detach): Clean up the process list. + * remote-utils.c (remote_open): Improve port number parsing. + (putpkt_binary, input_interrupt): Only send interrupts if the target + is running. + * server.c (extended_protocol): Make static. + (attached): Define earlier. + (exit_requested, response_needed, program_argv): New variables. + (target_running): New. + (start_inferior): Clear attached here. + (attach_inferior): Set attached here. + (require_running): Define. + (handle_query): Use require_running and target_running. Implement + "monitor exit". + (handle_v_attach, handle_v_run): New. + (handle_v_requests): Use require_running. Handle vAttach and vRun. + (gdbserver_usage): Update. + (main): Redo argument parsing. Handle --debug and --multi. Handle + --attach along with other options or after the port. Save + program_argv. Support no initial program. Resynchronize + communication with GDB after an error. Handle "monitor exit". + Use require_running and target_running. Always allow the extended + protocol. Do not error out for Hc0 or Hc-1. Do not automatically + restart in extended mode. + * README: Refer to the GDB manual. Update --attach usage. + +2007-12-20 Andreas Schwab + + * linux-low.c (STACK_SIZE): Define. + (linux_tracefork_child): Use it. Use __clone2 on ia64. + (linux_test_for_tracefork): Likewise. + +2007-12-18 Daniel Jacobowitz + + * linux-low.c (linux_wait_for_event): Update messages. Do not + reinsert auto-delete breakpoints. + * mem-break.c (struct breakpoint): Change return type of handler to + int. + (set_breakpoint_at): Update handler type. + (reinsert_breakpoint_handler): Return 1 instead of calling + delete_breakpoint. + (reinsert_breakpoint_by_bp): Check for the original breakpoint before + setting a new one. + (check_breakpoints): Delete auto-delete breakpoints and return 2. + * mem-break.h (set_breakpoint_at): Update handler type. + * thread-db.c (thread_db_create_event, thread_db_create_event): Update. + * win32-low.c (auto_delete_breakpoint): New. + (get_child_debug_event): Use it. + +2007-12-16 Daniel Jacobowitz + + * configure.ac: Check for pread and pwrite. + * hostio.c (handle_pread): Fall back to lseek and read. + (handle_pwrite): Fall back to lseek and write. + * config.in, configure: Regenerated. + +2007-12-07 Daniel Jacobowitz + + * server.c (myresume): Add own_buf argument. + (main): Update calls. + +2007-12-06 Daniel Jacobowitz + + * linux-low.c (linux_wait, linux_resume): Do not handle async I/O. + * remote-utils.c (remote_open): Do not call disable_async_io. + (block_async_io): Delete. + (unblock_async_io): Make static. + (initialize_async_io): New. + * server.c (handle_v_cont): Handle async I/O here. + (myresume): Likewise. Move other common resume tasks here... + (main): ... from here. Call initialize_async_io. Disable async + I/O before the main loop. + * server.h (initialize_async_io): Declare. + (block_async_io, unblock_async_io): Delete prototypes. + * spu-low.c (spu_resume, spu_wait): Do not handle async I/O here. + +2007-12-06 Mick Davis + + * remote-utils.c (readchar): Allow binary data in received messages. + +2007-12-03 Pedro Alves + + * win32-low.c (attaching): New global. + (win32_create_inferior): Clear the `attaching' global. + (win32_attach): Set the `attaching' global. + (get_child_debug_event) [_WIN32_WCE]: Stop the inferior when + attaching. Only set a breakpoint at the entry point if not + attaching. + +2007-12-03 Pedro Alves + + * server.c (main): Don't report dll events on the initial + connection on attaches. + +2007-12-03 Pedro Alves + + * server.c (main): Relax numerical bases supported for the pid of + the --attach command line argument. + +2007-12-03 Pedro Alves + + * win32-low.c (win32_attach): Call OpenProcess before + DebugActiveProcess, not after. Add last error output to error + call. + +2007-12-03 Pedro Alves + + * win32-low.c (win32_get_thread_context) + (win32_set_thread_context): New functions. + (thread_rec): Use win32_get_thread_context. + (continue_one_thread, win32_resume): Use win32_set_thread_context. + * win32-low.h (win32_thread_info) [_WIN32_WCE]: Add `base_context' + field. + +2007-12-03 Leo Zayas + Pedro Alves + + * win32-low.c (soft_interrupt_requested, faked_breakpoint): New + global variables. + (child_add_thread): Minor cleanup. + (child_continue): Resume artificially suspended threads before + calling ContinueDebugEvent. + (suspend_one_thread): New. + (fake_breakpoint_event): New. + (get_child_debug_event): Change return type to int. Check here if + gdb sent an interrupt request. If a soft interrupt was requested, + fake a breakpoint event. Return 0 if there is no event to handle, + and 1 otherwise. + (win32_wait): Don't check here if gdb sent an interrupt request. + Ensure there is a valid event to handle. + (win32_request_interrupt): Add soft interruption method as last + resort. + +2007-12-03 Leo Zayas + Pedro Alves + + * win32-low.h (win32_thread_info): Add descriptions to the + structure members. Replace `suspend_count' counter by a + `suspended' flag. + * win32-low.c (thread_rec): Update condition of when to get the + context from the inferior. Rely on ContextFlags being set if it + has already been retrieved. Only suspend the inferior thread if + we haven't already. Warn if that fails. + (continue_one_thread): s/suspend_count/suspended/. Only call + ResumeThread once. Warn if that fails. + +2007-12-02 Pedro Alves + + * win32-low.c (win32_wait): Don't read from the inferior when it + has already exited. + +2007-12-02 Pedro Alves + + * Makefile.in (win32_low_h): New variable. + (win32-low.o): Add dependency on $(win32_low_h). + (win32-arm-low.o, win32-i386-low.o): New rules. + +2007-11-30 Daniel Jacobowitz + + * hostio.c: Correct copyright year. + +2007-11-30 Daniel Jacobowitz + + * Makefile.in (OBS): Add hostio.o. + (hostio.o): New rule. + * server.h (handle_vFile): Declare. + * hostio.c: New file. + * server.c (handle_v_requests): Take packet_len and new_packet_len + for binary packets. Call handle_vFile. + (main): Update call to handle_v_requests. + +2007-11-05 Daniel Jacobowitz + + * linux-low.c: Include . + +2007-11-01 Daniel Jacobowitz + + * linux-low.c (linux_tracefork_grandchild): New. + (linux_tracefork_child): Use clone. + (linux_test_for_tracefork): Use clone; allocate and free a stack. + +2007-10-31 Joel Brobecker + + * Makefile.in: Use $(SHELL) instead of "sh" to call regdat.sh. + +2007-10-24 Daniel Jacobowitz + + * linux-low.c (handle_extended_wait): Handle unexpected signals. + +2007-10-23 Daniel Jacobowitz + + * inferiors.c (change_inferior_id): Delete. + (add_pid_to_list, pull_pid_from_list): New. + * linux-low.c (PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG) + (PTRACE_O_TRACESYSGOOD, PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK) + (PTRACE_O_TRACECLONE, PTRACE_O_TRACEEXEC, PTRACE_O_TRACEVFORKDONE) + (PTRACE_O_TRACEEXIT, PTRACE_EVENT_FORK, PTRACE_EVENT_VFORK) + (PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC, PTRACE_EVENT_VFORK_DONE) + (PTRACE_EVENT_EXIT, __WALL): Provide default definitions. + (stopped_pids, thread_db_active, must_set_ptrace_flags): New variables. + (using_threads): Always set to 1. + (handle_extended_wait): New. + (add_process): Do not set TID. + (linux_create_inferior): Set must_set_ptrace_flags. + (linux_attach_lwp): Remove TID argument. Do not check using_threads. + Use PTRACE_SETOPTIONS. Call new_thread_notify. Update all callers. + (linux_thread_alive): Rename TID argument to LWPID. + (linux_wait_for_process): Handle unknown processes. Do not use TID. + (linux_wait_for_event): Do not use TID or check using_threads. Update + call to dead_thread_notify. Call handle_extended_wait. + (linux_create_inferior): Use PTRACE_SETOPTIONS. + (send_sigstop): Delete sigstop_sent. + (wait_for_sigstop): Avoid TID. + (linux_supports_tracefork_flag, linux_tracefork_child, my_waitpid) + (linux_test_for_tracefork): New. + (linux_lookup_signals): Use thread_db_active and + linux_supports_tracefork_flag. + (initialize_low): Use thread_db_active and linux_test_for_tracefork. + * linux-low.h (get_process_thread): Avoid TID. + (struct process_ifo): Move thread_known and tid to the end. Remove + sigstop_sent. + (linux_attach_lwp, thread_db_init): Update prototypes. + * server.h (change_inferior_id): Delete prototype. + (add_pid_to_list, pull_pid_from_list): New prototypes. + * thread-db.c (thread_db_use_events): New. + (find_first_thread): Rename to... + (find_one_thread): ...this. Update callers and messages. Do not + call fatal. Check thread_db_use_events. Do not call + change_inferior_id or new_thread_notify. + (maybe_attach_thread): Update. Do not call new_thread_notify. + (thread_db_init): Set thread_db_use_events. Check use_events. + * utils.c (fatal, warning): Correct message prefix. + +2007-10-15 Daniel Jacobowitz + + * Makefile.in (clean): Remove new files. + (powerpc-32.o, powerpc-32.c, powerpc-e500.o, powerpc-e500.c) + (powerpc-64.o, powerpc-64.c): New rules. + * configure.srv: Use alternate register sets for powerpc64-*-linux* + with AltiVec, powerpc-*-linux* with AltiVec, and powerpc-*-linux* + with SPE. + * linux-ppc-low.c (ppc_regmap): Do not fetch the FP registers for + SPE targets. + (ppc_cannot_store_register): Do not check for FPSCR for SPE targets. + (PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, ppc_fill_vrregset) + (ppc_store_vrregset, PTRACE_GETEVRREGS, PTRACE_SETEVRREGS) + (struct gdb_evrregset_t, ppc_fill_evrregset, ppc_store_evrregset): New. + (target_regsets): Add AltiVec and SPE register sets. + * configure.ac: Check for AltiVec and SPE. + * linux-ppc64-low.c (PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS) + (ppc_fill_vrregset, ppc_store_vrregset): New. + (target_regsets): Add AltiVec register set. + * configure: Regenerated. + +2007-09-19 Daniel Jacobowitz + + * linux-low.c (O_LARGEFILE): Define. + (linux_read_memory): Use /proc/PID/mem. + * configure.ac: Use AC_GNU_SOURCE. Check for pread64. + * configure, config.in: Regenerated. + +2007-09-04 Daniel Jacobowitz + + * linux-low.c (linux_wait_for_event): Do not pass signals while + single-stepping. + +2007-09-03 Pedro Alves + + * win32-low.c (create_process): New. + (win32_create_inferior): Use create_process instead of + CreateProcess. If create_process failed retry appending an ".exe" + suffix. Store the GetLastError result immediatelly after + create_process calls and use it on the call to error. + +2007-09-03 Pedro Alves + + * win32-low.c (handle_load_dll): Don't use toolhelp when waiting. + +2007-08-23 Joel Brobecker + + * configure.ac: Switch license to GPLv3. + +2007-08-01 Michael Snyder + + * remote-utils.c (putpkt_binary): Memory leak, free buf2. + +2007-07-31 Pedro Alves + + * win32-low.c (winapi_CloseToolhelp32Snapshot) [_WIN32_WCE]: New + typedef. + (win32_CloseToolhelp32Snapshot) [_WIN32_WCE]: New global var. + (load_toolhelp) [_WIN32_WCE]: Load TOOLHELP.DLL. Get + CloseToolhelp32Snapshot. + (toolhelp_get_dll_name) [_WIN32_WCE]: Close the snapshot with + CloseToolhelp32Snapshot. + +2007-07-27 Michael Snyder + + * server.c (main): Check for inferior exit before main loop. + +2007-07-18 Pedro Alves + + * remote-utils.c (remote_open): Set SO_KEEPALIVE on remote_desc + instead of on tmp_desc. + +2007-07-17 Pedro Alves + Daniel Jacobowitz + + * inferiors.c (all_dlls, dlls_changed, get_dll): New. + (add_thread): Minor cleanups. + (clear_inferiors): Move lower in the file. Clear the DLL + list. + (free_one_dll, match_dll, loaded_dll, unloaded_dll, clear_list): New. + * remote-utils.c (prepare_resume_reply): Check dlls_changed. + (xml_escape_text): New. + * server.c (handle_query): Handle qXfer:libraries:read. Report it + for qSupported. + (handle_v_cont): Report errors. + (gdbserver_version): Update. + (main): Correct size of own_buf. Do not report initial DLL events. + * server.h (struct dll_info, all_dlls, dlls_changed, loaded_dll) + (unloaded_dll, xml_escape_text): New. + * win32-low.c (enum target_waitkind): Update comments. + (win32_add_one_solib, get_image_name, winapi_EnumProcessModules) + (winapi_GetModuleInformation, winapi_GetModuleFileNameExA) + (win32_EnumProcessModules, win32_GetModuleInformation) + (win32_GetModuleFileNameExA, load_psapi, psapi_get_dll_name) + (winapi_CreateToolhelp32Snapshot, winapi_Module32First) + (winapi_Module32Next, win32_CreateToolhelp32Snapshot) + (win32_Module32First, win32_Module32Next, load_toolhelp) + (toolhelp_get_dll_name, handle_load_dll, handle_unload_dll): New. + (get_child_debug_event): Handle DLL events. + (win32_wait): Likewise. + +2007-07-12 Daniel Jacobowitz + + * configure.srv: Set srv_linux_regsets for sh*-*-linux*. + * linux-sh-low.c (sh_fill_gregset, target_regsets): New. + +2007-07-08 Pedro Alves + + * win32-low.c (handle_output_debug_string): Ignore event if not + waiting. + +2007-07-08 Pedro Alves + + * win32-arm-low.c (arm_wince_breakpoint): Fix typo. + +2007-07-03 Daniel Jacobowitz + + * remote-utils.c (look_up_one_symbol): Handle 'm' packets. + +2007-07-02 Daniel Jacobowitz + + * inferiors.c (change_inferior_id): Add comment. + * linux-low.c (check_removed_breakpoint): Add an early + prototype. Improve debug output. + (linux_attach): Doc update. + (linux_detach_one_process, linux_detach): Clean up before releasing + each process. + (send_sigstop, wait_for_sigstop): Improve comments and debug output. + * linux-low.h (struct process_info): Doc improvement. + * mem-break.c (delete_all_breakpoints): New. + * mem-break.h (delete_all_breakpoints): New prototype. + * thread-db.c (find_first_thread): New. + (thread_db_create_event): Call it instead of + thread_db_find_new_threads. Clean up unused variables. + (maybe_attach_thread): Remove first thread handling. + (thread_db_find_new_threads): Use find_first_thread. + (thread_db_get_tls_address): Likewise. + +2007-06-27 Daniel Jacobowitz + + * thread-db.c (thread_db_find_new_threads): Add prototype. + (thread_db_create_event): Check for the main thread before adding + a new thread. + (maybe_attach_thread): Only enable event reporting if TID == 0. + (thread_db_get_tls_address): Check for new threads. + +2007-06-20 Daniel Jacobowitz + + * linux-low.c (linux_create_inferior): Try execv before execvp. + * spu-low.c (spu_create_inferior): Likewise. + +2007-06-13 Mike Frysinger + + * linux-low.c (linux_create_inferior): Change execv to execvp. + * spu-low.c (spu_create_inferior): Likewies. + +2007-06-13 Daniel Jacobowitz + + * Makefile.in (clean): Clean new files instead of deleted ones. + (reg-mips.o, reg-mips.c, reg-mips64.o, reg-mips64.c): Delete. + (mips-linux.o, mips-linux.c, mips64-linux.o, mips64-linux.c): New + rules. + * configure.srv: Specify XML files and new regformats for MIPS and + MIPS64 GNU/Linux. + * linux-mips-low.c (mips_num_regs): Set to only used registers. + (mips_regmap): Do not fetch $0. Remove unused registers. Add + an entry for the restart register. + (mips_cannot_fetch_register, mips_cannot_store_register) + (mips_reinsert_addr, mips_fill_fpregset, mips_store_fpregset): Update + register names to match the XML descriptions. + (mips_fill_gregset, mips_store_gregset): Likewise. Handle the + restart register instead of $0. + +2007-06-12 Ulrich Weigand + Markus Deuling + + * remote-utils.c (decode_xfer_write): New function. + * server.h (decode_xfer_write): Add prototype. + * server.c (handle_query): Add PACKET_LEN argument. Support + qXfer:spu:read and qXfer:spu:write packets. + (main): Pass packet_len to handle_query. + * spu-low.c (spu_target_ops): Add spu_proc_xfer_spu. + * target.h (target_ops): Add qxfer_spu. + +2007-06-12 Ulrich Weigand + + * spu-low.c (spu_proc_xfer_spu): Do not return failure when + accessing non-seekable spufs files. + +2007-05-16 Markus Deuling + + * server.c (handle_query): Add reply for qC packet. + +2007-05-10 Pedro Alves + Leo Zayas + + * server.h (check_remote_input_interrupt_request): New function. + * remote_utils.c (INVALID_DESCRIPTOR): New define. + (remote_desc): Initialize with INVALID_DESCRIPTOR. + (input_interrupt): Expose on USE_WIN32API too. Fix whitespace. + (check_remote_input_interrupt_request): New function. + * server.h (check_remote_input_interrupt_request): Declare. + * win32-low.c (winapi_DebugBreakProcess, + winapi_GenerateConsoleCtrlEvent): New typedefs. + (get_child_debug_event): Lower Win32 debug event polling from 1 sec + to 250 ms. + (win32_wait): Check for remote interrupt request + with check_remote_input_interrupt_request. + (win32_request_interrupt): New function. + (win32_target_op): Set request_interrupt to win32_request_interrupt. + +2007-05-10 Pedro Alves + + * win32-low.c (debug_registers_changed, + debug_registers_used, CONTEXT_EXTENDED_REGISTERS, + CONTEXT_FLOATING_POINT, CONTEXT_DEBUG_REGISTERS, + CONTEXT_DEBUGGER, CONTEXT_DEBUGGER_DR): Delete. + (thread_rec): Get context using the low target. + (child_add_thread): Call thread_added on the low target, + which does the same thing. + (regptr): Delete. + (do_initial_child_stuff): Remove debug registers references. + Set context using the low target. Resume threads after + setting the contexts. + (child_continue): Remove dead variable. Remove debug + registers references. + (child_fetch_inferior_registers): Go through the low target. + (do_child_store_inferior_registers): Remove. + (child_store_inferior_registers): Go through the low target. + (win32_resume): Remove debug registers references. + Set context using the low target. + (handle_exception): Change return type to void. Don't record + context here. Set status to TARGET_WAITKIND_SPURIOUS on a + first chance exception. + (get_child_debug_event): Change return type to void. Remove + goto loop. Always return after waiting for debug event. + (win32_wait): Convert to switch statement. Handle spurious + events. + + * win32-i386-low.c (debug_registers_changed, + debug_registers_used): New. + (initial_stuff): Rename to ... + (i386_initial_stuff): ... this. Clear debug registers + state variables. + (store_debug_registers): Delete. + (i386_get_thread_context): New. + (load_debug_registers): Delete. + (i386_set_thread_context): New. + (i386_thread_added): New. + (single_step): Rename to ... + (i386_single_step): ... this. + (do_fetch_inferior_registers): Rename to ... + (i386_fetch_inferior_register): ... this. + (i386_store_inferior_register): New. + (the_low_target): Adapt to new interface. + + * win32-arm-low.c (CONTEXT_FLOATING_POINT): Define. + (arm_get_thread_context): New. + (arm_set_thread_context): New. + (regptr): New. + (do_fetch_inferior_registers): Rename to ... + (arm_fetch_inferior_register): ... this. + (arm_store_inferior_register): New. + (arm_wince_breakpoint): Reimplement as unsigned long. + (arm_wince_breakpoint_len): Define. + (the_low_target): Adapt to new interface. + + * win32-low.h (target_ops): Remove regmap, store_debug_registers and + load_debug_registers. Add get_thread_context, set_thread_context, + thread_added and store_inferior_register. Rename + fetch_inferior_registers to fetch_inferior_register. + (regptr): Remove declaration. + +2007-05-10 Pedro Alves + + * linux-low.c (linux_detach): Change return type to int. Return 0. + * spu-low.c (spu_detach): Likewise. + +2007-05-10 Pedro Alves + + * target.h (target_ops): Change return type of detach to int. + Add join. + (join_inferior): New. + * server.c (main): Don't skip detach support on mingw32. + If the inferior doesn't support detaching return error. + Call join_inferior instead of using waitpid. + * linux-low.c (linux_join): New. + (linux_target_op): Add linux_join. + * spu-low.c (spu_join): New. + (spu_target_ops): Add spu_join. + * win32-low.c (win32_detach): Adapt to new interface. + Reopen current_process_handle before detaching. Issue a child + resume before detaching. + (win32_join): New. + (win32_target_op): Add win32_join. + +2007-05-10 Pedro Alves + + * win32-low.c (win32-attach): Fix return value. + * target.h (target_ops): Describe ATTACH return values. + +2007-05-10 Pedro Alves + + * win32-low.c (GETPROCADDRESS): Define. + (winapi_DebugActiveProcessStop): Add WINAPI. typedef as pointer. + (winapi_DebugSetProcessKillOnExit): Likewise. + (win32_create_inferior): Force usage of ansi CreateProcessA. + (win32_attach): Use GETPROCADDRESS. + (win32_detach): Likewise. + +2007-05-10 Pedro Alves + + * win32-low.c (win32_wait): Don't use WSTOPSIG. + +2007-03-30 Pedro Alves + + * win32-low.c: Commit leftover changes from 2007-03-29. + +2007-03-30 Daniel Jacobowitz + + * i387-fp.c (struct i387_fsave, struct i387_fxsave): Make 16-bit + fields short instead of int. Add explicit padding. + (i387_cache_to_fsave): Remove unnecessary casts. + (i387_fsave_to_cache): Doc fix. + (i387_cache_to_fxsave): Remove unnecessary casts and masking. + +2007-03-30 Daniel Jacobowitz + + * i387-fp.c (i387_cache_to_fxsave): Reinitialize val2 before use. + (i387_fxsave_to_cache): Check fp->ftag while building ftag value. + +2007-03-29 Pedro Alves + + * configure.srv (arm*-*-mingw32ce*): Move near the other + arm targets. + +2007-03-29 Pedro Alves + + * configure.ac: Add errno checking. + (AC_CHECK_HEADERS): Add errno.h, fcntl.h, signal.h, + sys/file.h and malloc.h. + (AC_CHECK_DECLS): Add perror. + (srv_mingwce): Handle. + * configure.srv (i[34567]86-*-cygwin*): Add + win32-i386-low.o to srv_tgtobj. + (i[34567]86-*-mingw*): Likewise. + (arm*-*-mingw32ce*): Add case. + * gdbreplay.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H, + HAVE_FCNTL_H, HAVE_ERRNO_H, HAVE_MALLOC_H]: Check. + [__MINGW32CE__] (strerror): New function. + [__MINGW32CE__] (errno): Define to GetLastError. + [__MINGW32CE__] (COUNTOF): New macro. + (remote_open): Remove extra close call. + * mem-break.c (delete_breakpoint_at): New function. + * mem-break.h (delete_breakpoint_at): Declare. + * remote-utils.c [HAVE_SYS_FILE_H, HAVE_SIGNAL_H, + HAVE_FCNTL_H, HAVE_UNISTD_H, HAVE_ERRNO_H]: Check. + [USE_WIN32API] (read, write): Add char* casts. + * server.c [HAVE_UNISTD_H, HAVE_SIGNAL_H]: Check. + * server.h: Include wincecompat.h on Windows CE. + [HAVE_ERRNO_H]: Check. + (perror): Declare if not declared. + * utils.c: Add stdlib.h, errno.h and malloc.h includes. + (perror_with_name): Remove errno declaration. + * wincecompat.h: New. + * wincecompat.c: New. + * win32-low.h: New. + * win32-arm-low.c: New. + * win32-i386-low.c: New. + (win32-low.c): Include mem-break.h and win32-low.h, and winnt.h. + (OUTMSG2): Make it safe. + (_T): New macro. + (COUNTOF): New macro. + (NUM_REGS): Get it from the low target. + (CONTEXT_EXTENDED_REGISTERS, CONTEXT_FLOATING_POINT, + CONTEXT_DEBUG_REGISTERS): Add fallbacks to 0. + (thread_rec): Let low target handle debug registers. + (child_add_thread): Likewise. + (child_init_thread_list): Likewise. + (continue_one_thread): Likewise. + (regptr): New. + (do_child_fetch_inferior_registers): Move to ... + * win32-i386-low.c: ... here, and rename to ... + (do_fetch_inferior_registers): ... this. + * win32-low.c (child_fetch_inferior_registers): + Go through the low target. + (do_child_store_inferior_registers): Use regptr. + (strwinerror): New function. + (win32_create_inferior): Handle Windows CE. + Use strwinerror instead of strerror on Windows error + codes. Add program to the error output. + Don't close the main thread handle on Windows CE. + (win32_attach): Use coredll.dll on Windows CE. + (win32_kill): Close current process and current + thread handles. + (win32_detach): Use coredll.dll on Windows CE. + (win32_resume): Let low target handle debug registers, and + step request. + (handle_exception): Add/Remove initial breakpoint. Avoid + non-existant WSTOPSIG on Windows CE. + (win32_read_inferior_memory): Cast to remove warning. + (win32_arch_string): Go through the low target. + (initialize_low): Call set_breakpoint_data with the low + target's breakpoint. + * win32-low.c (dr, FLAG_TRACE_BIT, FCS_REGNUM, + FOP_REGNUM, mappings): Move to ... + * win32-i386-low.c: ... here. + * win32-low.c (win32_thread_info): Move to ... + * win32-low.h: ... here. + * Makefile.in (SFILES): Add win32-low.c, win32-i386-low.c, + win32-arm-low.c and wincecompat.c. + (all:): Add $EXEEXT. + (install-only:): Likewise. + (gdbserver:): Likewise. + (gdbreplay:): Likewise. + * config.in: Regenerate. + * configure: Regenerate. + +2007-03-28 Pedro Alves + + * win32-low.c: Rename typedef thread_info to + win32_thread_info throughout. + +2007-03-28 Pedro Alves + + * win32-i386-low.c: Rename to ... + * win32-low.c: ... this. + * configure.srv: Replace win32-i386-low.o with win32-low.o. + * Makefile.in: Likewise. + +2007-03-27 Pedro Alves + + * remote-utils.c (monitor_output): Constify msg parameter. + * server.h (monitor_output): Likewise. + * win32-i386-low.c (handle_output_debug_string): New. + (win32_kill): Handle OUTPUT_DEBUG_STRING_EVENT events using + handle_output_debug_string. + (get_child_debug_event): Likewise. + +2007-03-27 Mat Hostetter + + * server.c (main): Correct strtoul check. + +2007-03-27 Jon Ringle + + * linux-low.c: Check __ARCH_HAS_MMU__ also. + +2007-03-27 Brooks Moses + + * Makefile.in: Add dummy "pdf" and "install-pdf" targets. + +2007-02-27 Daniel Jacobowitz + + * terminal.h: Check HAVE_SGTTY_H. + +2007-02-27 Mat Hostetter + + * remote-utils.c (remote_open): Print out the assigned port number. + +2007-02-26 Daniel Jacobowitz + + * remote-utils.c (monitor_output): New function. + * server.c (debug_threads): Define here. + (monitor_show_help): New function. + (handle_query): Handle qRcmd. + (main): Do not handle 'd' packet. + * server.h (debug_threads, remote_debug, monitor_output): Declare. + * linux-low.c, spu-low.c, win32-i386-low.c: Remove definitions + of debug_threads. + +2007-02-25 Pedro Alves + + * Makefile.in (EXEEXT): New. + (clean): Use $(EXEEXT). + +2007-02-25 Pedro Alves + + * target.h (target_ops): Rename send_signal to request_interrupt, + and remove enum target_signal parameter. + * linux-low.c (linux_request_interrupt): Rename from + linux_send_signal, and always send SIGINT. + * spu-low.c (spu_request_interrupt): Rename from spu_send_signal, + and always send SIGINT. + * remote-utils.c (putpkt_binary): Call request_interrupt, instead + of send_signal. + (input_interrupt): Likewise. + +2007-02-25 Pedro Alves + + * server.c (get_features_xml): Check if target implemented + arch_string. + * win32-i386-low.c (win32_arch_string): New. + (win32_target_ops): Add win32_arch_string as arch_string member. + +2007-02-22 Markus Deuling + + * spu-low.c (spu_arch_string): New. + (spu_target_ops): Add spu_arch_string. + +2007-02-16 Daniel Jacobowitz + + * remote-utils.c: Remove HAVE_TERMINAL_H check. + * configure.ac: Do not check for terminal.h. + * configure, config.in: Regenerated. + +2007-02-08 Daniel Jacobowitz + + * Makefile.in (OBS): Add $(XML_BUILTIN). + (XML_DIR, XML_TARGET, XML_FILES, XML_BUILTIN): New. + (clean): Update. + (target.xml, xml-builtin.c, stamp-xml, arm-with-iwmmxt.o) + (arm-with-iwmmxt.c): New. + * config.in, configure: Regenerate. + * configure.ac: Check for iWMMXt. Handle srv_xmltarget, + srv_xmlbuiltin, and srv_xmlfiles. Define USE_XML. + * configure.srv: Mention srv_xmltarget and srv_xmlfiles. + (arm*-*-linux*): Add iWMMXt and regset support. + * linux-arm-low.c (PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS): Define. + (arm_fill_gregset, arm_store_gregset, arm_fill_wmmxregset) + (arm_store_wmmxregset, target_regsets): New. + * server.c (get_features_xml): Take annex argument. Check builtin + XML documents. + (handle_query): Handle multiple annexes. + +2007-01-29 Daniel Jacobowitz + + * remote-utils.c [USE_WIN32API] (read, write): Define. + (putpkt_binary, input_interrupt, readchar, getpkt): Use read and + write. + +2007-01-09 Daniel Jacobowitz + + * linux-i386-low.c (the_low_target): Set arch_string. + * linux-x86-64-low.c (the_low_target): Likewise. + * linux-low.c (linux_arch_string): New. + (linux_target_ops): Add it. + * linux-low.h (struct linux_target_ops): Add arch_string. + * server.c (write_qxfer_response): Use const void * for DATA. + (get_features_xml): New. + (handle_query): Handle qXfer:features:read. Report it for qSupported. + * target.h (struct target_ops): Add arch_string method. + +2007-01-03 Denis Pilat + Daniel Jacobowitz + + * linux-low.c (linux_kill): Handle being called with no threads. + * win32-i386-low.c (win32_kill): Likewise. + (get_child_debug_event): Clear current_process_handle. + +2006-12-30 Denis PILAT + Daniel Jacobowitz + + * remote-utils.c (remote_open): Check the type of specified + serial port devices before opening them. + * server.c (main): Kill the inferior if an error occurs during + the first remote_open. + +2006-12-05 Markus Deuling + + * README: Update supported targets. + +2006-11-28 Daniel Jacobowitz + + * Makefile.in (clean): Remove reg-mips64.c. + (reg-mips64.c, reg-mips64.o): New rules. + * configure.srv: Handle mips64. Include regset support for mips. + * linux-mips-low.c (union mips_register): New. + (mips_get_pc, mips_set_pc, mips_reinsert_addr): Use it. + (mips_breakpoint, mips_breakpoint_at): Use int. + (mips_collect_register, mips_supply_register) + (mips_collect_register_32bit, mips_supply_register_32bit) + (mips_fill_gregset, mips_store_gregset, mips_fill_fpregset) + (mips_store_fpregset, target_regsets): New. + * thread-db.c (thread_db_get_tls_address): Use uintptr_t. + +2006-11-22 Ulrich Weigand + + * configure.srv: Add target "spu*-*-*". + * Makefile.in (clean): Remove reg-spu.c. + (reg-spu.c, reg-spu.o, spu-low.o): Add dependencies. + * spu-low.c: New file. + +2006-11-16 Daniel Jacobowitz + + * configure.ac: Correct td_thr_tls_get_addr test. + * configure: Regenerated. + +2006-11-16 Daniel Jacobowitz + + * linux-low.c (linux_wait_for_event): Reformat. Use the + pass_signals array. + * remote-utils.c (decode_address_to_semicolon): New. + * server.c (pass_signals, handle_general_set): New. + (handle_query): Mention QPassSignals for qSupported. + (main): Call handle_general_set. + * server.h (pass_signals, decode_address_to_semicolon): New. + +2006-11-06 Daniel Jacobowitz + + * server.c (handle_query): Correct error handling for read_auxv. + +2005-10-19 Ulrich Weigand + + * configure.srv [s390-*-linux*, s390x-*-linux*]: Set srv_linux_regsets + and srv_linux_thread_db to yes. + * linux-s390-low.c (s390_fill_gregset): New function. + (target_regsets): Define data structure. + +2006-10-17 Daniel Jacobowitz + + * acinclude.m4 (SRV_CHECK_TLS_GET_ADDR): New. + * configure.ac: Use it. Define HAVE_TD_THR_TLS_GET_ADDR. + * config.in, configure: Regenerated. + * inferiors.c (gdb_id_to_thread): New function. + (gdb_id_to_thread_id): Use it. + * linux-low.c (linux_target_ops): Use thread_db_get_tls_address. + * linux-low.h (struct process_info): Add th member. + (thread_db_get_tls_address): New prototype. + * remote-utils.c (decode_address): Make non-static. + * server.c (handle_query): Handle qGetTLSAddr. + * server.h (gdb_id_to_thread, decode_address): New prototypes. + * target.h (struct target_ops): Add get_tls_address. + * thread-db.c (maybe_attach_thread): Save the thread handle. + (thread_db_get_tls_address): New. + +2006-09-28 Daniel Jacobowitz + + * linux-low.c (PTRACE_GETSIGINFO, PTRACE_SETSIGINFO): Define. + (linux_resume_one_process): Take a siginfo_t *. Update all + callers. Queue it if necessary. Use PTRACE_SETSIGINFO. + (struct pending_signals): Add a siginfo_t. + (linux_wait_for_process): Always set last_status. + (linux_wait_for_event): Use PTRACE_GETSIGINFO. + (linux_queue_one_thread): Use PTRACE_GETSIGINFO. + * linux-low.h (struct process_info): Add last_status. + +2006-09-21 Daniel Jacobowitz + + * remote-utils.c (try_rle): New function. + (putpkt_binary): Use it. + +2006-08-19 Daniel Jacobowitz + + * Makefile.in (clean): Clean reg-x86-64-linux.c. + (reg-x86-64-linux.o, reg-x86-64-linux.c): New. + * configure.srv (x86_64-*-linux*): Use reg-x86-64-linux.o. + * linux-x86-64-low.c (x86_64_regmap): Include ORIG_RAX. + (x86_64_fill_gregset, x86_64_store_gregset): Skip floating + point registers. + +2006-08-08 Richard Sandiford + + * server.c (terminal_fd): New variable. + (old_foreground_pgrp): Likewise. + (restore_old_foreground_pgrp): New function. + (start_inferior): Record the terminal file descriptor in terminal_fd + and its original foreground group in old_foreground_pgrp. Register + restore_old_foreground_pgrp with atexit(). + +2006-07-26 Daniel Jacobowitz + + * server.c (handle_query): Correct qPart to qXfer. + +2006-07-22 Daniel Jacobowitz + + * configure.ac: Check for more headers which are missing on + Windows. Automatically supply -lwsock32 and USE_WIN32API. + * configure.srv: Add Cygwin and mingw32. + * remote-utils.c: Don't include headers unconditionally which + are missing on mingw32. Include for mingw32. + (remote_open): Adjust for mingw32 support. Flush + standard error after writing to it. + (remote_close, putpkt_binary, input_interrupt, block_async_io) + (unblock_async_io, enable_async_io, disable_async_io) + (readchar, getpkt): Update for Winsock support. + (prepare_resume_reply): Expect a protocol signal number. + * server.c: Disable on mingw32. + (start_inferior): Adjust for mingw32 support. Flush + standard error after writing to it. + (attach_inferior): Likewise. Use protocol signal + numbers. + (main): Skip 'D' packet on mingw32. Use protocol signal numbers + and names. + * win32-i386-low.c: New file. + * Makefile.in (XM_CLIBS): Set. + (gdbserver, gdbreplay): Use $(INTERNAL_CFLAGS). + (win32-i386-low.o): New dependency rule. + * linux-low.c (linux_wait): Use target signal numbers. + * target.h (struct target_ops): Doc fix. + * server.h (target_signal_to_name): New prototype. + * gdbreplay.c: Don't include headers unconditionally which + are missing on mingw32. Include for mingw32. + (remote_close, remote_open): Adjust for Winsock support. + * configure, config.in: Regenerated. + +2006-07-12 Daniel Jacobowitz + + * server.c (decode_xfer_read, write_qxfer_response): New. + (handle_query): Take a packet length argument. Handle + qXfer:auxv:read instead of qPart:auxv:read. Mention it in + the qSupported response. + (main): Update call to handle_query. + +2006-06-22 Daniel Jacobowitz + + * remote-utils.c (remote_escape_output, remote_unescape_input): New. + (putpkt_binary): Renamed from putpkt and adjusted for binary + data. + (putpkt): New wrapper for putpkt_binary. + (readchar): Don't mask off the high bit. + (decode_X_packet): New function. + * server.c (main): Call putpkt_binary if a handler sets the packet + length. Save the length of the incoming packet. Handle 'X'. + * server.h (gdb_byte, remote_escape_output, decode_X_packet): New. + +2006-06-21 Daniel Jacobowitz + + * server.c (handle_query): Handle qSupported. + +2006-05-30 Daniel Jacobowitz + + * remote-utils.c (all_symbols_looked_up): New variable. + (look_up_one_symbol): Check it. + * server.h (look_up_one_symbol): New declaration. + * thread-db.c (thread_db_init): Set all_symbols_looked_up. + +2006-05-30 Daniel Jacobowitz + + * Makefile.in (linux-arm-low.o): Update dependencies. + * linux-arm-low.c: Include "gdb_proc_service.h". + (PTRACE_GET_THREAD_AREA): Define. + (ps_get_thread_area): New function. + +2006-05-09 Nathan Sidwell + + * configure.srv (m68k*-*-uclinux*): New target. + * linux-low.c (linux_create_inferior): Use vfork on mmuless systems. + (linux_resume_one_process): Remove extraneous cast. + (linux_read_offsets): New. + (linux_target_op): Add linux_read_offsets on mmuless systems. + * server.c (handle_query): Add qOffsets logic. + * target.h (struct target_ops): Add read_offsets. + +2006-03-15 Daniel Jacobowitz + + * linux-mips-low.c: Include and "gdb_proc_service.h". + (PTRACE_GET_THREAD_AREA): Define. + (ps_get_thread_area): New function. + * Makefile.in (linux-i386-low.o, linux-mips-low.o) + (linux-x86-64-low.o): Update. + +2006-03-15 Daniel Jacobowitz + + * configure.ac: Remove checks for prfpregset_t. + * gdb_proc_service.h: New file. + * linux-i386-low.c, linux-x86-64-low.c, thread-db.c: Use the + new "gdb_proc_service.h". + * proc-service.c: Likewise. + (ps_pglobal_lookup, ps_pdread, ps_pdwrite): Use psaddr_t. + (ps_lgetfpregs, ps_lsetfpregs): Use a void* argument. + * Makefile.in (gdb_proc_service_h): Updated. + * configure, config.in: Regenerated. + +2006-03-03 Daniel Jacobowitz + + * remote-utils.c (prepare_resume_reply): Move declaration + of gdb_id_from_wait to the top of the block. + +2006-02-15 Daniel Jacobowitz + + * linux-low.c (regsets_store_inferior_registers): Read the regset + from the target before filling it. + +2006-02-08 Daniel Jacobowitz + + * server.c (attach_inferior): Return SIGTRAP for a successful + attach. + +2006-02-01 Daniel Jacobowitz + + * Makefile.in (OBS): Add version.o. + (STAGESTUFF): Delete. + (version.o): Add dependencies. + (version.c): Replace rule. + (clean): Remove version.c. + * server.c (gdbserver_version): New. + (gdbserver_usage): Use printf. + (main): Handle --version and --help. + * server.h (version, host_name): Add declarations. + +2005-12-23 Eli Zaretskii + + * linux-arm-low.c: + * linux-arm-low.c: + * inferiors.c: + * i387-fp.h: + * i387-fp.c: + * gdbreplay.c: + * regcache.c: + * proc-service.c: + * mem-break.h: + * mem-break.c: + * linux-x86-64-low.c: + * linux-sh-low.c: + * linux-s390-low.c: + * linux-ppc64-low.c: + * linux-ppc-low.c: + * linux-mips-low.c: + * linux-m68k-low.c: + * linux-m32r-low.c: + * linux-low.h: + * linux-low.c: + * linux-ia64-low.c: + * linux-i386-low.c: + * linux-crisv32-low.c: + * thread-db.c: + * terminal.h: + * target.h: + * target.c: + * server.h: + * server.c: + * remote-utils.c: + * regcache.h: + * utils.c: + * Makefile.in: + * configure.ac: + * gdbserver.1: Add (C) after Copyright. Update the FSF + address. + +2005-11-13 Daniel Jacobowitz + + * linux-arm-low.c (arm_eabi_breakpoint): New variable. + (arm_breakpoint_at): Recognize both breakpoints. + (the_low_target): Use the correct breakpoint instruction. + +2005-11-02 Daniel Jacobowitz + + * configure.srv (x86_64-*-linux*): Turn on thread_db support. + * linux-x86-64-low.c (x86_64_breakpoint, x86_64_breakpoint_len) + (x86_64_get_pc, x86_64_set_pc, x86_64_breakpoint_at): New. + (the_low_target): Update. + +2005-10-25 Andreas Schwab + + * server.c (main): Allocate mem_buf with PBUFSIZ bytes. + + * linux-ia64-low.c (ia64_regmap): Remove NAT registers. + (ia64_num_regs): Reduce to 462. + +2005-09-17 Daniel Jacobowitz + + * acinclude.m4: Correct quoting. + * aclocal.m4: Regenerated. + + Suggested by SZOKOVACS Robert : + * thread-db.c (thread_db_err_str): Handle TD_VERSION. + (thread_db_init): Call thread_db_err_str. + * configure.ac: Check for TD_VERSION. + * config.in, configure: Regenerated. + +2005-07-31 Kaveh R. Ghazi + + * server.h (error, fatal, warning): Add ATTR_FORMAT. + +2005-07-13 Daniel Jacobowitz + + * configure.ac: Define HAVE_LINUX_REGSETS even if PTRACE_GETREGS + is not available. Define HAVE_PTRACE_GETREGS if it is. + * config.in, configure: Regenerated. + * configure.srv: Set srv_linux_regsets for PowerPC and PowerPC64. + * linux-i386-low.c, linux-m68k-low.c: Update to use + HAVE_PTRACE_GETREGS. + * linux-low.c (regsets_fetch_inferior_registers) + (regsets_store_inferior_registers): Only return 0 if we processed + GENERAL_REGS. + * linux-ppc-low.c (ppc_fill_gregset, target_regsets): New. + * linux-ppc64-low.c (ppc_fill_gregset, target_regsets): New. + +2005-07-13 Daniel Jacobowitz + + * inferiors.c (struct thread_info): Add gdb_id. + (add_thread): Add gdb_id argument. + (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New. + * linux-low.c (linux_create_inferior, linux_attach_lwp): Update + calls to add_thread. + * remote-utils.c (prepare_resume_reply: Use thread_to_gdb_id. + * server.c (handle_query): Use thread_to_gdb_id. + (handle_v_cont, main): Use gdb_id_to_thread_id. + * server.h (add_thread): Update prototype. + (thread_id_to_gdb_id, thread_to_gdb_id, gdb_id_to_thread_id): New + prototypes. + +2005-07-13 Daniel Jacobowitz + + * linux-low.c (fetch_register, usr_store_inferior_registers): Handle + left-padded registers. + * linux-low.h (struct linux_target_ops): Add left_pad_xfer. + * linux-ppc64-low.c (the_low_target): Set left_pad_xfer. + +2005-07-01 Steve Ellcey + + * configure.ac (BFD_NEED_DECLARATION): Replace with AC_CHECK_DECLS. + * configure: Regenerate. + * config.in: Regenerate. + * server.h (NEED_DECLARATION_STRERROR): + Replace with !HAVE_DECL_STRERROR. + +2005-06-16 Daniel Jacobowitz + + * linux-low.c (linux_wait, linux_send_signal): Don't test + an unsigned long variable for > 0 if it could be MAX_ULONG. + * server.c (myresume): Likewise. + * target.c (set_desired_inferior): Likewise. + +2005-06-13 Mark Kettenis + + * configure.ac: Simplify and improve check for socklen_t. + * configure, config.in: Regenerate. + +2005-06-12 Daniel Jacobowitz + + * acconfig.h: Remove. + * configure.ac: Add a test for socklen_t. Use three-argument + AC_DEFINE throughout. + * config.in: Regenerated using autoheader 2.59. + * configure: Regenerated. + + * gdbreplay.c (socklen_t): Provide a default. + (remote_open): Use socklen_t. + * remote-utils.c (socklen_t): Provide a default. + (remote_open): Use socklen_t. + (convert_int_to_ascii, convert_ascii_to_int, decode_M_packet): Use + unsigned char. + + * i387-fp.c (struct i387_fsave, struct i387_fxsave): Use unsigned + char for buffers. + * linux-low.c (linux_read_memory, linux_write_memory) + (linux_read_auxv): Likewise. + * mem-break.c (breakpoint_data, set_breakpoint_data, check_mem_read) + (check_mem_write): Likewise. + * mem-break.h (set_breakpoint_data, check_mem_read, check_mem_write): + Likewise. + * regcache.c (struct inferior_rgcache_data, registers_to_string) + (registers_from_string, register_data): Likewise. + * server.c (handle_query, main): Likewise. + * server.h (convert_ascii_to_int, convert_int_to_ascii) + (decode_M_packet): Likewise. + * target.c (read_inferior_memory, write_inferior_memory): Likewise. + * target.h (struct target_ops): Update read_memory, write_memory, + and read_auxv. + (read_inferior_memory, write_inferior_memory): Update. + * linux-low.h (struct linux_target_ops): Change type of breakpoint + to unsigned char *. + * linux-arm-low.c, linux-cris-low.c, linux-crisv32-low.c, + linux-i386-low.c, linux-m32r-low.c, linux-m68k-low.c, + linux-mips-low.c, linux-ppc-low.c, linux-ppc64-low.c, + linux-s390-low.c, linux-sh-low.c: Update for changes in + read_inferior_memory and the_low_target->breakpoint. + +2005-05-28 Daniel Jacobowitz + + * Makefile.in (SFILES): Add linux-ppc64-low.c. + (linux-ppc64-low.o, reg-ppc64.c, reg-ppc64.o): New targets. + * configure.srv: Add powerpc64-*-linux*. + * linux-ppc64-low.c: New file. + +2005-05-23 Orjan Friberg + + * linux-cris-low.c: New file with support for CRIS. + * linux-crisv32-low.c: Ditto for CRISv32. + * Makefile.in (SFILES): Add linux-cris-low.c, linux-crisv32-low.c. + (clean): Add reg-cris.c and reg-crisv32.c. + Add linux-cris-low.o, linux-crisv32-low.o, reg-cris.o, reg-cris.c, + reg-crisv32.o, and reg-crisv32.c to make rules. + * configure.srv: Add cris-*-linux* and crisv32-*-linux* to list of + recognized targets. + +2005-05-16 Ulrich Weigand + + * linux-low.c (fetch_register): Ensure buffer size is a multiple + of sizeof (PTRACE_XFER_TYPE). + (usr_store_inferior_registers): Likewise. Zero out excess bytes. + +2005-05-12 Orjan Friberg + + * target.h (struct target_ops): Add insert_watchpoint, + remove_watchpoint, stopped_by_watchpoint, stopped_data_address function + pointers for hardware watchpoint support. + * linux-low.h (struct linux_target_ops): Ditto. + * linux-low.c (linux_insert_watchpoint, linux_remove_watchpoint) + (linux_stopped_by_watchpoint, linux_stopped_data_address): New. Add + to linux_target_ops. + * remote-utils.c (prepare_resume_reply): Add watchpoint information to + reply packet. + * server.c (main): Recognize 'Z' and 'z' packets. + +2005-05-10 Ulrich Weigand + + * linux-s390-low.c (s390_breakpoint, s390_breakpoint_len): Define. + (s390_get_pc, s390_set_pc, s390_breakpoint_at): New functions. + (the_low_target): Add new members. + +2005-05-04 Daniel Jacobowitz + + * proc-service.c (ps_lgetregs): Search all_processes instead of + all_threads. + +2005-05-04 Daniel Jacobowitz + + * server.c (start_inferior): Change return type to int. + (attach_inferior): Change sigptr to int *. + (handle_v_cont, handle_v_requests): Change signal to int *. + (main): Change signal to int. + +2005-04-15 Kei Sakamoto + + * Makefile.in: Add linux-m32r-low.o, reg-m32r.c and reg-m32r.o. + * configure.srv: Add m32r*-*-linux*. + * linux-m32r-low.c: New file. + +2005-03-04 Daniel Jacobowitz + + * Makefile.in (stamp-h): Set CONFIG_HEADERS explicitly. + +2005-03-03 Daniel Jacobowitz + + * inferiors.c (change_inferior_id, add_thread, find_inferior_id): + Take unsigned long arguments for PIDs. + * linux-low.c (add_process, linux_attach_lwp, linux_attach) + (linux_thread_alive, linux_wait_for_event, kill_lwp, send_sigstop) + (wait_for_sigstop, linux_resume_one_process) + (regsets_fetch_inferior_registers, linux_send_signal) + (linux_read_auxv): Likewise. Update the types of variables holding + PIDs. Update format string specifiers. + * linux-low.h (struct process_info, linux_attach_lwp): Likewise. + * remote-utils.c (prepare_resume_reply): Likewise. + * server.c (cont_thread, general_thread, step_thread) + (thread_from_wait, old_thread_from_wait, signal_pid): Change type to + unsigned long. + (handle_query): Update format specifiers. + (handle_v_cont, main): Use strtoul for thread IDs. + * server.h (struct inferior_list_entry): Use unsigned long for ID. + (add_thread, find_inferior_id, change_inferior_id, cont_thread) + (general_thread, step_thread, thread_from_wait) + (old_thread_from_wait): Update. + * target.h (struct thread_resume): Use unsigned long for THREAD. + (struct target_ops): Use unsigned long for arguments to attach and + thread_alive. + +2005-02-24 Daniel Jacobowitz + + * acinclude.m4: Include bfd/bfd.m4 directly. + * configure.ac: Use AC_ARG_PROGRAM. Suggested by Aron Griffis + . + * aclocal.m4, configure: Regenerated. + +2005-01-07 Andrew Cagney + + * configure.ac: Rename configure.in, require autoconf 2.59. + * configure: Re-generate. + +2004-12-08 Daniel Jacobowitz + + * acinclude.m4 (SRV_CHECK_THREAD_DB): Add ps_get_thread_area. Reset + LIBS when finished. + * aclocal.m4: Regenerated. + * configure: Regenerated. + +2004-11-21 Andreas Schwab + + * linux-m68k-low.c (m68k_num_gregs): Define. + (m68k_fill_gregset, m68k_store_gregset, m68k_fill_fpregset) + (m68k_store_fpregset, target_regsets) [HAVE_LINUX_REGSETS]: New. + (m68k_breakpoint, m68k_breakpoint_len, m68k_get_pc, m68k_set_pc) + (m68k_breakpoint_at): New. Add to the_low_target. + + * configure.srv (m68*-*-linux*): Set srv_linux_regsets and + srv_linux_thread_db to yes. + +2004-10-20 Joel Brobecker + + * linux-x86-64-low.c (ARCH_SET_GS): Add definition if missing. + (ARCH_SET_FS): Likewise. + (ARCH_GET_FS): Likewise. + (ARCH_GET_GS): Likewise. + +2004-10-16 Daniel Jacobowitz + + * linux-i386-low.c (ps_get_thread_area): New. + * linux-x86-64-low.c (ps_get_thread_area): New. + * linux-low.c: Include . + (linux_kill_one_process): Don't kill the first thread here. + (linux_kill): Kill the first thread here. + (kill_lwp): New function. + (send_sigstop, linux_send_signal): Use it. + * proc-service.c: Clean up #ifdefs. + (fpregset_info): Delete. + (ps_lgetregs): Update and enable implementation. + (ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Remove disabled + implementations. + * remote-utils.c (struct sym_cache, symbol_cache): New. + (input_interrupt): Print a clearer message. + (async_io_enabled): New variable. + (enable_async_io, disable_async_io): Use it. Update comments. + (look_up_one_symbol): Use the symbol cache. + * thread-db.c (thread_db_look_up_symbols): New function. + (thread_db_init): Update comments. Call thread_db_look_up_symbols. + +2004-10-16 Daniel Jacobowitz + + * configure.in: Test for -rdynamic. + * configure: Regenerated. + * Makefile (INTERNAL_LDFLAGS): New. + (gdbserver, gdbreplay): Use it. + +2004-09-02 Andrew Cagney + + * Makefile.in (TAGS): Replace TM_FILE with DEPRECATED_TM_FILE. + +2004-03-23 Daniel Jacobowitz + + * linux-low.c (linux_wait): Clear all_processes list also. + +2004-03-12 Daniel Jacobowitz + + * linux-low.c: Include . Remove extern declaration of + errno. + +2004-03-12 Daniel Jacobowitz + + * gdbreplay.c, server.h, utils.c: Update copyright years. + +2004-03-04 Nathan J. Williams + + * server.c (main): Print child status or termination signal from + variable 'signal', not 'sig'. + +2004-03-04 Nathan J. Williams + + * linux-low.c (linux_read_memory): Change return type to + int. Check for and return error from ptrace(). + * target.c (read_inferior_memory): Change return type to int. Pass + back return status from the_target->read_memory(). + * target.h (struct target_ops): Adapt *read_memory() prototype. + Update comment. + (read_inferior_memory): Adapt prototype. + * server.c (main): Return an error packet if + read_inferior_memory() returns an error. + +2004-03-04 Daniel Jacobowitz + + * Makefile.in (distclean): Remove config.h, stamp-h, and config.log. + Unify with other clean targets. + +2004-02-29 Daniel Jacobowitz + + * server.c (handle_v_cont): Call set_desired_inferior. + +2004-02-29 Daniel Jacobowitz + + * remote-utils.c (prepare_resume_reply): Always supply "thread:". + +2004-02-29 Daniel Jacobowitz + + * linux-low.c (linux_wait): Unblock async I/O. + (linux_resume): Block and enable async I/O. + * remote-utils.c (block_async_io, unblock_async_io): New functions. + * server.h (block_async_io, unblock_async_io): Add prototypes. + +2004-02-29 Daniel Jacobowitz + + * remote-utils.c (remote_open): Print a status notice after + opening a TCP port. + * server.c (attach_inferior): Print a status notice after + attaching. + +2004-02-29 Daniel Jacobowitz + + * linux-arm-low.c (arm_get_pc): Print out stop PC in debug mode. + +2004-02-26 Daniel Jacobowitz + + * remote-utils.c (write_enn): Use "E01" instead of "ENN" for the + error packet. + * server.c, target.h: Update copyright years. + +2004-02-25 Roland McGrath + + * target.h (struct target_ops): New member `read_auxv'. + * server.c (handle_query): Handle qPart:auxv:read: query using that. + * linux-low.c (linux_read_auxv): New function. + (linux_target_ops): Initialize `read_auxv' member to that. + +2004-02-17 Ulrich Weigand + + Committed by Jim Blandy . + + * linux-s390-low.c (s390_num_regs): Update. + (s390_regmap): Remove control registers. Use __s390x__ predefine + instead of GPR_SIZE to distiguish s390 and s390x targets. + +2004-01-31 Daniel Jacobowitz + + * linux-low.c: Update copyright year. + (check_removed_breakpoint): Clear pending_is_breakpoint. + (linux_set_resume_request, linux_queue_one_thread) + (resume_status_pending_p): New functions. + (linux_continue_one_thread): Use process->resume. + (linux_resume): Only resume threads if there are no pending events. + * linux-low.h (struct process_info): Add resume request + pointer. + +2004-01-30 Daniel Jacobowitz + + * regcache.c (new_register_cache): Clear the allocated register + buffer. Suggested by Atsushi Nemoto . + +2003-10-13 Daniel Jacobowitz + + * linux-low.c (linux_resume): Take a struct thread_resume * + argument. + (linux_wait): Update call. + (resume_ptr): New static variable. + (linux_continue_one_thread): Renamed from + linux_continue_one_process. Use resume_ptr. + (linux_resume): Use linux_continue_one_thread. + * server.c (handle_v_cont, handle_v_requests): New functions. + (myresume): New function. + (main): Handle 'v' case. + * target.h (struct thread_resume): New type. + (struct target_ops): Change argument of "resume" to struct + thread_resume *. + (myresume): Delete macro. + +2003-08-08 H.J. Lu + + * Makefile.in (install-only): Create dest dir. Support DESTDIR. + (uninstall): Support DESTDIR. + +Mon Jul 21 20:09:34 UTC 2003 Brendan Conoboy + + * configure.srv: Add xscale*linux copy of arm*linux entry. + +2003-07-24 Daniel Jacobowitz + + * linux-arm-low.c (arm_reinsert_addr): New function. + (the_low_target): Add arm_reinsert_addr. + +2003-07-08 Mark Kettenis + + * mem-break.c: Remove whitespace at end of file. + +2003-06-28 Daniel Jacobowitz + + * configure.in: Check whether we need to prototype strerror. + * server.h: Optionally prototype strerror. + * gdbreplay.c (perror_with_name): Use strerror. + * linux-low.c (linux_attach_lwp): Use strerror. + * utils.c (perror_with_name): Use strerror. + * config.in, configure: Regenerated. + +2003-06-28 Daniel Jacobowitz + + * linux-sh-low.c (sh_regmap): Fix FP register offsets, reported by + SUGIOKA Toshinobu . + +2003-06-20 Daniel Jacobowitz + + * Makefile.in (SFILES): Update. + * low-hppabsd.c, low-lynx.c, low-nbsd.c, low-sim.c, low-sparc.c, + low-sun3.c: Remove files. + +2003-06-17 Daniel Jacobowitz + + * linux-low.c: Move comment to linux_thread_alive where it belonged. + (linux_detach_one_process, linux_detach): New functions. + (linux_target_ops): Add linux_detach. + * server.c (main): Handle 'D' packet. + * target.h (struct target_ops): Add "detach" member. + (detach_inferior): Define. + +2003-06-13 Mark Kettenis + + From Kelley Cook : + * configure.srv: Accept i[34567]86 variants. + +2003-06-05 Daniel Jacobowitz + + * linux-low.c (linux_wait_for_event): Correct comment typos. + (linux_resume_one_process): Call check_removed_breakpoint. + (linux_send_signal): New function. + (linux_target_ops): Add linux_send_signal. + * remote-utils.c (putpkt, input_interrupt): Use send_signal instead + of kill. + * target.h (struct target_ops): Add send_signal. + +2003-05-29 Jim Blandy + + * linux-low.c (usr_store_inferior_registers): Transfer buf in + PTRACE_XFER_TYPE-sized chunks, not int-sized chunks. Otherwise, + if 'int' is smaller than PTRACE_XFER_TYPE, you end up throwing + away part of the register's value. + +2003-03-26 Daniel Jacobowitz + + * linux-low.c (linux_create_inferior): Use __SIGRTMIN. + (linux_wait_for_event, linux_init_signals): Likewise. + +2003-03-17 Daniel Jacobowitz + + * configure.in: Check for stdlib.h. + * configure: Regenerated. + * config.in: Regenerated. + +2003-01-04 Andreas Schwab + + * linux-m68k-low.c (m68k_num_regs): Define to 29 instead of 31. + +2003-01-02 Andrew Cagney + + * Makefile.in: Remove obsolete code. + +2002-11-20 Daniel Jacobowitz + + * linux-s390-low.c (s390_regmap): Check GPR_SIZE instead of + defined(PT_FPR0_HI). + +2002-11-17 Stuart Hughes + + * linux-arm-low.c (arm_num_regs): Increase. + (arm_regmap): Include status register. + +2002-11-17 Daniel Jacobowitz + + * linux-low.c (register_addr): Remove incorrect -1 check. + +2002-08-29 Daniel Jacobowitz + + * linux-low.c (linux_create_inferior): Call setpgid. Return + the new PID. + (unstopped_p, linux_signal_pid): Remove. + (linux_target_ops): Remove linux_signal_pid. + * remote-utils.c (putpkt, input_interrupt): Use signal_pid + global instead of target method. + * target.h (struct target_ops): Remove signal_pid. Update comment + for create_inferior. + * server.c (signal_pid): New variable. + (create_inferior): Set signal_pid. Block SIGTTOU and SIGTTIN in + gdbserver. Set the child to be the foreground process group. + (attach_inferior): Set signal_pid. + +2002-08-23 Daniel Jacobowitz + + * ChangeLog: New file, with entries from gdb/ChangeLog after GDB 5.2. + +2002-08-20 Jim Blandy + + * Makefile.in (LDFLAGS): Allow the configure script to establish a + default for this. + +2002-08-01 Andrew Cagney + + * Makefile.in: Make chill references obsolete. + +2002-07-24 Kevin Buettner + + * configure.in (unistd.h): Add to AC_CHECK_HEADERS list. + * configure: Regenerate. + * config.in: Regenerate. + +2002-07-09 David O'Brien + + * gdbreplay.c (stdlib.h, unistd.h): Conditionaly include. + (perror_with_name, remote_close, remote_open, expect, play): Static. + +2002-07-04 Michal Ludvig + + * linux-x86-64-low.c (x86_64_regmap): Make it an array of + byte offsets instead of an array of indexes. + (x86_64_store_gregset, x86_64_store_fpregset): Parameter made const. + +2002-06-13 Daniel Jacobowitz + + * regcache.c: Add comment. + +2002-06-11 Daniel Jacobowitz + + * thread-db.c: New file. + * proc-service.c: New file. + * acinclude.m4: New file. + * Makefile.in: Add GDBSERVER_LIBS, gdb_proc_service_h, + proc-service.o, and thread-db.o. + (linux-low.o): Add USE_THREAD_DB. + * acconfig.h: Add HAVE_PRGREGSET_T, HAVE_PRFPREGSET_T, + HAVE_LWPID_T, HAVE_PSADDR_T, and PRFPREGSET_T_BROKEN. + * aclocal.m4: Regenerated. + * config.in: Regenerated. + * configure: Regenerated. + * configure.in: Check for proc_service.h, sys/procfs.h, + thread_db.h, and linux/elf.h headrs. + Check for lwpid_t, psaddr_t, prgregset_t, prfpregset_t, and + PRFPREGSET_T_BROKEN. Introduce srv_thread_depfiles and USE_THREAD_DB. + Check for -lthread_db and thread support. + * configure.srv: Enable thread_db support for ARM, i386, MIPS, + PowerPC, and SuperH. + * i387-fp.c: Constify arguments. + * i387-fp.h: Likewise. + * inferiors.c: (struct thread_info): Renamed from + `struct inferior_info'. Remove PID member. Use generic inferior + list header. All uses updated. + (inferiors, signal_pid): Removed. + (all_threads): New variable. + (get_thread): Define. + (add_inferior_to_list): New function. + (for_each_inferior): New function. + (change_inferior_id): New function. + (add_inferior): Removed. + (remove_inferior): New function. + (add_thread): New function. + (free_one_thread): New function. + (remove_thread): New function. + (clear_inferiors): Use for_each_inferior and free_one_thread. + (find_inferior): New function. + (find_inferior_id): New function. + (inferior_target_data): Update argument type. + (set_inferior_target_data): Likewise. + (inferior_regcache_data): Likewise. + (set_inferior_regcache_data): Likewise. + * linux-low.c (linux_bp_reinsert): Remove. + (all_processes, stopping_threads, using_thrads) + (struct pending_signals, debug_threads, pid_of): New. + (inferior_pid): Replace with macro. + (struct inferior_linux_data): Remove. + (get_stop_pc, add_process): New functions. + (linux_create_inferior): Restore SIGRTMIN+1 before calling exec. + Use add_process and add_thread. + (linux_attach_lwp): New function, based on old linux_attach. Use + add_process and add_thread. Set stop_expected for new threads. + (linux_attach): New function. + (linux_kill_one_process): New function. + (linux_kill): Kill all LWPs. + (linux_thread_alive): Use find_inferior_id. + (check_removed_breakpoints, status_pending_p): New functions. + (linux_wait_for_process): Renamed from linux_wait_for_one_inferior. + Update. Use WNOHANG. Wait for cloned processes also. Update process + struct for the found process. + (linux_wait_for_event): New function. + (linux_wait): Use it. Support LWPs. + (send_sigstop, wait_for_sigstop, stop_all_processes) + (linux_resume_one_process, linux_continue_one_process): New functions. + (linux_resume): Support LWPs. + (REGISTER_RAW_SIZE): Remove. + (fetch_register): Use register_size instead. Call supply_register. + (usr_store_inferior_registers): Likewise. Call collect_register. + Fix recursive case. + (regsets_fetch_inferior_registers): Improve error message. + (regsets_store_inferior_registers): Add debugging. + (linux_look_up_symbols): Call thread_db_init if USE_THREAD_DB. + (unstopped_p, linux_signal_pid): New functions. + (linux_target_ops): Add linux_signal_pid. + (linux_init_signals): New function. + (initialize_low): Call it. Initialize using_threads. + * regcache.c (inferior_regcache_data): Add valid + flag. + (get_regcache): Fetch registers lazily. Add fetch argument + and update all callers. + (regcache_invalidate_one, regcache_invalidate): New + functions. + (new_register_cache): Renamed from create_register_cache. + Return the new regcache. + (free_register_cache): Change argument to a void *. + (registers_to_string, registers_from_string): Call get_regcache + with fetch flag set. + (register_data): Make static. Pass fetch flag to get_regcache. + (supply_register): Call get_regcache with fetch flag clear. + (collect_register): Call get_regcache with fetch flag set. + (collect_register_as_string): New function. + * regcache.h: Update. + * remote-utils.c (putpkt): Flush after debug output and use + stderr. + Handle input interrupts while waiting for an ACK. + (input_interrupt): Use signal_pid method. + (getpkt): Flush after debug output and use stderr. + (outreg): Use collect_register_as_string. + (new_thread_notify, dead_thread_notify): New functions. + (prepare_resume_reply): Check using_threads. Set thread_from_wait + and general_thread. + (look_up_one_symbol): Flush after debug output. + * server.c (step_thread, server_waiting): New variables. + (start_inferior): Don't use signal_pid. Update call to mywait. + (attach_inferior): Update call to mywait. + (handle_query): Handle qfThreadInfo and qsThreadInfo. + (main): Don't fetch/store registers explicitly. Use + set_desired_inferior. Support proposed ``Hs'' packet. Update + calls to mywait. + * server.h: Update. + (struct inferior_list, struct_inferior_list_entry): New. + * target.c (set_desired_inferior): New. + (write_inferior_memory): Constify. + (mywait): New function. + * target.h: Update. + (struct target_ops): New signal_pid method. + (mywait): Removed macro, added prototype. + + * linux-low.h (regset_func): Removed. + (regset_fill_func, regset_store_func): New. + (enum regset_type): New. + (struct regset_info): Add type field. Use new operation types. + (struct linux_target_ops): stop_pc renamed to get_pc. + Add decr_pc_after_break and breakpoint_at. + (get_process, get_thread_proess, get_process_thread) + (strut process_info, all_processes, linux_attach_lwp) + (thread_db_init): New. + + * linux-arm-low.c (arm_get_pc, arm_set_pc, + arm_breakpoint, arm_breakpoint_len, arm_breakpoint_at): New. + (the_low_target): Add new members. + * linux-i386-low.c (i386_store_gregset, i386_store_fpregset) + (i386_store_fpxregset): Constify. + (target_regsets): Add new kind identifier. + (i386_get_pc): Renamed from i386_stop_pc. Simplify. + (i386_set_pc): Add debugging. + (i386_breakpoint_at): New function. + (the_low_target): Add new members. + * linux-mips-low.c (mips_get_pc, mips_set_pc) + (mips_breakpoint, mips_breakpoint_len, mips_reinsert_addr) + (mips_breakpoint_at): New. + (the_low_target): Add new members. + * linux-ppc-low.c (ppc_get_pc, ppc_set_pc) + (ppc_breakpoint, ppc_breakpoint_len, ppc_breakpoint_at): New. + (the_low_target): Add new members. + * linux-sh-low.c (sh_get_pc, sh_set_pc) + (sh_breakpoint, sh_breakpoint_len, sh_breakpoint_at): New. + (the_low_target): Add new members. + * linux-x86-64-low.c (target_regsets): Add new kind + identifier. + +2002-05-15 Daniel Jacobowitz + + From Martin Pool : + * server.c (gdbserver_usage): New function. + (main): Call it. + +2002-05-14 Daniel Jacobowitz + + * mem-break.c (reinsert_breakpoint_by_bp): Correct typo + stop_at -> stop_pc. + +2002-05-04 Andrew Cagney + + * Makefile.in: Remove obsolete code. + +2002-04-24 Michal Ludvig + + * linux-low.c (regsets_fetch_inferior_registers), + (regsets_store_inferior_registers): Removed cast to int from + ptrace() calls. + * regcache.h: Added declaration of struct inferior_info. + +2002-04-20 Daniel Jacobowitz + + * inferiors.c (struct inferior_info): Add regcache_data. + (add_inferior): Call create_register_cache. + (clear_inferiors): Call free_register_cache. + (inferior_regcache_data, set_inferior_regcache_data): New functions. + * regcache.c (struct inferior_regcache_data): New. + (registers): Remove. + (get_regcache): New function. + (create_register_cache, free_register_cache): New functions. + (set_register_cache): Don't initialize the register cache here. + (registers_to_string, registers_from_string, register_data): Call + get_regcache. + * regcache.h: Add prototypes. + * server.h: Likewise. + +2002-04-20 Daniel Jacobowitz + + * mem-break.c: New file. + * mem-break.h: New file. + * Makefile.in: Add mem-break.o rule; update server.h + dependencies. + * inferiors.c (struct inferior_info): Add target_data + member. + (clear_inferiors): Free target_data member if set. + (inferior_target_data, set_inferior_target_data): New functions. + * linux-i386-low.c (i386_breakpoint, i386_breakpoint_len) + (i386_stop_pc, i386_set_pc): New. Add to the_low_target. + * linux-low.c (linux_bp_reinsert): New variable. + (struct inferior_linux_data): New. + (linux_create_inferior): Use set_inferior_target_data. + (linux_attach): Likewise. Call add_inferior. + (linux_wait_for_one_inferior): New function. + (linux_wait): Call it. + (linux_write_memory): Add const. + (initialize_low): Call set_breakpoint_data. + * linux-low.h (struct linux_target_ops): Add breakpoint + handling members. + * server.c (attach_inferior): Remove extra add_inferior + call. + * server.h: Include mem-break.h. Update inferior.c + prototypes. + * target.c (read_inferior_memory) + (write_inferior_memory): New functions. + * target.h (read_inferior_memory) + (write_inferior_memory): Change macros to prototypes. + (struct target_ops): Update comments. Add const to write_memory + definition. + +2002-04-11 Daniel Jacobowitz + + * linux-low.c (usr_store_inferior_registers): Support + registers which are allowed to fail to store. + * linux-low.h (linux_target_ops): Likewise. + * linux-ppc-low.c (ppc_regmap): Support FPSCR. + (ppc_cannot_store_register): FPSCR may not be storable. + +2002-04-09 Daniel Jacobowitz + + * server.h: Include if HAVE_STRING_H. + * ChangeLog: Correct paths in last ChangeLog entry. + +2002-04-09 Daniel Jacobowitz + + * linux-low.h: Remove obsolete prototypes. + (struct linux_target_ops): New. + (extern the_low_target): New. + * linux-low.c (num_regs, regmap): Remove declarations. + (register_addr): Use the_low_target explicitly. + (fetch_register): Likewise. + (usr_fetch_inferior_registers): Likewise. + (usr_store_inferior_registers): Likewise. + * linux-arm-low.c (num_regs): Remove. + (arm_num_regs): Define. + (arm_regmap): Renamed from regmap, made static. + (arm_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (arm_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-i386-low.c (num_regs): Remove. + (i386_num_regs): Define. + (i386_regmap): Renamed from regmap, made static. + (i386_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (i386_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-ia64-low.c (num_regs): Remove. + (ia64_num_regs): Define. + (ia64_regmap): Renamed from regmap, made static. + (ia64_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (ia64_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-m68k-low.c (num_regs): Remove. + (m68k_num_regs): Define. + (m68k_regmap): Renamed from regmap, made static. + (m68k_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (m68k_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-mips-low.c (num_regs): Remove. + (mips_num_regs): Define. + (mips_regmap): Renamed from regmap, made static. + (mips_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (mips_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-ppc-low.c (num_regs): Remove. + (ppc_num_regs): Define. + (ppc_regmap): Renamed from regmap, made static. + (ppc_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (ppc_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-s390-low.c (num_regs): Remove. + (s390_num_regs): Define. + (s390_regmap): Renamed from regmap, made static. + (s390_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (s390_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-sh-low.c (num_regs): Remove. + (sh_num_regs): Define. + (sh_regmap): Renamed from regmap, made static. + (sh_cannot_fetch_register): Renamed from cannot_fetch_register, + made static. + (sh_cannot_store_register): Renamed from cannot_store_register, + made static. + (the_low_target): New. + * linux-x86-64-low.c (x86_64_regmap): Renamed from regmap. + (the_low_target): New. + +2002-04-09 Daniel Jacobowitz + + * Makefile.in: Add stamp-h target. + * configure.in: Create stamp-h. + * configure: Regenerated. + +2002-04-09 Daniel Jacobowitz + + * inferiors.c: New file. + * target.c: New file. + * target.h: New file. + * Makefile.in: Add target.o and inferiors.o. Update + dependencies. + * linux-low.c (inferior_pid): New static variable, + moved from server.c. + (linux_create_inferior): Renamed from create_inferior. + Call add_inferior. Return 0 on success instead of a PID. + (linux_attach): Renamed from myattach. + (linux_kill): Renamed from kill_inferior. Call clear_inferiors (). + (linux_thread_alive): Renamed from mythread_alive. + (linux_wait): Renamed from mywait. Call clear_inferiors () if the + child dies. + (linux_resume): Renamed from myresume. Add missing ``return 0''. + (regsets_store_inferior_registers): Correct error message. + Add missing ``return 0''. + (linux_fetch_registers): Renamed from fetch_inferior_registers. + (linux_store_registers): Renamed from store_inferior_registers. + (linux_read_memory): Renamed from read_inferior_memory. + (linux_write_memory): Renamed from write_inferior_memory. + (linux_target_ops): New structure. + (initialize_low): Call set_target_ops (). + * remote-utils.c (unhexify): New function. + (hexify): New function. + (input_interrupt): Send signals to ``signal_pid''. + * server.c (inferior_pid): Remove. + (start_inferior): Update create_inferior call. + (attach_inferior): Call add_inferior. + (handle_query): New function. + (main): Call handle_query for `q' packets. + * server.h: Include "target.h". Remove obsolete prototypes. + Add prototypes for "inferiors.c", "target.c", hexify, and unhexify. + +2002-04-09 Daniel Jacobowitz + + * Makefile.in: Add WARN_CFLAGS. Update configury + dependencies. + * configure.in: Check for + * configure: Regenerate. + * config.in: Regenerate. + * gdbreplay.c: Include needed system headers. + (remote_open): Remove strchr prototype. + * linux-low.h: Correct #ifdef to HAVE_LINUX_USRREGS. + * regcache.c (supply_register): Change buf argument to const void *. + (supply_register_by_name): Likewise. + (collect_register): Change buf argument to void *. + (collect_register_by_name): Likewise. + * regcache.h: Add missing prototypes. + * remote-utils.c: Include for inet_ntoa. + * server.c (handle_query): New function. + (attached): New static variable, moved out of main. + (main): Quiet longjmp clobber warnings. + * server.h: Add ATTR_NORETURN and ATTR_FORMAT. Update prototypes. + * utils.c (error): Remove NORETURN. + (fatal): Likewise.
ChangeLog Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: server.c =================================================================== --- server.c (nonexistent) +++ server.c (revision 816) @@ -0,0 +1,1541 @@ +/* Main code for remote server for GDB. + Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, + 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif +#if HAVE_SYS_WAIT_H +#include +#endif + +unsigned long cont_thread; +unsigned long general_thread; +unsigned long step_thread; +unsigned long thread_from_wait; +unsigned long old_thread_from_wait; +int server_waiting; + +static int extended_protocol; +static int attached; +static int response_needed; +static int exit_requested; + +static char **program_argv; + +/* Enable miscellaneous debugging output. The name is historical - it + was originally used to debug LinuxThreads support. */ +int debug_threads; + +int pass_signals[TARGET_SIGNAL_LAST]; + +jmp_buf toplevel; + +/* The PID of the originally created or attached inferior. Used to + send signals to the process when GDB sends us an asynchronous interrupt + (user hitting Control-C in the client), and to wait for the child to exit + when no longer debugging it. */ + +unsigned long signal_pid; + +#ifdef SIGTTOU +/* A file descriptor for the controlling terminal. */ +int terminal_fd; + +/* TERMINAL_FD's original foreground group. */ +pid_t old_foreground_pgrp; + +/* Hand back terminal ownership to the original foreground group. */ + +static void +restore_old_foreground_pgrp (void) +{ + tcsetpgrp (terminal_fd, old_foreground_pgrp); +} +#endif + +static int +target_running (void) +{ + return all_threads.head != NULL; +} + +static int +start_inferior (char *argv[], char *statusptr) +{ + attached = 0; + +#ifdef SIGTTOU + signal (SIGTTOU, SIG_DFL); + signal (SIGTTIN, SIG_DFL); +#endif + + signal_pid = create_inferior (argv[0], argv); + + /* FIXME: we don't actually know at this point that the create + actually succeeded. We won't know that until we wait. */ + fprintf (stderr, "Process %s created; pid = %ld\n", argv[0], + signal_pid); + fflush (stderr); + +#ifdef SIGTTOU + signal (SIGTTOU, SIG_IGN); + signal (SIGTTIN, SIG_IGN); + terminal_fd = fileno (stderr); + old_foreground_pgrp = tcgetpgrp (terminal_fd); + tcsetpgrp (terminal_fd, signal_pid); + atexit (restore_old_foreground_pgrp); +#endif + + /* Wait till we are at 1st instruction in program, return signal + number (assuming success). */ + return mywait (statusptr, 0); +} + +static int +attach_inferior (int pid, char *statusptr, int *sigptr) +{ + /* myattach should return -1 if attaching is unsupported, + 0 if it succeeded, and call error() otherwise. */ + + if (myattach (pid) != 0) + return -1; + + attached = 1; + + fprintf (stderr, "Attached; pid = %d\n", pid); + fflush (stderr); + + /* FIXME - It may be that we should get the SIGNAL_PID from the + attach function, so that it can be the main thread instead of + whichever we were told to attach to. */ + signal_pid = pid; + + *sigptr = mywait (statusptr, 0); + + /* GDB knows to ignore the first SIGSTOP after attaching to a running + process using the "attach" command, but this is different; it's + just using "target remote". Pretend it's just starting up. */ + if (*statusptr == 'T' && *sigptr == TARGET_SIGNAL_STOP) + *sigptr = TARGET_SIGNAL_TRAP; + + return 0; +} + +extern int remote_debug; + +/* Decode a qXfer read request. Return 0 if everything looks OK, + or -1 otherwise. */ + +static int +decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len) +{ + /* Extract and NUL-terminate the annex. */ + *annex = buf; + while (*buf && *buf != ':') + buf++; + if (*buf == '\0') + return -1; + *buf++ = 0; + + /* After the read marker and annex, qXfer looks like a + traditional 'm' packet. */ + decode_m_packet (buf, ofs, len); + + return 0; +} + +/* Write the response to a successful qXfer read. Returns the + length of the (binary) data stored in BUF, corresponding + to as much of DATA/LEN as we could fit. IS_MORE controls + the first character of the response. */ +static int +write_qxfer_response (char *buf, const void *data, int len, int is_more) +{ + int out_len; + + if (is_more) + buf[0] = 'm'; + else + buf[0] = 'l'; + + return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len, + PBUFSIZ - 2) + 1; +} + +/* Handle all of the extended 'Q' packets. */ +void +handle_general_set (char *own_buf) +{ + if (strncmp ("QPassSignals:", own_buf, strlen ("QPassSignals:")) == 0) + { + int numsigs = (int) TARGET_SIGNAL_LAST, i; + const char *p = own_buf + strlen ("QPassSignals:"); + CORE_ADDR cursig; + + p = decode_address_to_semicolon (&cursig, p); + for (i = 0; i < numsigs; i++) + { + if (i == cursig) + { + pass_signals[i] = 1; + if (*p == '\0') + /* Keep looping, to clear the remaining signals. */ + cursig = -1; + else + p = decode_address_to_semicolon (&cursig, p); + } + else + pass_signals[i] = 0; + } + strcpy (own_buf, "OK"); + return; + } + + /* Otherwise we didn't know what packet it was. Say we didn't + understand it. */ + own_buf[0] = 0; +} + +static const char * +get_features_xml (const char *annex) +{ + static int features_supported = -1; + static char *document; + +#ifdef USE_XML + extern const char *const xml_builtin[][2]; + int i; + + /* Look for the annex. */ + for (i = 0; xml_builtin[i][0] != NULL; i++) + if (strcmp (annex, xml_builtin[i][0]) == 0) + break; + + if (xml_builtin[i][0] != NULL) + return xml_builtin[i][1]; +#endif + + if (strcmp (annex, "target.xml") != 0) + return NULL; + + if (features_supported == -1) + { + const char *arch = NULL; + if (the_target->arch_string != NULL) + arch = (*the_target->arch_string) (); + + if (arch == NULL) + features_supported = 0; + else + { + features_supported = 1; + document = malloc (64 + strlen (arch)); + snprintf (document, 64 + strlen (arch), + "%s", + arch); + } + } + + return document; +} + +void +monitor_show_help (void) +{ + monitor_output ("The following monitor commands are supported:\n"); + monitor_output (" set debug <0|1>\n"); + monitor_output (" Enable general debugging messages\n"); + monitor_output (" set remote-debug <0|1>\n"); + monitor_output (" Enable remote protocol debugging messages\n"); + monitor_output (" exit\n"); + monitor_output (" Quit GDBserver\n"); +} + +#define require_running(BUF) \ + if (!target_running ()) \ + { \ + write_enn (BUF); \ + return; \ + } + +/* Handle all of the extended 'q' packets. */ +void +handle_query (char *own_buf, int packet_len, int *new_packet_len_p) +{ + static struct inferior_list_entry *thread_ptr; + + /* Reply the current thread id. */ + if (strcmp ("qC", own_buf) == 0) + { + require_running (own_buf); + thread_ptr = all_threads.head; + sprintf (own_buf, "QC%x", + thread_to_gdb_id ((struct thread_info *)thread_ptr)); + return; + } + + if (strcmp ("qSymbol::", own_buf) == 0) + { + if (target_running () && the_target->look_up_symbols != NULL) + (*the_target->look_up_symbols) (); + + strcpy (own_buf, "OK"); + return; + } + + if (strcmp ("qfThreadInfo", own_buf) == 0) + { + require_running (own_buf); + thread_ptr = all_threads.head; + sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); + thread_ptr = thread_ptr->next; + return; + } + + if (strcmp ("qsThreadInfo", own_buf) == 0) + { + require_running (own_buf); + if (thread_ptr != NULL) + { + sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr)); + thread_ptr = thread_ptr->next; + return; + } + else + { + sprintf (own_buf, "l"); + return; + } + } + + if (the_target->read_offsets != NULL + && strcmp ("qOffsets", own_buf) == 0) + { + CORE_ADDR text, data; + + require_running (own_buf); + if (the_target->read_offsets (&text, &data)) + sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX", + (long)text, (long)data, (long)data); + else + write_enn (own_buf); + + return; + } + + if (the_target->qxfer_spu != NULL + && strncmp ("qXfer:spu:read:", own_buf, 15) == 0) + { + char *annex; + int n; + unsigned int len; + CORE_ADDR ofs; + unsigned char *spu_buf; + + require_running (own_buf); + strcpy (own_buf, "E00"); + if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0) + return; + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + spu_buf = malloc (len + 1); + if (!spu_buf) + return; + + n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1); + if (n < 0) + write_enn (own_buf); + else if (n > len) + *new_packet_len_p = write_qxfer_response + (own_buf, spu_buf, len, 1); + else + *new_packet_len_p = write_qxfer_response + (own_buf, spu_buf, n, 0); + + free (spu_buf); + return; + } + + if (the_target->qxfer_spu != NULL + && strncmp ("qXfer:spu:write:", own_buf, 16) == 0) + { + char *annex; + int n; + unsigned int len; + CORE_ADDR ofs; + unsigned char *spu_buf; + + require_running (own_buf); + strcpy (own_buf, "E00"); + spu_buf = malloc (packet_len - 15); + if (!spu_buf) + return; + if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex, + &ofs, &len, spu_buf) < 0) + { + free (spu_buf); + return; + } + + n = (*the_target->qxfer_spu) + (annex, NULL, (unsigned const char *)spu_buf, ofs, len); + if (n < 0) + write_enn (own_buf); + else + sprintf (own_buf, "%x", n); + + free (spu_buf); + return; + } + + if (the_target->read_auxv != NULL + && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0) + { + unsigned char *data; + int n; + CORE_ADDR ofs; + unsigned int len; + char *annex; + + require_running (own_buf); + + /* Reject any annex; grab the offset and length. */ + if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0 + || annex[0] != '\0') + { + strcpy (own_buf, "E00"); + return; + } + + /* Read one extra byte, as an indicator of whether there is + more. */ + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + data = malloc (len + 1); + n = (*the_target->read_auxv) (ofs, data, len + 1); + if (n < 0) + write_enn (own_buf); + else if (n > len) + *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1); + else + *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0); + + free (data); + + return; + } + + if (strncmp ("qXfer:features:read:", own_buf, 20) == 0) + { + CORE_ADDR ofs; + unsigned int len, total_len; + const char *document; + char *annex; + + require_running (own_buf); + + /* Check for support. */ + document = get_features_xml ("target.xml"); + if (document == NULL) + { + own_buf[0] = '\0'; + return; + } + + /* Grab the annex, offset, and length. */ + if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0) + { + strcpy (own_buf, "E00"); + return; + } + + /* Now grab the correct annex. */ + document = get_features_xml (annex); + if (document == NULL) + { + strcpy (own_buf, "E00"); + return; + } + + total_len = strlen (document); + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + + if (ofs > total_len) + write_enn (own_buf); + else if (len < total_len - ofs) + *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, + len, 1); + else + *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, + total_len - ofs, 0); + + return; + } + + if (strncmp ("qXfer:libraries:read:", own_buf, 21) == 0) + { + CORE_ADDR ofs; + unsigned int len, total_len; + char *document, *p; + struct inferior_list_entry *dll_ptr; + char *annex; + + require_running (own_buf); + + /* Reject any annex; grab the offset and length. */ + if (decode_xfer_read (own_buf + 21, &annex, &ofs, &len) < 0 + || annex[0] != '\0') + { + strcpy (own_buf, "E00"); + return; + } + + /* Over-estimate the necessary memory. Assume that every character + in the library name must be escaped. */ + total_len = 64; + for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) + total_len += 128 + 6 * strlen (((struct dll_info *) dll_ptr)->name); + + document = malloc (total_len); + strcpy (document, "\n"); + p = document + strlen (document); + + for (dll_ptr = all_dlls.head; dll_ptr != NULL; dll_ptr = dll_ptr->next) + { + struct dll_info *dll = (struct dll_info *) dll_ptr; + char *name; + + strcpy (p, " name); + strcpy (p, name); + free (name); + p = p + strlen (p); + strcpy (p, "\">base_addr); + p = p + strlen (p); + strcpy (p, "\"/>\n"); + p = p + strlen (p); + } + + strcpy (p, "\n"); + + total_len = strlen (document); + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + + if (ofs > total_len) + write_enn (own_buf); + else if (len < total_len - ofs) + *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, + len, 1); + else + *new_packet_len_p = write_qxfer_response (own_buf, document + ofs, + total_len - ofs, 0); + + free (document); + return; + } + + /* Protocol features query. */ + if (strncmp ("qSupported", own_buf, 10) == 0 + && (own_buf[10] == ':' || own_buf[10] == '\0')) + { + sprintf (own_buf, "PacketSize=%x;QPassSignals+", PBUFSIZ - 1); + + /* We do not have any hook to indicate whether the target backend + supports qXfer:libraries:read, so always report it. */ + strcat (own_buf, ";qXfer:libraries:read+"); + + if (the_target->read_auxv != NULL) + strcat (own_buf, ";qXfer:auxv:read+"); + + if (the_target->qxfer_spu != NULL) + strcat (own_buf, ";qXfer:spu:read+;qXfer:spu:write+"); + + if (get_features_xml ("target.xml") != NULL) + strcat (own_buf, ";qXfer:features:read+"); + + return; + } + + /* Thread-local storage support. */ + if (the_target->get_tls_address != NULL + && strncmp ("qGetTLSAddr:", own_buf, 12) == 0) + { + char *p = own_buf + 12; + CORE_ADDR parts[3], address = 0; + int i, err; + + require_running (own_buf); + + for (i = 0; i < 3; i++) + { + char *p2; + int len; + + if (p == NULL) + break; + + p2 = strchr (p, ','); + if (p2) + { + len = p2 - p; + p2++; + } + else + { + len = strlen (p); + p2 = NULL; + } + + decode_address (&parts[i], p, len); + p = p2; + } + + if (p != NULL || i < 3) + err = 1; + else + { + struct thread_info *thread = gdb_id_to_thread (parts[0]); + + if (thread == NULL) + err = 2; + else + err = the_target->get_tls_address (thread, parts[1], parts[2], + &address); + } + + if (err == 0) + { + sprintf (own_buf, "%llx", address); + return; + } + else if (err > 0) + { + write_enn (own_buf); + return; + } + + /* Otherwise, pretend we do not understand this packet. */ + } + + /* Handle "monitor" commands. */ + if (strncmp ("qRcmd,", own_buf, 6) == 0) + { + char *mon = malloc (PBUFSIZ); + int len = strlen (own_buf + 6); + + if ((len % 2) != 0 || unhexify (mon, own_buf + 6, len / 2) != len / 2) + { + write_enn (own_buf); + free (mon); + return; + } + mon[len / 2] = '\0'; + + write_ok (own_buf); + + if (strcmp (mon, "set debug 1") == 0) + { + debug_threads = 1; + monitor_output ("Debug output enabled.\n"); + } + else if (strcmp (mon, "set debug 0") == 0) + { + debug_threads = 0; + monitor_output ("Debug output disabled.\n"); + } + else if (strcmp (mon, "set remote-debug 1") == 0) + { + remote_debug = 1; + monitor_output ("Protocol debug output enabled.\n"); + } + else if (strcmp (mon, "set remote-debug 0") == 0) + { + remote_debug = 0; + monitor_output ("Protocol debug output disabled.\n"); + } + else if (strcmp (mon, "help") == 0) + monitor_show_help (); + else if (strcmp (mon, "exit") == 0) + exit_requested = 1; + else + { + monitor_output ("Unknown monitor command.\n\n"); + monitor_show_help (); + write_enn (own_buf); + } + + free (mon); + return; + } + + /* Otherwise we didn't know what packet it was. Say we didn't + understand it. */ + own_buf[0] = 0; +} + +/* Parse vCont packets. */ +void +handle_v_cont (char *own_buf, char *status, int *signal) +{ + char *p, *q; + int n = 0, i = 0; + struct thread_resume *resume_info, default_action; + + /* Count the number of semicolons in the packet. There should be one + for every action. */ + p = &own_buf[5]; + while (p) + { + n++; + p++; + p = strchr (p, ';'); + } + /* Allocate room for one extra action, for the default remain-stopped + behavior; if no default action is in the list, we'll need the extra + slot. */ + resume_info = malloc ((n + 1) * sizeof (resume_info[0])); + + default_action.thread = -1; + default_action.leave_stopped = 1; + default_action.step = 0; + default_action.sig = 0; + + p = &own_buf[5]; + i = 0; + while (*p) + { + p++; + + resume_info[i].leave_stopped = 0; + + if (p[0] == 's' || p[0] == 'S') + resume_info[i].step = 1; + else if (p[0] == 'c' || p[0] == 'C') + resume_info[i].step = 0; + else + goto err; + + if (p[0] == 'S' || p[0] == 'C') + { + int sig; + sig = strtol (p + 1, &q, 16); + if (p == q) + goto err; + p = q; + + if (!target_signal_to_host_p (sig)) + goto err; + resume_info[i].sig = target_signal_to_host (sig); + } + else + { + resume_info[i].sig = 0; + p = p + 1; + } + + if (p[0] == 0) + { + resume_info[i].thread = -1; + default_action = resume_info[i]; + + /* Note: we don't increment i here, we'll overwrite this entry + the next time through. */ + } + else if (p[0] == ':') + { + unsigned int gdb_id = strtoul (p + 1, &q, 16); + unsigned long thread_id; + + if (p == q) + goto err; + p = q; + if (p[0] != ';' && p[0] != 0) + goto err; + + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id) + resume_info[i].thread = thread_id; + else + goto err; + + i++; + } + } + + resume_info[i] = default_action; + + /* Still used in occasional places in the backend. */ + if (n == 1 && resume_info[0].thread != -1) + cont_thread = resume_info[0].thread; + else + cont_thread = -1; + set_desired_inferior (0); + + enable_async_io (); + (*the_target->resume) (resume_info); + + free (resume_info); + + *signal = mywait (status, 1); + prepare_resume_reply (own_buf, *status, *signal); + disable_async_io (); + return; + +err: + write_enn (own_buf); + free (resume_info); + return; +} + +/* Attach to a new program. Return 1 if successful, 0 if failure. */ +int +handle_v_attach (char *own_buf, char *status, int *signal) +{ + int pid; + + pid = strtol (own_buf + 8, NULL, 16); + if (pid != 0 && attach_inferior (pid, status, signal) == 0) + { + prepare_resume_reply (own_buf, *status, *signal); + return 1; + } + else + { + write_enn (own_buf); + return 0; + } +} + +/* Run a new program. Return 1 if successful, 0 if failure. */ +static int +handle_v_run (char *own_buf, char *status, int *signal) +{ + char *p, **pp, *next_p, **new_argv; + int i, new_argc; + + new_argc = 0; + for (p = own_buf + strlen ("vRun;"); p && *p; p = strchr (p, ';')) + { + p++; + new_argc++; + } + + new_argv = malloc ((new_argc + 2) * sizeof (char *)); + i = 0; + for (p = own_buf + strlen ("vRun;"); *p; p = next_p) + { + next_p = strchr (p, ';'); + if (next_p == NULL) + next_p = p + strlen (p); + + if (i == 0 && p == next_p) + new_argv[i] = NULL; + else + { + new_argv[i] = malloc (1 + (next_p - p) / 2); + unhexify (new_argv[i], p, (next_p - p) / 2); + new_argv[i][(next_p - p) / 2] = '\0'; + } + + if (*next_p) + next_p++; + i++; + } + new_argv[i] = NULL; + + if (new_argv[0] == NULL) + { + if (program_argv == NULL) + { + write_enn (own_buf); + return 0; + } + + new_argv[0] = strdup (program_argv[0]); + } + + /* Free the old argv. */ + if (program_argv) + { + for (pp = program_argv; *pp != NULL; pp++) + free (*pp); + free (program_argv); + } + program_argv = new_argv; + + *signal = start_inferior (program_argv, status); + if (*status == 'T') + { + prepare_resume_reply (own_buf, *status, *signal); + return 1; + } + else + { + write_enn (own_buf); + return 0; + } +} + +/* Handle all of the extended 'v' packets. */ +void +handle_v_requests (char *own_buf, char *status, int *signal, + int packet_len, int *new_packet_len) +{ + if (strncmp (own_buf, "vCont;", 6) == 0) + { + require_running (own_buf); + handle_v_cont (own_buf, status, signal); + return; + } + + if (strncmp (own_buf, "vCont?", 6) == 0) + { + strcpy (own_buf, "vCont;c;C;s;S"); + return; + } + + if (strncmp (own_buf, "vFile:", 6) == 0 + && handle_vFile (own_buf, packet_len, new_packet_len)) + return; + + if (strncmp (own_buf, "vAttach;", 8) == 0) + { + if (target_running ()) + { + fprintf (stderr, "Already debugging a process\n"); + write_enn (own_buf); + return; + } + handle_v_attach (own_buf, status, signal); + return; + } + + if (strncmp (own_buf, "vRun;", 5) == 0) + { + if (target_running ()) + { + fprintf (stderr, "Already debugging a process\n"); + write_enn (own_buf); + return; + } + handle_v_run (own_buf, status, signal); + return; + } + + /* Otherwise we didn't know what packet it was. Say we didn't + understand it. */ + own_buf[0] = 0; + return; +} + +void +myresume (char *own_buf, int step, int *signalp, char *statusp) +{ + struct thread_resume resume_info[2]; + int n = 0; + int sig = *signalp; + + set_desired_inferior (0); + + if (step || sig || (cont_thread != 0 && cont_thread != -1)) + { + resume_info[0].thread + = ((struct inferior_list_entry *) current_inferior)->id; + resume_info[0].step = step; + resume_info[0].sig = sig; + resume_info[0].leave_stopped = 0; + n++; + } + resume_info[n].thread = -1; + resume_info[n].step = 0; + resume_info[n].sig = 0; + resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1); + + enable_async_io (); + (*the_target->resume) (resume_info); + *signalp = mywait (statusp, 1); + prepare_resume_reply (own_buf, *statusp, *signalp); + disable_async_io (); +} + +static void +gdbserver_version (void) +{ + printf ("GNU gdbserver %s\n" + "Copyright (C) 2007 Free Software Foundation, Inc.\n" + "gdbserver is free software, covered by the GNU General Public License.\n" + "This gdbserver was configured as \"%s\"\n", + version, host_name); +} + +static void +gdbserver_usage (void) +{ + printf ("Usage:\tgdbserver [OPTIONS] COMM PROG [ARGS ...]\n" + "\tgdbserver [OPTIONS] --attach COMM PID\n" + "\tgdbserver [OPTIONS] --multi COMM\n" + "\n" + "COMM may either be a tty device (for serial debugging), or \n" + "HOST:PORT to listen for a TCP connection.\n" + "\n" + "Options:\n" + " --debug\t\tEnable debugging output.\n"); +} + +#undef require_running +#define require_running(BUF) \ + if (!target_running ()) \ + { \ + write_enn (BUF); \ + break; \ + } + +int +main (int argc, char *argv[]) +{ + char ch, status, *own_buf; + unsigned char *mem_buf; + int i = 0; + int signal; + unsigned int len; + CORE_ADDR mem_addr; + int bad_attach; + int pid; + char *arg_end, *port; + char **next_arg = &argv[1]; + int multi_mode = 0; + int attach = 0; + int was_running; + + while (*next_arg != NULL && **next_arg == '-') + { + if (strcmp (*next_arg, "--version") == 0) + { + gdbserver_version (); + exit (0); + } + else if (strcmp (*next_arg, "--help") == 0) + { + gdbserver_usage (); + exit (0); + } + else if (strcmp (*next_arg, "--attach") == 0) + attach = 1; + else if (strcmp (*next_arg, "--multi") == 0) + multi_mode = 1; + else if (strcmp (*next_arg, "--debug") == 0) + debug_threads = 1; + else + { + fprintf (stderr, "Unknown argument: %s\n", *next_arg); + exit (1); + } + + next_arg++; + continue; + } + + if (setjmp (toplevel)) + { + fprintf (stderr, "Exiting\n"); + exit (1); + } + + port = *next_arg; + next_arg++; + if (port == NULL || (!attach && !multi_mode && *next_arg == NULL)) + { + gdbserver_usage (); + exit (1); + } + + bad_attach = 0; + pid = 0; + + /* --attach used to come after PORT, so allow it there for + compatibility. */ + if (*next_arg != NULL && strcmp (*next_arg, "--attach") == 0) + { + attach = 1; + next_arg++; + } + + if (attach + && (*next_arg == NULL + || (*next_arg)[0] == '\0' + || (pid = strtoul (*next_arg, &arg_end, 0)) == 0 + || *arg_end != '\0' + || next_arg[1] != NULL)) + bad_attach = 1; + + if (bad_attach) + { + gdbserver_usage (); + exit (1); + } + + initialize_async_io (); + initialize_low (); + + own_buf = malloc (PBUFSIZ + 1); + mem_buf = malloc (PBUFSIZ); + + if (pid == 0 && *next_arg != NULL) + { + int i, n; + + n = argc - (next_arg - argv); + program_argv = malloc (sizeof (char *) * (n + 1)); + for (i = 0; i < n; i++) + program_argv[i] = strdup (next_arg[i]); + program_argv[i] = NULL; + + /* Wait till we are at first instruction in program. */ + signal = start_inferior (program_argv, &status); + + /* We are now (hopefully) stopped at the first instruction of + the target process. This assumes that the target process was + successfully created. */ + } + else if (pid != 0) + { + if (attach_inferior (pid, &status, &signal) == -1) + error ("Attaching not supported on this target"); + + /* Otherwise succeeded. */ + } + else + { + status = 'W'; + signal = 0; + } + + /* Don't report shared library events on the initial connection, + even if some libraries are preloaded. Avoids the "stopped by + shared library event" notice on gdb side. */ + dlls_changed = 0; + + if (setjmp (toplevel)) + { + fprintf (stderr, "Killing inferior\n"); + kill_inferior (); + exit (1); + } + + if (status == 'W' || status == 'X') + was_running = 0; + else + was_running = 1; + + if (!was_running && !multi_mode) + { + fprintf (stderr, "No program to debug. GDBserver exiting.\n"); + exit (1); + } + + while (1) + { + remote_open (port); + + restart: + if (setjmp (toplevel) != 0) + { + /* An error occurred. */ + if (response_needed) + { + write_enn (own_buf); + putpkt (own_buf); + } + } + + disable_async_io (); + while (!exit_requested) + { + unsigned char sig; + int packet_len; + int new_packet_len = -1; + + response_needed = 0; + packet_len = getpkt (own_buf); + if (packet_len <= 0) + break; + response_needed = 1; + + i = 0; + ch = own_buf[i++]; + switch (ch) + { + case 'q': + handle_query (own_buf, packet_len, &new_packet_len); + break; + case 'Q': + handle_general_set (own_buf); + break; + case 'D': + require_running (own_buf); + fprintf (stderr, "Detaching from inferior\n"); + if (detach_inferior () != 0) + write_enn (own_buf); + else + { + write_ok (own_buf); + + if (extended_protocol) + { + /* Treat this like a normal program exit. */ + signal = 0; + status = 'W'; + } + else + { + putpkt (own_buf); + remote_close (); + + /* If we are attached, then we can exit. Otherwise, we + need to hang around doing nothing, until the child + is gone. */ + if (!attached) + join_inferior (); + + exit (0); + } + } + break; + case '!': + extended_protocol = 1; + write_ok (own_buf); + break; + case '?': + prepare_resume_reply (own_buf, status, signal); + break; + case 'H': + if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's') + { + unsigned long gdb_id, thread_id; + + require_running (own_buf); + gdb_id = strtoul (&own_buf[2], NULL, 16); + if (gdb_id == 0 || gdb_id == -1) + thread_id = gdb_id; + else + { + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id == 0) + { + write_enn (own_buf); + break; + } + } + + if (own_buf[1] == 'g') + { + general_thread = thread_id; + set_desired_inferior (1); + } + else if (own_buf[1] == 'c') + cont_thread = thread_id; + else if (own_buf[1] == 's') + step_thread = thread_id; + + write_ok (own_buf); + } + else + { + /* Silently ignore it so that gdb can extend the protocol + without compatibility headaches. */ + own_buf[0] = '\0'; + } + break; + case 'g': + require_running (own_buf); + set_desired_inferior (1); + registers_to_string (own_buf); + break; + case 'G': + require_running (own_buf); + set_desired_inferior (1); + registers_from_string (&own_buf[1]); + write_ok (own_buf); + break; + case 'm': + require_running (own_buf); + decode_m_packet (&own_buf[1], &mem_addr, &len); + if (read_inferior_memory (mem_addr, mem_buf, len) == 0) + convert_int_to_ascii (mem_buf, own_buf, len); + else + write_enn (own_buf); + break; + case 'M': + require_running (own_buf); + decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf); + if (write_inferior_memory (mem_addr, mem_buf, len) == 0) + write_ok (own_buf); + else + write_enn (own_buf); + break; + case 'X': + require_running (own_buf); + if (decode_X_packet (&own_buf[1], packet_len - 1, + &mem_addr, &len, mem_buf) < 0 + || write_inferior_memory (mem_addr, mem_buf, len) != 0) + write_enn (own_buf); + else + write_ok (own_buf); + break; + case 'C': + require_running (own_buf); + convert_ascii_to_int (own_buf + 1, &sig, 1); + if (target_signal_to_host_p (sig)) + signal = target_signal_to_host (sig); + else + signal = 0; + myresume (own_buf, 0, &signal, &status); + break; + case 'S': + require_running (own_buf); + convert_ascii_to_int (own_buf + 1, &sig, 1); + if (target_signal_to_host_p (sig)) + signal = target_signal_to_host (sig); + else + signal = 0; + myresume (own_buf, 1, &signal, &status); + break; + case 'c': + require_running (own_buf); + signal = 0; + myresume (own_buf, 0, &signal, &status); + break; + case 's': + require_running (own_buf); + signal = 0; + myresume (own_buf, 1, &signal, &status); + break; + case 'Z': + { + char *lenptr; + char *dataptr; + CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16); + int len = strtol (lenptr + 1, &dataptr, 16); + char type = own_buf[1]; + + if (the_target->insert_watchpoint == NULL + || (type < '2' || type > '4')) + { + /* No watchpoint support or not a watchpoint command; + unrecognized either way. */ + own_buf[0] = '\0'; + } + else + { + int res; + + require_running (own_buf); + res = (*the_target->insert_watchpoint) (type, addr, len); + if (res == 0) + write_ok (own_buf); + else if (res == 1) + /* Unsupported. */ + own_buf[0] = '\0'; + else + write_enn (own_buf); + } + break; + } + case 'z': + { + char *lenptr; + char *dataptr; + CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16); + int len = strtol (lenptr + 1, &dataptr, 16); + char type = own_buf[1]; + + if (the_target->remove_watchpoint == NULL + || (type < '2' || type > '4')) + { + /* No watchpoint support or not a watchpoint command; + unrecognized either way. */ + own_buf[0] = '\0'; + } + else + { + int res; + + require_running (own_buf); + res = (*the_target->remove_watchpoint) (type, addr, len); + if (res == 0) + write_ok (own_buf); + else if (res == 1) + /* Unsupported. */ + own_buf[0] = '\0'; + else + write_enn (own_buf); + } + break; + } + case 'k': + response_needed = 0; + if (!target_running ()) + /* The packet we received doesn't make sense - but we + can't reply to it, either. */ + goto restart; + + fprintf (stderr, "Killing inferior\n"); + kill_inferior (); + + /* When using the extended protocol, we wait with no + program running. The traditional protocol will exit + instead. */ + if (extended_protocol) + { + status = 'X'; + signal = TARGET_SIGNAL_KILL; + was_running = 0; + goto restart; + } + else + { + exit (0); + break; + } + case 'T': + { + unsigned long gdb_id, thread_id; + + require_running (own_buf); + gdb_id = strtoul (&own_buf[1], NULL, 16); + thread_id = gdb_id_to_thread_id (gdb_id); + if (thread_id == 0) + { + write_enn (own_buf); + break; + } + + if (mythread_alive (thread_id)) + write_ok (own_buf); + else + write_enn (own_buf); + } + break; + case 'R': + response_needed = 0; + + /* Restarting the inferior is only supported in the + extended protocol. */ + if (extended_protocol) + { + if (target_running ()) + kill_inferior (); + fprintf (stderr, "GDBserver restarting\n"); + + /* Wait till we are at 1st instruction in prog. */ + if (program_argv != NULL) + signal = start_inferior (program_argv, &status); + else + { + status = 'X'; + signal = TARGET_SIGNAL_KILL; + } + goto restart; + } + else + { + /* It is a request we don't understand. Respond with an + empty packet so that gdb knows that we don't support this + request. */ + own_buf[0] = '\0'; + break; + } + case 'v': + /* Extended (long) request. */ + handle_v_requests (own_buf, &status, &signal, + packet_len, &new_packet_len); + break; + + default: + /* It is a request we don't understand. Respond with an + empty packet so that gdb knows that we don't support this + request. */ + own_buf[0] = '\0'; + break; + } + + if (new_packet_len != -1) + putpkt_binary (own_buf, new_packet_len); + else + putpkt (own_buf); + + response_needed = 0; + + if (was_running && (status == 'W' || status == 'X')) + { + was_running = 0; + + if (status == 'W') + fprintf (stderr, + "\nChild exited with status %d\n", signal); + if (status == 'X') + fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n", + target_signal_to_host (signal), + target_signal_to_name (signal)); + + if (extended_protocol) + goto restart; + else + { + fprintf (stderr, "GDBserver exiting\n"); + exit (0); + } + } + + if (status != 'W' && status != 'X') + was_running = 1; + } + + /* If an exit was requested (using the "monitor exit" command), + terminate now. The only other way to get here is for + getpkt to fail; close the connection and reopen it at the + top of the loop. */ + + if (exit_requested) + { + remote_close (); + if (attached && target_running ()) + detach_inferior (); + else if (target_running ()) + kill_inferior (); + exit (0); + } + else + { + fprintf (stderr, "Remote side has terminated connection. " + "GDBserver will reopen the connection.\n"); + remote_close (); + } + } +}
server.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: spu-low.c =================================================================== --- spu-low.c (nonexistent) +++ spu-low.c (revision 816) @@ -0,0 +1,604 @@ +/* Low level interface to SPUs, for the remote server for GDB. + Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Some older glibc versions do not define this. */ +#ifndef __WNOTHREAD +#define __WNOTHREAD 0x20000000 /* Don't wait on children of other + threads in this group */ +#endif + +#define PTRACE_TYPE_RET long +#define PTRACE_TYPE_ARG3 long + +/* Number of registers. */ +#define SPU_NUM_REGS 130 +#define SPU_NUM_CORE_REGS 128 + +/* Special registers. */ +#define SPU_ID_REGNUM 128 +#define SPU_PC_REGNUM 129 + +/* PPU side system calls. */ +#define INSTR_SC 0x44000002 +#define NR_spu_run 0x0116 + +/* Get current thread ID (Linux task ID). */ +#define current_tid ((struct inferior_list_entry *)current_inferior)->id + +/* These are used in remote-utils.c. */ +int using_threads = 0; + + +/* Fetch PPU register REGNO. */ +static CORE_ADDR +fetch_ppc_register (int regno) +{ + PTRACE_TYPE_RET res; + + int tid = current_tid; + +#ifndef __powerpc64__ + /* If running as a 32-bit process on a 64-bit system, we attempt + to get the full 64-bit register content of the target process. + If the PPC special ptrace call fails, we're on a 32-bit system; + just fall through to the regular ptrace call in that case. */ + { + char buf[8]; + + errno = 0; + ptrace (PPC_PTRACE_PEEKUSR_3264, tid, + (PTRACE_TYPE_ARG3) (regno * 8), buf); + if (errno == 0) + ptrace (PPC_PTRACE_PEEKUSR_3264, tid, + (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4); + if (errno == 0) + return (CORE_ADDR) *(unsigned long long *)buf; + } +#endif + + errno = 0; + res = ptrace (PT_READ_U, tid, + (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0); + if (errno != 0) + { + char mess[128]; + sprintf (mess, "reading PPC register #%d", regno); + perror_with_name (mess); + } + + return (CORE_ADDR) (unsigned long) res; +} + +/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */ +static int +fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word) +{ + errno = 0; + +#ifndef __powerpc64__ + if (memaddr >> 32) + { + unsigned long long addr_8 = (unsigned long long) memaddr; + ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word); + } + else +#endif + *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0); + + return errno; +} + +/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */ +static int +store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word) +{ + errno = 0; + +#ifndef __powerpc64__ + if (memaddr >> 32) + { + unsigned long long addr_8 = (unsigned long long) memaddr; + ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word); + } + else +#endif + ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word); + + return errno; +} + +/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR. */ +static int +fetch_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + int i, ret; + + CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET); + int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1) + / sizeof (PTRACE_TYPE_RET)); + PTRACE_TYPE_RET *buffer; + + int tid = current_tid; + + buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET)); + for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET)) + if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0) + return ret; + + memcpy (myaddr, + (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)), + len); + + return 0; +} + +/* Store LEN bytes from MYADDR to PPU memory at MEMADDR. */ +static int +store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + int i, ret; + + CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET); + int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1) + / sizeof (PTRACE_TYPE_RET)); + PTRACE_TYPE_RET *buffer; + + int tid = current_tid; + + buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET)); + + if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET)) + if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0) + return ret; + + if (count > 1) + if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1) + * sizeof (PTRACE_TYPE_RET), + &buffer[count - 1])) != 0) + return ret; + + memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)), + myaddr, len); + + for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET)) + if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0) + return ret; + + return 0; +} + + +/* 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) +{ + char buf[4]; + CORE_ADDR pc = fetch_ppc_register (32); /* nip */ + + /* Fetch instruction preceding current NIP. */ + if (fetch_ppc_memory (pc-4, buf, 4) != 0) + return 0; + /* It should be a "sc" instruction. */ + if (*(unsigned int *)buf != INSTR_SC) + return 0; + /* System call number should be NR_spu_run. */ + if (fetch_ppc_register (0) != NR_spu_run) + return 0; + + /* Register 3 contains fd, register 4 the NPC param pointer. */ + *fd = fetch_ppc_register (34); /* orig_gpr3 */ + *addr = fetch_ppc_register (4); + return 1; +} + + +/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF, + using the /proc file system. */ +static int +spu_proc_xfer_spu (const char *annex, unsigned char *readbuf, + const unsigned char *writebuf, + CORE_ADDR offset, int len) +{ + char buf[128]; + int fd = 0; + int ret = -1; + + if (!annex) + return 0; + + sprintf (buf, "/proc/%ld/fd/%s", current_tid, 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; +} + + +/* Start an inferior process and returns its pid. + ALLARGS is a vector of program-name and args. */ +static int +spu_create_inferior (char *program, char **allargs) +{ + int pid; + + pid = fork (); + if (pid < 0) + perror_with_name ("fork"); + + if (pid == 0) + { + ptrace (PTRACE_TRACEME, 0, 0, 0); + + setpgid (0, 0); + + execv (program, allargs); + if (errno == ENOENT) + execvp (program, allargs); + + fprintf (stderr, "Cannot exec %s: %s.\n", program, + strerror (errno)); + fflush (stderr); + _exit (0177); + } + + add_thread (pid, NULL, pid); + return pid; +} + +/* Attach to an inferior process. */ +int +spu_attach (unsigned long pid) +{ + if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0) + { + fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid, + strerror (errno), errno); + fflush (stderr); + _exit (0177); + } + + add_thread (pid, NULL, pid); + return 0; +} + +/* Kill the inferior process. */ +static void +spu_kill (void) +{ + ptrace (PTRACE_KILL, current_tid, 0, 0); +} + +/* Detach from inferior process. */ +static int +spu_detach (void) +{ + ptrace (PTRACE_DETACH, current_tid, 0, 0); + return 0; +} + +static void +spu_join (void) +{ + int status, ret; + + do { + ret = waitpid (current_tid, &status, 0); + if (WIFEXITED (status) || WIFSIGNALED (status)) + break; + } while (ret != -1 || errno != ECHILD); +} + +/* Return nonzero if the given thread is still alive. */ +static int +spu_thread_alive (unsigned long tid) +{ + return tid == current_tid; +} + +/* Resume process. */ +static void +spu_resume (struct thread_resume *resume_info) +{ + while (resume_info->thread != -1 + && resume_info->thread != current_tid) + resume_info++; + + if (resume_info->leave_stopped) + return; + + /* We don't support hardware single-stepping right now, assume + GDB knows to use software single-stepping. */ + if (resume_info->step) + fprintf (stderr, "Hardware single-step not supported.\n"); + + regcache_invalidate (); + + errno = 0; + ptrace (PTRACE_CONT, current_tid, 0, resume_info->sig); + if (errno) + perror_with_name ("ptrace"); +} + +/* Wait for process, returns status. */ +static unsigned char +spu_wait (char *status) +{ + int tid = current_tid; + int w; + int ret; + + while (1) + { + ret = waitpid (tid, &w, WNOHANG | __WALL | __WNOTHREAD); + + if (ret == -1) + { + if (errno != ECHILD) + perror_with_name ("waitpid"); + } + else if (ret > 0) + break; + + usleep (1000); + } + + /* On the first wait, continue running the inferior until we are + blocked inside an spu_run system call. */ + if (!server_waiting) + { + int fd; + CORE_ADDR addr; + + while (!parse_spufs_run (&fd, &addr)) + { + ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0); + waitpid (tid, NULL, __WALL | __WNOTHREAD); + } + } + + if (WIFEXITED (w)) + { + fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); + *status = 'W'; + clear_inferiors (); + return ((unsigned char) WEXITSTATUS (w)); + } + else if (!WIFSTOPPED (w)) + { + fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); + *status = 'X'; + clear_inferiors (); + return ((unsigned char) WTERMSIG (w)); + } + + /* After attach, we may have received a SIGSTOP. Do not return this + as signal to GDB, or else it will try to continue with SIGSTOP ... */ + if (!server_waiting) + { + *status = 'T'; + return 0; + } + + *status = 'T'; + return ((unsigned char) WSTOPSIG (w)); +} + +/* Fetch inferior registers. */ +static void +spu_fetch_registers (int regno) +{ + int fd; + CORE_ADDR addr; + + /* ??? Some callers use 0 to mean all registers. */ + if (regno == 0) + regno = -1; + + /* We must be stopped on a spu_run system call. */ + if (!parse_spufs_run (&fd, &addr)) + return; + + /* The ID register holds the spufs file handle. */ + if (regno == -1 || regno == SPU_ID_REGNUM) + supply_register (SPU_ID_REGNUM, (char *)&fd); + + /* The NPC register is found at ADDR. */ + if (regno == -1 || regno == SPU_PC_REGNUM) + { + char buf[4]; + if (fetch_ppc_memory (addr, buf, 4) == 0) + supply_register (SPU_PC_REGNUM, buf); + } + + /* The GPRs are found in the "regs" spufs file. */ + if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS)) + { + unsigned char buf[16*SPU_NUM_CORE_REGS]; + char annex[32]; + int i; + + sprintf (annex, "%d/regs", fd); + if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf) + for (i = 0; i < SPU_NUM_CORE_REGS; i++) + supply_register (i, buf + i*16); + } +} + +/* Store inferior registers. */ +static void +spu_store_registers (int regno) +{ + int fd; + CORE_ADDR addr; + + /* ??? Some callers use 0 to mean all registers. */ + if (regno == 0) + regno = -1; + + /* We must be stopped on a spu_run system call. */ + if (!parse_spufs_run (&fd, &addr)) + return; + + /* The NPC register is found at ADDR. */ + if (regno == -1 || regno == SPU_PC_REGNUM) + { + char buf[4]; + collect_register (SPU_PC_REGNUM, buf); + store_ppc_memory (addr, buf, 4); + } + + /* The GPRs are found in the "regs" spufs file. */ + if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS)) + { + unsigned char buf[16*SPU_NUM_CORE_REGS]; + char annex[32]; + int i; + + for (i = 0; i < SPU_NUM_CORE_REGS; i++) + collect_register (i, buf + i*16); + + sprintf (annex, "%d/regs", fd); + spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf); + } +} + +/* Copy LEN bytes from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. */ +static int +spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int fd, ret; + CORE_ADDR addr; + char annex[32]; + + /* We must be stopped on a spu_run system call. */ + if (!parse_spufs_run (&fd, &addr)) + return 0; + + /* Use the "mem" spufs file to access SPU local store. */ + sprintf (annex, "%d/mem", fd); + ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len); + return ret == len ? 0 : EIO; +} + +/* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. + On failure (cannot write the inferior) + returns the value of errno. */ +static int +spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len) +{ + int fd, ret; + CORE_ADDR addr; + char annex[32]; + + /* We must be stopped on a spu_run system call. */ + if (!parse_spufs_run (&fd, &addr)) + return 0; + + /* Use the "mem" spufs file to access SPU local store. */ + sprintf (annex, "%d/mem", fd); + ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len); + return ret == len ? 0 : EIO; +} + +/* Look up special symbols -- unneded here. */ +static void +spu_look_up_symbols (void) +{ +} + +/* Send signal to inferior. */ +static void +spu_request_interrupt (void) +{ + syscall (SYS_tkill, current_tid, SIGINT); +} + +static const char * +spu_arch_string (void) +{ + return "spu"; +} + +static struct target_ops spu_target_ops = { + spu_create_inferior, + spu_attach, + spu_kill, + spu_detach, + spu_join, + spu_thread_alive, + spu_resume, + spu_wait, + spu_fetch_registers, + spu_store_registers, + spu_read_memory, + spu_write_memory, + spu_look_up_symbols, + spu_request_interrupt, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + spu_arch_string, + spu_proc_xfer_spu, + hostio_last_error_from_errno, +}; + +void +initialize_low (void) +{ + static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff }; + + set_target_ops (&spu_target_ops); + set_breakpoint_data (breakpoint, sizeof breakpoint); + init_registers (); +}
spu-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-x86-64-low.c =================================================================== --- linux-x86-64-low.c (nonexistent) +++ linux-x86-64-low.c (revision 816) @@ -0,0 +1,180 @@ +/* GNU/Linux/x86-64 specific low level interface, for the remote server + for GDB. + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" +#include "i387-fp.h" + +#include "gdb_proc_service.h" + +#include +#include +#include + +/* This definition comes from prctl.h, but some kernels may not have it. */ +#ifndef PTRACE_ARCH_PRCTL +#define PTRACE_ARCH_PRCTL 30 +#endif + +/* The following definitions come from prctl.h, but may be absent + for certain configurations. */ +#ifndef ARCH_GET_FS +#define ARCH_SET_GS 0x1001 +#define ARCH_SET_FS 0x1002 +#define ARCH_GET_FS 0x1003 +#define ARCH_GET_GS 0x1004 +#endif + +static int x86_64_regmap[] = { + RAX * 8, RBX * 8, RCX * 8, RDX * 8, + RSI * 8, RDI * 8, RBP * 8, RSP * 8, + R8 * 8, R9 * 8, R10 * 8, R11 * 8, + R12 * 8, R13 * 8, R14 * 8, R15 * 8, + RIP * 8, EFLAGS * 8, CS * 8, SS * 8, + DS * 8, ES * 8, FS * 8, GS * 8, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + ORIG_RAX * 8 +}; + +#define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int)) + +/* Called by libthread_db. */ + +ps_err_e +ps_get_thread_area (const struct ps_prochandle *ph, + lwpid_t lwpid, int idx, void **base) +{ + switch (idx) + { + case FS: + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0) + return PS_OK; + break; + case GS: + if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0) + return PS_OK; + break; + default: + return PS_BADADDR; + } + return PS_ERR; +} + +static void +x86_64_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < X86_64_NUM_GREGS; i++) + if (x86_64_regmap[i] != -1) + collect_register (i, ((char *) buf) + x86_64_regmap[i]); +} + +static void +x86_64_store_gregset (const void *buf) +{ + int i; + + for (i = 0; i < X86_64_NUM_GREGS; i++) + if (x86_64_regmap[i] != -1) + supply_register (i, ((char *) buf) + x86_64_regmap[i]); +} + +static void +x86_64_fill_fpregset (void *buf) +{ + i387_cache_to_fxsave (buf); +} + +static void +x86_64_store_fpregset (const void *buf) +{ + i387_fxsave_to_cache (buf); +} + +struct regset_info target_regsets[] = { + { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t), + GENERAL_REGS, + x86_64_fill_gregset, x86_64_store_gregset }, + { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t), + FP_REGS, + x86_64_fill_fpregset, x86_64_store_fpregset }, + { 0, 0, -1, -1, NULL, NULL } +}; + +static const unsigned char x86_64_breakpoint[] = { 0xCC }; +#define x86_64_breakpoint_len 1 + +extern int debug_threads; + +static CORE_ADDR +x86_64_get_pc () +{ + unsigned long pc; + + collect_register_by_name ("rip", &pc); + + if (debug_threads) + fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc); + return pc; +} + +static void +x86_64_set_pc (CORE_ADDR newpc) +{ + if (debug_threads) + fprintf (stderr, "set pc to %08lx\n", (long) newpc); + supply_register_by_name ("rip", &newpc); +} + +static int +x86_64_breakpoint_at (CORE_ADDR pc) +{ + unsigned char c; + + read_inferior_memory (pc, &c, 1); + if (c == 0xCC) + return 1; + + return 0; +} + +struct linux_target_ops the_low_target = { + -1, + NULL, + NULL, + NULL, + x86_64_get_pc, + x86_64_set_pc, + x86_64_breakpoint, + x86_64_breakpoint_len, + NULL, + 1, + x86_64_breakpoint_at, + NULL, + NULL, + NULL, + NULL, + 0, + "i386:x86-64", +};
linux-x86-64-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: gdbreplay.c =================================================================== --- gdbreplay.c (nonexistent) +++ gdbreplay.c (revision 816) @@ -0,0 +1,428 @@ +/* Replay a remote debug session logfile for GDB. + Copyright (C) 1996, 1998, 1999, 2000, 2002, 2003, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + Written by Fred Fish (fnf@cygnus.com) from pieces of gdbserver. + + 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 3 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, see . */ + +#include "config.h" +#include +#if HAVE_SYS_FILE_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif +#include +#if HAVE_FCNTL_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#if HAVE_NETDB_H +#include +#endif +#if HAVE_NETINET_TCP_H +#include +#endif +#if HAVE_MALLOC_H +#include +#endif + +#if USE_WIN32API +#include +#endif + +#ifndef HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + +/* Sort of a hack... */ +#define EOL (EOF - 1) + +static int remote_desc; + +#ifdef __MINGW32CE__ + +#ifndef COUNTOF +#define COUNTOF(STR) (sizeof (STR) / sizeof ((STR)[0])) +#endif + +#define errno (GetLastError ()) + +char * +strerror (DWORD error) +{ + static char buf[1024]; + WCHAR *msgbuf; + DWORD lasterr = GetLastError (); + DWORD chars = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) + { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 + && msgbuf[chars - 2] == '\r' + && msgbuf[chars - 1] == '\n') + { + chars -= 2; + msgbuf[chars] = 0; + } + + if (chars > ((COUNTOF (buf)) - 1)) + { + chars = COUNTOF (buf) - 1; + msgbuf [chars] = 0; + } + + wcstombs (buf, msgbuf, chars + 1); + LocalFree (msgbuf); + } + else + sprintf (buf, "unknown win32 error (%ld)", error); + + SetLastError (lasterr); + return buf; +} + +#endif /* __MINGW32CE__ */ + +/* Print the system error message for errno, and also mention STRING + as the file name for which the error was encountered. + Then return to command level. */ + +static void +perror_with_name (char *string) +{ +#ifndef STDC_HEADERS + extern int errno; +#endif + const char *err; + char *combined; + + err = strerror (errno); + if (err == NULL) + err = "unknown error"; + + combined = (char *) alloca (strlen (err) + strlen (string) + 3); + strcpy (combined, string); + strcat (combined, ": "); + strcat (combined, err); + fprintf (stderr, "\n%s.\n", combined); + fflush (stderr); + exit (1); +} + +static void +sync_error (FILE *fp, char *desc, int expect, int got) +{ + fprintf (stderr, "\n%s\n", desc); + fprintf (stderr, "At logfile offset %ld, expected '0x%x' got '0x%x'\n", + ftell (fp), expect, got); + fflush (stderr); + exit (1); +} + +static void +remote_close (void) +{ +#ifdef USE_WIN32API + closesocket (remote_desc); +#else + close (remote_desc); +#endif +} + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +static void +remote_open (char *name) +{ + if (!strchr (name, ':')) + { + fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name); + fflush (stderr); + exit (1); + } + else + { +#ifdef USE_WIN32API + static int winsock_initialized; +#endif + char *port_str; + int port; + struct sockaddr_in sockaddr; + socklen_t tmp; + int tmp_desc; + + port_str = strchr (name, ':'); + + port = atoi (port_str + 1); + +#ifdef USE_WIN32API + if (!winsock_initialized) + { + WSADATA wsad; + + WSAStartup (MAKEWORD (1, 0), &wsad); + winsock_initialized = 1; + } +#endif + + tmp_desc = socket (PF_INET, SOCK_STREAM, 0); + if (tmp_desc < 0) + perror_with_name ("Can't open socket"); + + /* Allow rapid reuse of this port. */ + tmp = 1; + setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, + sizeof (tmp)); + + sockaddr.sin_family = PF_INET; + sockaddr.sin_port = htons (port); + sockaddr.sin_addr.s_addr = INADDR_ANY; + + if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) + || listen (tmp_desc, 1)) + perror_with_name ("Can't bind address"); + + tmp = sizeof (sockaddr); + remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp); + if (remote_desc == -1) + perror_with_name ("Accept failed"); + + /* Enable TCP keep alive process. */ + tmp = 1; + setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp)); + + /* Tell TCP not to delay small packets. This greatly speeds up + interactive response. */ + tmp = 1; + setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY, + (char *) &tmp, sizeof (tmp)); + +#ifndef USE_WIN32API + close (tmp_desc); /* No longer need this */ + + signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbreplay simply + exits when the remote side dies. */ +#else + closesocket (tmp_desc); /* No longer need this */ +#endif + } + +#if defined(F_SETFL) && defined (FASYNC) + fcntl (remote_desc, F_SETFL, FASYNC); +#endif + + fprintf (stderr, "Replay logfile using %s\n", name); + fflush (stderr); +} + +static int +tohex (int ch) +{ + if (ch >= '0' && ch <= '9') + { + return (ch - '0'); + } + if (ch >= 'A' && ch <= 'F') + { + return (ch - 'A' + 10); + } + if (ch >= 'a' && ch <= 'f') + { + return (ch - 'a' + 10); + } + fprintf (stderr, "\nInvalid hex digit '%c'\n", ch); + fflush (stderr); + exit (1); +} + +static int +logchar (FILE *fp) +{ + int ch; + int ch2; + + ch = fgetc (fp); + fputc (ch, stdout); + fflush (stdout); + switch (ch) + { + case '\n': + ch = EOL; + break; + case '\\': + ch = fgetc (fp); + fputc (ch, stdout); + fflush (stdout); + switch (ch) + { + case '\\': + break; + case 'b': + ch = '\b'; + break; + case 'f': + ch = '\f'; + break; + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + case 'v': + ch = '\v'; + break; + case 'x': + ch2 = fgetc (fp); + fputc (ch2, stdout); + fflush (stdout); + ch = tohex (ch2) << 4; + ch2 = fgetc (fp); + fputc (ch2, stdout); + fflush (stdout); + ch |= tohex (ch2); + break; + default: + /* Treat any other char as just itself */ + break; + } + default: + break; + } + return (ch); +} + +/* Accept input from gdb and match with chars from fp (after skipping one + blank) up until a \n is read from fp (which is not matched) */ + +static void +expect (FILE *fp) +{ + int fromlog; + unsigned char fromgdb; + + if ((fromlog = logchar (fp)) != ' ') + { + sync_error (fp, "Sync error during gdb read of leading blank", ' ', + fromlog); + } + do + { + fromlog = logchar (fp); + if (fromlog == EOL) + { + break; + } + read (remote_desc, &fromgdb, 1); + } + while (fromlog == fromgdb); + if (fromlog != EOL) + { + sync_error (fp, "Sync error during read of gdb packet", fromlog, + fromgdb); + } +} + +/* Play data back to gdb from fp (after skipping leading blank) up until a + \n is read from fp (which is discarded and not sent to gdb). */ + +static void +play (FILE *fp) +{ + int fromlog; + char ch; + + if ((fromlog = logchar (fp)) != ' ') + { + sync_error (fp, "Sync error skipping blank during write to gdb", ' ', + fromlog); + } + while ((fromlog = logchar (fp)) != EOL) + { + ch = fromlog; + write (remote_desc, &ch, 1); + } +} + +int +main (int argc, char *argv[]) +{ + FILE *fp; + int ch; + + if (argc < 3) + { + fprintf (stderr, "Usage: gdbreplay \n"); + fflush (stderr); + exit (1); + } + fp = fopen (argv[1], "r"); + if (fp == NULL) + { + perror_with_name (argv[1]); + } + remote_open (argv[2]); + while ((ch = logchar (fp)) != EOF) + { + switch (ch) + { + case 'w': + /* data sent from gdb to gdbreplay, accept and match it */ + expect (fp); + break; + case 'r': + /* data sent from gdbreplay to gdb, play it */ + play (fp); + break; + case 'c': + /* Command executed by gdb */ + while ((ch = logchar (fp)) != EOL); + break; + } + } + remote_close (); + exit (0); +}
gdbreplay.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: server.h =================================================================== --- server.h (nonexistent) +++ server.h (revision 816) @@ -0,0 +1,242 @@ +/* Common definitions for remote server for GDB. + Copyright (C) 1993, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, + 2006, 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#ifndef SERVER_H +#define SERVER_H + +#include "config.h" + +#ifdef __MINGW32CE__ +#include "wincecompat.h" +#endif + +#include +#include +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include + +#ifdef HAVE_STRING_H +#include +#endif + +#if !HAVE_DECL_STRERROR +#ifndef strerror +extern char *strerror (int); /* X3.159-1989 4.11.6.2 */ +#endif +#endif + +#if !HAVE_DECL_PERROR +#ifndef perror +extern void perror (const char *); +#endif +#endif + +#ifndef ATTR_NORETURN +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) +#define ATTR_NORETURN __attribute__ ((noreturn)) +#else +#define ATTR_NORETURN /* nothing */ +#endif +#endif + +#ifndef ATTR_FORMAT +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4)) +#define ATTR_FORMAT(type, x, y) __attribute__ ((format(type, x, y))) +#else +#define ATTR_FORMAT(type, x, y) /* nothing */ +#endif +#endif + +/* A type used for binary buffers. */ +typedef unsigned char gdb_byte; + +/* FIXME: This should probably be autoconf'd for. It's an integer type at + least the size of a (void *). */ +typedef long long CORE_ADDR; + +/* Generic information for tracking a list of ``inferiors'' - threads, + processes, etc. */ +struct inferior_list +{ + struct inferior_list_entry *head; + struct inferior_list_entry *tail; +}; +struct inferior_list_entry +{ + unsigned long id; + struct inferior_list_entry *next; +}; + +/* Opaque type for user-visible threads. */ +struct thread_info; + +struct dll_info +{ + struct inferior_list_entry entry; + char *name; + CORE_ADDR base_addr; +}; + +#include "regcache.h" +#include "gdb/signals.h" + +#include "target.h" +#include "mem-break.h" + +/* Target-specific functions */ + +void initialize_low (); + +/* From inferiors.c. */ + +extern struct inferior_list all_threads; +extern struct inferior_list all_dlls; +extern int dlls_changed; + +void add_inferior_to_list (struct inferior_list *list, + struct inferior_list_entry *new_inferior); +void for_each_inferior (struct inferior_list *list, + void (*action) (struct inferior_list_entry *)); +extern struct thread_info *current_inferior; +void remove_inferior (struct inferior_list *list, + struct inferior_list_entry *entry); +void remove_thread (struct thread_info *thread); +void add_thread (unsigned long thread_id, void *target_data, unsigned int); +unsigned int thread_id_to_gdb_id (unsigned long); +unsigned int thread_to_gdb_id (struct thread_info *); +unsigned long gdb_id_to_thread_id (unsigned int); +struct thread_info *gdb_id_to_thread (unsigned int); +void clear_inferiors (void); +struct inferior_list_entry *find_inferior + (struct inferior_list *, + int (*func) (struct inferior_list_entry *, + void *), + void *arg); +struct inferior_list_entry *find_inferior_id (struct inferior_list *list, + unsigned long id); +void *inferior_target_data (struct thread_info *); +void set_inferior_target_data (struct thread_info *, void *); +void *inferior_regcache_data (struct thread_info *); +void set_inferior_regcache_data (struct thread_info *, void *); +void add_pid_to_list (struct inferior_list *list, unsigned long pid); +int pull_pid_from_list (struct inferior_list *list, unsigned long pid); + +void loaded_dll (const char *name, CORE_ADDR base_addr); +void unloaded_dll (const char *name, CORE_ADDR base_addr); + +/* Public variables in server.c */ + +extern unsigned long cont_thread; +extern unsigned long general_thread; +extern unsigned long step_thread; +extern unsigned long thread_from_wait; +extern unsigned long old_thread_from_wait; +extern int server_waiting; +extern int debug_threads; +extern int pass_signals[]; + +extern jmp_buf toplevel; + +/* Functions from hostio.c. */ +extern int handle_vFile (char *, int, int *); + +/* Functions from hostio-errno.c. */ +extern void hostio_last_error_from_errno (char *own_buf); + +/* From remote-utils.c */ + +extern int remote_debug; +extern int all_symbols_looked_up; + +int putpkt (char *buf); +int putpkt_binary (char *buf, int len); +int getpkt (char *buf); +void remote_open (char *name); +void remote_close (void); +void write_ok (char *buf); +void write_enn (char *buf); +void initialize_async_io (void); +void enable_async_io (void); +void disable_async_io (void); +void check_remote_input_interrupt_request (void); +void convert_ascii_to_int (char *from, unsigned char *to, int n); +void convert_int_to_ascii (unsigned char *from, char *to, int n); +void new_thread_notify (int id); +void dead_thread_notify (int id); +void prepare_resume_reply (char *buf, char status, unsigned char sig); + +const char *decode_address_to_semicolon (CORE_ADDR *addrp, const char *start); +void decode_address (CORE_ADDR *addrp, const char *start, int len); +void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr, + unsigned int *len_ptr); +void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, + unsigned int *len_ptr, unsigned char *to); +int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr, + unsigned int *len_ptr, unsigned char *to); +int decode_xfer_write (char *buf, int packet_len, char **annex, + CORE_ADDR *offset, unsigned int *len, + unsigned char *data); + +int unhexify (char *bin, const char *hex, int count); +int hexify (char *hex, const char *bin, int count); +int remote_escape_output (const gdb_byte *buffer, int len, + gdb_byte *out_buf, int *out_len, + int out_maxlen); + +int look_up_one_symbol (const char *name, CORE_ADDR *addrp); + +void monitor_output (const char *msg); + +char *xml_escape_text (const char *text); + +/* Functions from ``signals.c''. */ +enum target_signal target_signal_from_host (int hostsig); +int target_signal_to_host_p (enum target_signal oursig); +int target_signal_to_host (enum target_signal oursig); +char *target_signal_to_name (enum target_signal); + +/* Functions from utils.c */ + +void perror_with_name (char *string); +void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2); +void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2); +void warning (const char *string,...) ATTR_FORMAT (printf, 1, 2); + +/* Functions from the register cache definition. */ + +void init_registers (void); + +/* Maximum number of bytes to read/write at once. The value here + is chosen to fill up a packet (the headers account for the 32). */ +#define MAXBUFBYTES(N) (((N)-32)/2) + +/* Buffer sizes for transferring memory, registers, etc. Round up PBUFSIZ to + hold all the registers, at least. */ +#define PBUFSIZ ((registers_length () + 32 > 2000) \ + ? (registers_length () + 32) \ + : 2000) + +/* Version information, from version.c. */ +extern const char version[]; +extern const char host_name[]; + +#endif /* SERVER_H */
server.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: README =================================================================== --- README (nonexistent) +++ README (revision 816) @@ -0,0 +1,151 @@ + README for GDBserver & GDBreplay + by Stu Grossman and Fred Fish + +Introduction: + +This is GDBserver, a remote server for Un*x-like systems. It can be used to +control the execution of a program on a target system from a GDB on a different +host. GDB and GDBserver communicate using the standard remote serial protocol +implemented in remote.c, and various *-stub.c files. They communicate via +either a serial line or a TCP connection. + +For more information about GDBserver, see the GDB manual. + +Usage (server (target) side): + +First, you need to have a copy of the program you want to debug put onto +the target system. The program can be stripped to save space if needed, as +GDBserver doesn't care about symbols. All symbol handling is taken care of by +the GDB running on the host system. + +To use the server, you log on to the target system, and run the `gdbserver' +program. You must tell it (a) how to communicate with GDB, (b) the name of +your program, and (c) its arguments. The general syntax is: + + target> gdbserver COMM PROGRAM [ARGS ...] + +For example, using a serial port, you might say: + + target> gdbserver /dev/com1 emacs foo.txt + +This tells gdbserver to debug emacs with an argument of foo.txt, and to +communicate with GDB via /dev/com1. Gdbserver now waits patiently for the +host GDB to communicate with it. + +To use a TCP connection, you could say: + + target> gdbserver host:2345 emacs foo.txt + +This says pretty much the same thing as the last example, except that we are +going to communicate with the host GDB via TCP. The `host:2345' argument means +that we are expecting to see a TCP connection from `host' to local TCP port +2345. (Currently, the `host' part is ignored.) You can choose any number you +want for the port number as long as it does not conflict with any existing TCP +ports on the target system. This same port number must be used in the host +GDBs `target remote' command, which will be described shortly. Note that if +you chose a port number that conflicts with another service, gdbserver will +print an error message and exit. + +On some targets, gdbserver can also attach to running programs. This is +accomplished via the --attach argument. The syntax is: + + target> gdbserver --attach COMM PID + +PID is the process ID of a currently running process. It isn't necessary +to point gdbserver at a binary for the running process. + +Usage (host side): + +You need an unstripped copy of the target program on your host system, since +GDB needs to examine it's symbol tables and such. Start up GDB as you normally +would, with the target program as the first argument. (You may need to use the +--baud option if the serial line is running at anything except 9600 baud.) +Ie: `gdb TARGET-PROG', or `gdb --baud BAUD TARGET-PROG'. After that, the only +new command you need to know about is `target remote'. It's argument is either +a device name (usually a serial device, like `/dev/ttyb'), or a HOST:PORT +descriptor. For example: + + (gdb) target remote /dev/ttyb + +communicates with the server via serial line /dev/ttyb, and: + + (gdb) target remote the-target:2345 + +communicates via a TCP connection to port 2345 on host `the-target', where +you previously started up gdbserver with the same port number. Note that for +TCP connections, you must start up gdbserver prior to using the `target remote' +command, otherwise you may get an error that looks something like +`Connection refused'. + +Building gdbserver: + +The supported targets as of November 2006 are: + arm-*-linux* + crisv32-*-linux* + cris-*-linux* + i[34567]86-*-cygwin* + i[34567]86-*-linux* + i[34567]86-*-mingw* + ia64-*-linux* + m32r*-*-linux* + m68*-*-linux* + m68*-*-uclinux* + mips*64*-*-linux* + mips*-*-linux* + powerpc[64]-*-linux* + s390[x]-*-linux* + sh-*-linux* + spu*-*-* + x86_64-*-linux* + xscale*-*-linux* + +Configuring gdbserver you should specify the same machine for host and +target (which are the machine that gdbserver is going to run on. This +is not the same as the machine that gdb is going to run on; building +gdbserver automatically as part of building a whole tree of tools does +not currently work if cross-compilation is involved (we don't get the +right CC in the Makefile, to start with)). + +Building gdbserver for your target is very straightforward. If you build +GDB natively on a target which gdbserver supports, it will be built +automatically when you build GDB. You can also build just gdbserver: + + % mkdir obj + % cd obj + % path-to-gdbserver-sources/configure + % make + +If you prefer to cross-compile to your target, then you can also build +gdbserver that way. In a Bourne shell, for example: + + % export CC=your-cross-compiler + % path-to-gdbserver-sources/configure your-target-name + % make + +Using GDBreplay: + +A special hacked down version of gdbserver can be used to replay remote +debug log files created by gdb. Before using the gdb "target" command to +initiate a remote debug session, use "set remotelogfile " to tell +gdb that you want to make a recording of the serial or tcp session. Note +that when replaying the session, gdb communicates with gdbreplay via tcp, +regardless of whether the original session was via a serial link or tcp. + +Once you are done with the remote debug session, start gdbreplay and +tell it the name of the log file and the host and port number that gdb +should connect to (typically the same as the host running gdb): + + $ gdbreplay logfile host:port + +Then start gdb (preferably in a different screen or window) and use the +"target" command to connect to gdbreplay: + + (gdb) target remote host:port + +Repeat the same sequence of user commands to gdb that you gave in the +original debug session. Gdb should not be able to tell that it is talking +to gdbreplay rather than a real target, all other things being equal. Note +that gdbreplay echos the command lines to stderr, as well as the contents of +the packets it sends and receives. The last command echoed by gdbreplay is +the next command that needs to be typed to gdb to continue the session in +sync with the original session.
README Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: xtensa-xtregs.c =================================================================== --- xtensa-xtregs.c (nonexistent) +++ xtensa-xtregs.c (revision 816) @@ -0,0 +1,37 @@ +/* Table mapping between kernel xtregset and GDB register cache. + Copyright 2007, 2008 Free Software Foundation, Inc. + + 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, see . */ + + +typedef struct { + int gdb_regnum; + int gdb_offset; + int ptrace_cp_offset; + int ptrace_offset; + int size; + int coproc; + int dbnum; + char* name +;} xtensa_regtable_t; + +#define XTENSA_ELF_XTREG_SIZE 0 + +const xtensa_regtable_t xtensa_regmap_table[] = { + /* gnum,gofs,cpofs,ofs,siz,cp, dbnum, name */ + { 0 } +}; +
xtensa-xtregs.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: terminal.h =================================================================== --- terminal.h (nonexistent) +++ terminal.h (revision 816) @@ -0,0 +1,51 @@ +/* Terminal interface definitions for the GDB remote server. + Copyright (C) 2002, Free Software Foundation, Inc. + + 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 3 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, see . */ + +#if !defined (TERMINAL_H) +#define TERMINAL_H 1 + +/* Autoconf will have defined HAVE_TERMIOS_H, HAVE_TERMIO_H, + and HAVE_SGTTY_H for us as appropriate. */ + +#if defined(HAVE_TERMIOS_H) +#define HAVE_TERMIOS +#include +#else /* ! HAVE_TERMIOS_H */ +#if defined(HAVE_TERMIO_H) +#define HAVE_TERMIO +#include + +#undef TIOCGETP +#define TIOCGETP TCGETA +#undef TIOCSETN +#define TIOCSETN TCSETA +#undef TIOCSETP +#define TIOCSETP TCSETAF +#define TERMINAL struct termio +#else /* ! HAVE_TERMIO_H */ +#ifdef HAVE_SGTTY_H +#define HAVE_SGTTY +#include +#include +#include +#define TERMINAL struct sgttyb +#endif +#endif +#endif + +#endif /* !defined (TERMINAL_H) */
terminal.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: acinclude.m4 =================================================================== --- acinclude.m4 (nonexistent) +++ acinclude.m4 (revision 816) @@ -0,0 +1,63 @@ +dnl gdb/gdbserver/configure.in uses BFD_HAVE_SYS_PROCFS_TYPE. +sinclude(../../bfd/bfd.m4) + +AC_DEFUN([SRV_CHECK_THREAD_DB], +[AC_CACHE_CHECK([for libthread_db],[srv_cv_thread_db], + [old_LIBS="$LIBS" + LIBS="$LIBS -lthread_db" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_get_thread_area() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="-lthread_db"], + [srv_cv_thread_db=no + + if test "$prefix" = "/usr" || test "$prefix" = "NONE"; then + thread_db="/lib/libthread_db.so.1" + else + thread_db='$prefix/lib/libthread_db.so.1' + fi + LIBS="$old_LIBS `eval echo "$thread_db"`" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_get_thread_area() {} + void ps_getpid() {}], + [td_ta_new();], + [srv_cv_thread_db="$thread_db"], + [srv_cv_thread_db=no]) + ]) + LIBS="$old_LIBS" +])]) + +AC_DEFUN([SRV_CHECK_TLS_GET_ADDR], +[AC_CACHE_CHECK([for thread_db_tls_get_addr],[srv_cv_tls_get_addr], + [old_LIBS="$LIBS" + LIBS="$LIBS $srv_cv_thread_db" + AC_TRY_LINK( + [void ps_pglobal_lookup() {} + void ps_pdread() {} + void ps_pdwrite() {} + void ps_lgetregs() {} + void ps_lsetregs() {} + void ps_lgetfpregs() {} + void ps_lsetfpregs() {} + void ps_get_thread_area() {} + void ps_getpid() {}], + [td_thr_tls_get_addr();], + [srv_cv_tls_get_addr=yes], + [srv_cv_tls_get_addr=no]) + LIBS="$old_LIBS" +])]) Index: target.c =================================================================== --- target.c (nonexistent) +++ target.c (revision 816) @@ -0,0 +1,111 @@ +/* Target operations for the remote server for GDB. + Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#include "server.h" + +struct target_ops *the_target; + +void +set_desired_inferior (int use_general) +{ + struct thread_info *found; + + if (use_general == 1) + { + found = (struct thread_info *) find_inferior_id (&all_threads, + general_thread); + } + else + { + found = NULL; + + /* If we are continuing any (all) thread(s), use step_thread + to decide which thread to step and/or send the specified + signal to. */ + if ((step_thread != 0 && step_thread != -1) + && (cont_thread == 0 || cont_thread == -1)) + found = (struct thread_info *) find_inferior_id (&all_threads, + step_thread); + + if (found == NULL) + found = (struct thread_info *) find_inferior_id (&all_threads, + cont_thread); + } + + if (found == NULL) + current_inferior = (struct thread_info *) all_threads.head; + else + current_inferior = found; +} + +int +read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) +{ + int res; + res = (*the_target->read_memory) (memaddr, myaddr, len); + check_mem_read (memaddr, myaddr, len); + return res; +} + +int +write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, + int len) +{ + /* Lacking cleanups, there is some potential for a memory leak if the + write fails and we go through error(). Make sure that no more than + one buffer is ever pending by making BUFFER static. */ + static unsigned char *buffer = 0; + int res; + + if (buffer != NULL) + free (buffer); + + buffer = malloc (len); + memcpy (buffer, myaddr, len); + check_mem_write (memaddr, buffer, len); + res = (*the_target->write_memory) (memaddr, buffer, len); + free (buffer); + buffer = NULL; + + return res; +} + +unsigned char +mywait (char *statusp, int connected_wait) +{ + unsigned char ret; + + if (connected_wait) + server_waiting = 1; + + ret = (*the_target->wait) (statusp); + + if (connected_wait) + server_waiting = 0; + + return ret; +} + +void +set_target_ops (struct target_ops *target) +{ + the_target = (struct target_ops *) malloc (sizeof (*the_target)); + memcpy (the_target, target, sizeof (*the_target)); +}
target.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-ppc64-low.c =================================================================== --- linux-ppc64-low.c (nonexistent) +++ linux-ppc64-low.c (revision 816) @@ -0,0 +1,181 @@ +/* GNU/Linux/PowerPC64 specific low level interface, for the remote server for + GDB. + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "linux-low.h" + +#include + +#define ppc_num_regs 71 + +/* We use a constant for FPSCR instead of PT_FPSCR, because + many shipped PPC64 kernels had the wrong value in ptrace.h. */ +static int ppc_regmap[] = + {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8, + PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8, + PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8, + PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8, + PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8, + PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8, + PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8, + PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8, + PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24, + PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56, + PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88, + PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120, + PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152, + PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184, + 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 }; + +static int +ppc_cannot_store_register (int regno) +{ + return 0; +} + +static int +ppc_cannot_fetch_register (int regno) +{ + return 0; +} + +static CORE_ADDR +ppc_get_pc (void) +{ + 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; + + supply_register_by_name ("pc", &newpc); +} + +/* Correct in either endianness. + This instruction is "twge r2, r2", which GDB uses as a software + breakpoint. */ +static const unsigned int ppc_breakpoint = 0x7d821008; +#define ppc_breakpoint_len 4 + +static int +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. */ + return 0; +} + +/* Provide only a fill function for the general register set. ps_lgetregs + will use this for NPTL support. */ + +static void ppc_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < 32; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); + + for (i = 64; i < 70; i++) + collect_register (i, (char *) buf + ppc_regmap[i]); +} + +#ifdef __ALTIVEC__ + +#ifndef PTRACE_GETVRREGS +#define PTRACE_GETVRREGS 18 +#define PTRACE_SETVRREGS 19 +#endif + +#define SIZEOF_VRREGS 33*16+4 + +static void +ppc_fill_vrregset (void *buf) +{ + int i, base; + char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + collect_register (base + i, ®set[i * 16]); + + collect_register_by_name ("vscr", ®set[32 * 16 + 12]); + collect_register_by_name ("vrsave", ®set[33 * 16]); +} + +static void +ppc_store_vrregset (const void *buf) +{ + int i, base; + const char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + supply_register (base + i, ®set[i * 16]); + + supply_register_by_name ("vscr", ®set[32 * 16 + 12]); + supply_register_by_name ("vrsave", ®set[33 * 16]); +} + +#endif /* __ALTIVEC__ */ + +struct regset_info target_regsets[] = { + /* List the extra register sets before GENERAL_REGS. That way we will + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ +#ifdef __ALTIVEC__ + { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS, + ppc_fill_vrregset, ppc_store_vrregset }, +#endif + { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL }, + { 0, 0, -1, -1, NULL, NULL } +}; + +struct linux_target_ops the_low_target = { + ppc_num_regs, + ppc_regmap, + ppc_cannot_fetch_register, + ppc_cannot_store_register, + ppc_get_pc, + ppc_set_pc, + (const unsigned char *) &ppc_breakpoint, + ppc_breakpoint_len, + NULL, + 0, + ppc_breakpoint_at, + NULL, + NULL, + NULL, + NULL, + 1 +};
linux-ppc64-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: win32-i386-low.c =================================================================== --- win32-i386-low.c (nonexistent) +++ win32-i386-low.c (revision 816) @@ -0,0 +1,205 @@ +/* Copyright (C) 2007, 2008 Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "win32-low.h" + +#define FCS_REGNUM 27 +#define FOP_REGNUM 31 + +#define FLAG_TRACE_BIT 0x100 + +static unsigned dr[8]; + +static int debug_registers_changed = 0; +static int debug_registers_used = 0; + +static void +i386_initial_stuff (void) +{ + memset (&dr, 0, sizeof (dr)); + debug_registers_changed = 0; + debug_registers_used = 0; +} + +static void +i386_get_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + th->context.ContextFlags = \ + CONTEXT_FULL | \ + CONTEXT_FLOATING_POINT | \ + CONTEXT_EXTENDED_REGISTERS | \ + CONTEXT_DEBUG_REGISTERS; + + GetThreadContext (th->h, &th->context); + + debug_registers_changed = 0; + + if (th->tid == current_event->dwThreadId) + { + /* Copy dr values from the current thread. */ + dr[0] = th->context.Dr0; + dr[1] = th->context.Dr1; + dr[2] = th->context.Dr2; + dr[3] = th->context.Dr3; + dr[6] = th->context.Dr6; + dr[7] = th->context.Dr7; + } +} + +static void +i386_set_thread_context (win32_thread_info *th, DEBUG_EVENT* current_event) +{ + if (debug_registers_changed) + { + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + } + + SetThreadContext (th->h, &th->context); +} + +static void +i386_thread_added (win32_thread_info *th) +{ + /* Set the debug registers for the new thread if they are used. */ + if (debug_registers_used) + { + th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + GetThreadContext (th->h, &th->context); + + th->context.Dr0 = dr[0]; + th->context.Dr1 = dr[1]; + th->context.Dr2 = dr[2]; + th->context.Dr3 = dr[3]; + /* th->context.Dr6 = dr[6]; + FIXME: should we set dr6 also ?? */ + th->context.Dr7 = dr[7]; + + SetThreadContext (th->h, &th->context); + th->context.ContextFlags = 0; + } +} + +static void +i386_single_step (win32_thread_info *th) +{ + th->context.EFlags |= FLAG_TRACE_BIT; +} + +/* An array of offset mappings into a Win32 Context structure. + This is a one-to-one mapping which is indexed by gdb's register + numbers. It retrieves an offset into the context structure where + the 4 byte register is located. + An offset value of -1 indicates that Win32 does not provide this + register in it's CONTEXT structure. In this case regptr will return + a pointer into a dummy register. */ +#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x)) +static const int mappings[] = { + context_offset (Eax), + context_offset (Ecx), + context_offset (Edx), + context_offset (Ebx), + context_offset (Esp), + context_offset (Ebp), + context_offset (Esi), + context_offset (Edi), + context_offset (Eip), + context_offset (EFlags), + context_offset (SegCs), + context_offset (SegSs), + context_offset (SegDs), + context_offset (SegEs), + context_offset (SegFs), + context_offset (SegGs), + context_offset (FloatSave.RegisterArea[0 * 10]), + context_offset (FloatSave.RegisterArea[1 * 10]), + context_offset (FloatSave.RegisterArea[2 * 10]), + context_offset (FloatSave.RegisterArea[3 * 10]), + context_offset (FloatSave.RegisterArea[4 * 10]), + context_offset (FloatSave.RegisterArea[5 * 10]), + context_offset (FloatSave.RegisterArea[6 * 10]), + context_offset (FloatSave.RegisterArea[7 * 10]), + context_offset (FloatSave.ControlWord), + context_offset (FloatSave.StatusWord), + context_offset (FloatSave.TagWord), + context_offset (FloatSave.ErrorSelector), + context_offset (FloatSave.ErrorOffset), + context_offset (FloatSave.DataSelector), + context_offset (FloatSave.DataOffset), + context_offset (FloatSave.ErrorSelector), + /* XMM0-7 */ + context_offset (ExtendedRegisters[10 * 16]), + context_offset (ExtendedRegisters[11 * 16]), + context_offset (ExtendedRegisters[12 * 16]), + context_offset (ExtendedRegisters[13 * 16]), + context_offset (ExtendedRegisters[14 * 16]), + context_offset (ExtendedRegisters[15 * 16]), + context_offset (ExtendedRegisters[16 * 16]), + context_offset (ExtendedRegisters[17 * 16]), + /* MXCSR */ + context_offset (ExtendedRegisters[24]) +}; +#undef context_offset + +/* Fetch register from gdbserver regcache data. */ +static void +i386_fetch_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = (char *) &th->context + mappings[r]; + + long l; + if (r == FCS_REGNUM) + { + l = *((long *) context_offset) & 0xffff; + supply_register (r, (char *) &l); + } + else if (r == FOP_REGNUM) + { + l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); + supply_register (r, (char *) &l); + } + else + supply_register (r, context_offset); +} + +/* Store a new register value into the thread context of TH. */ +static void +i386_store_inferior_register (win32_thread_info *th, int r) +{ + char *context_offset = (char *) &th->context + mappings[r]; + collect_register (r, context_offset); +} + +struct win32_target_ops the_low_target = { + sizeof (mappings) / sizeof (mappings[0]), + i386_initial_stuff, + i386_get_thread_context, + i386_set_thread_context, + i386_thread_added, + i386_fetch_inferior_register, + i386_store_inferior_register, + i386_single_step, + NULL, /* breakpoint */ + 0, /* breakpoint_len */ + "i386" /* arch_string */ +};
win32-i386-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: remote-utils.c =================================================================== --- remote-utils.c (nonexistent) +++ remote-utils.c (revision 816) @@ -0,0 +1,1244 @@ +/* Remote utility routines for the remote server for GDB. + Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +#include "server.h" +#include "terminal.h" +#include +#include +#if HAVE_SYS_IOCTL_H +#include +#endif +#if HAVE_SYS_FILE_H +#include +#endif +#if HAVE_NETINET_IN_H +#include +#endif +#if HAVE_SYS_SOCKET_H +#include +#endif +#if HAVE_NETDB_H +#include +#endif +#if HAVE_NETINET_TCP_H +#include +#endif +#if HAVE_SYS_IOCTL_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif +#if HAVE_FCNTL_H +#include +#endif +#include +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_ARPA_INET_H +#include +#endif +#include +#if HAVE_ERRNO_H +#include +#endif + +#if USE_WIN32API +#include +#endif + +#ifndef HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + +#if USE_WIN32API +# define INVALID_DESCRIPTOR INVALID_SOCKET +#else +# define INVALID_DESCRIPTOR -1 +#endif + +/* A cache entry for a successfully looked-up symbol. */ +struct sym_cache +{ + const char *name; + CORE_ADDR addr; + struct sym_cache *next; +}; + +/* The symbol cache. */ +static struct sym_cache *symbol_cache; + +/* If this flag has been set, assume cache misses are + failures. */ +int all_symbols_looked_up; + +int remote_debug = 0; +struct ui_file *gdb_stdlog; + +static int remote_desc = INVALID_DESCRIPTOR; + +/* FIXME headerize? */ +extern int using_threads; +extern int debug_threads; + +#ifdef USE_WIN32API +# define read(fd, buf, len) recv (fd, (char *) buf, len, 0) +# define write(fd, buf, len) send (fd, (char *) buf, len, 0) +#endif + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +void +remote_open (char *name) +{ +#if defined(F_SETFL) && defined (FASYNC) + int save_fcntl_flags; +#endif + char *port_str; + + port_str = strchr (name, ':'); + if (port_str == NULL) + { +#ifdef USE_WIN32API + error ("Only : is supported on this platform."); +#else + struct stat statbuf; + + if (stat (name, &statbuf) == 0 + && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode))) + remote_desc = open (name, O_RDWR); + else + { + errno = EINVAL; + remote_desc = -1; + } + + if (remote_desc < 0) + perror_with_name ("Could not open remote device"); + +#ifdef HAVE_TERMIOS + { + struct termios termios; + tcgetattr (remote_desc, &termios); + + termios.c_iflag = 0; + termios.c_oflag = 0; + termios.c_lflag = 0; + termios.c_cflag &= ~(CSIZE | PARENB); + termios.c_cflag |= CLOCAL | CS8; + termios.c_cc[VMIN] = 1; + termios.c_cc[VTIME] = 0; + + tcsetattr (remote_desc, TCSANOW, &termios); + } +#endif + +#ifdef HAVE_TERMIO + { + struct termio termio; + ioctl (remote_desc, TCGETA, &termio); + + termio.c_iflag = 0; + termio.c_oflag = 0; + termio.c_lflag = 0; + termio.c_cflag &= ~(CSIZE | PARENB); + termio.c_cflag |= CLOCAL | CS8; + termio.c_cc[VMIN] = 1; + termio.c_cc[VTIME] = 0; + + ioctl (remote_desc, TCSETA, &termio); + } +#endif + +#ifdef HAVE_SGTTY + { + struct sgttyb sg; + + ioctl (remote_desc, TIOCGETP, &sg); + sg.sg_flags = RAW; + ioctl (remote_desc, TIOCSETP, &sg); + } +#endif + + fprintf (stderr, "Remote debugging using %s\n", name); +#endif /* USE_WIN32API */ + } + else + { +#ifdef USE_WIN32API + static int winsock_initialized; +#endif + int port; + struct sockaddr_in sockaddr; + socklen_t tmp; + int tmp_desc; + char *port_end; + + port = strtoul (port_str + 1, &port_end, 10); + if (port_str[1] == '\0' || *port_end != '\0') + fatal ("Bad port argument: %s", name); + +#ifdef USE_WIN32API + if (!winsock_initialized) + { + WSADATA wsad; + + WSAStartup (MAKEWORD (1, 0), &wsad); + winsock_initialized = 1; + } +#endif + + tmp_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tmp_desc < 0) + perror_with_name ("Can't open socket"); + + /* Allow rapid reuse of this port. */ + tmp = 1; + setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, + sizeof (tmp)); + + sockaddr.sin_family = PF_INET; + sockaddr.sin_port = htons (port); + sockaddr.sin_addr.s_addr = INADDR_ANY; + + if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) + || listen (tmp_desc, 1)) + perror_with_name ("Can't bind address"); + + /* If port is zero, a random port will be selected, and the + fprintf below needs to know what port was selected. */ + if (port == 0) + { + socklen_t len = sizeof (sockaddr); + if (getsockname (tmp_desc, (struct sockaddr *) &sockaddr, &len) < 0 + || len < sizeof (sockaddr)) + perror_with_name ("Can't determine port"); + port = ntohs (sockaddr.sin_port); + } + + fprintf (stderr, "Listening on port %d\n", port); + fflush (stderr); + + tmp = sizeof (sockaddr); + remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp); + if (remote_desc == -1) + perror_with_name ("Accept failed"); + + /* Enable TCP keep alive process. */ + tmp = 1; + setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE, + (char *) &tmp, sizeof (tmp)); + + /* Tell TCP not to delay small packets. This greatly speeds up + interactive response. */ + tmp = 1; + setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY, + (char *) &tmp, sizeof (tmp)); + + +#ifndef USE_WIN32API + close (tmp_desc); /* No longer need this */ + + signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply + exits when the remote side dies. */ +#else + closesocket (tmp_desc); /* No longer need this */ +#endif + + /* Convert IP address to string. */ + fprintf (stderr, "Remote debugging from host %s\n", + inet_ntoa (sockaddr.sin_addr)); + } + +#if defined(F_SETFL) && defined (FASYNC) + save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0); + fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC); +#if defined (F_SETOWN) + fcntl (remote_desc, F_SETOWN, getpid ()); +#endif +#endif +} + +void +remote_close (void) +{ +#ifdef USE_WIN32API + closesocket (remote_desc); +#else + close (remote_desc); +#endif +} + +/* Convert hex digit A to a number. */ + +static int +fromhex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else + error ("Reply contains invalid hex digit"); + return 0; +} + +int +unhexify (char *bin, const char *hex, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + if (hex[0] == 0 || hex[1] == 0) + { + /* Hex string is short, or of uneven length. + Return the count that has been converted so far. */ + return i; + } + *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); + hex += 2; + } + return i; +} + +void +decode_address (CORE_ADDR *addrp, const char *start, int len) +{ + CORE_ADDR addr; + char ch; + int i; + + addr = 0; + for (i = 0; i < len; i++) + { + ch = start[i]; + addr = addr << 4; + addr = addr | (fromhex (ch) & 0x0f); + } + *addrp = addr; +} + +const char * +decode_address_to_semicolon (CORE_ADDR *addrp, const char *start) +{ + const char *end; + + end = start; + while (*end != '\0' && *end != ';') + end++; + + decode_address (addrp, start, end - start); + + if (*end == ';') + end++; + return end; +} + +/* Convert number NIB to a hex digit. */ + +static int +tohex (int nib) +{ + if (nib < 10) + return '0' + nib; + else + return 'a' + nib - 10; +} + +int +hexify (char *hex, const char *bin, int count) +{ + int i; + + /* May use a length, or a nul-terminated string as input. */ + if (count == 0) + count = strlen (bin); + + for (i = 0; i < count; i++) + { + *hex++ = tohex ((*bin >> 4) & 0xf); + *hex++ = tohex (*bin++ & 0xf); + } + *hex = 0; + return i; +} + +/* Convert BUFFER, binary data at least LEN bytes long, into escaped + binary data in OUT_BUF. Set *OUT_LEN to the length of the data + encoded in OUT_BUF, and return the number of bytes in OUT_BUF + (which may be more than *OUT_LEN due to escape characters). The + total number of bytes in the output buffer will be at most + OUT_MAXLEN. */ + +int +remote_escape_output (const gdb_byte *buffer, int len, + gdb_byte *out_buf, int *out_len, + int out_maxlen) +{ + int input_index, output_index; + + output_index = 0; + for (input_index = 0; input_index < len; input_index++) + { + gdb_byte b = buffer[input_index]; + + if (b == '$' || b == '#' || b == '}' || b == '*') + { + /* These must be escaped. */ + if (output_index + 2 > out_maxlen) + break; + out_buf[output_index++] = '}'; + out_buf[output_index++] = b ^ 0x20; + } + else + { + if (output_index + 1 > out_maxlen) + break; + out_buf[output_index++] = b; + } + } + + *out_len = input_index; + return output_index; +} + +/* Convert BUFFER, escaped data LEN bytes long, into binary data + in OUT_BUF. Return the number of bytes written to OUT_BUF. + Raise an error if the total number of bytes exceeds OUT_MAXLEN. + + This function reverses remote_escape_output. It allows more + escaped characters than that function does, in particular because + '*' must be escaped to avoid the run-length encoding processing + in reading packets. */ + +static int +remote_unescape_input (const gdb_byte *buffer, int len, + gdb_byte *out_buf, int out_maxlen) +{ + int input_index, output_index; + int escaped; + + output_index = 0; + escaped = 0; + for (input_index = 0; input_index < len; input_index++) + { + gdb_byte b = buffer[input_index]; + + if (output_index + 1 > out_maxlen) + error ("Received too much data from the target."); + + if (escaped) + { + out_buf[output_index++] = b ^ 0x20; + escaped = 0; + } + else if (b == '}') + escaped = 1; + else + out_buf[output_index++] = b; + } + + if (escaped) + error ("Unmatched escape character in target response."); + + return output_index; +} + +/* Look for a sequence of characters which can be run-length encoded. + If there are any, update *CSUM and *P. Otherwise, output the + single character. Return the number of characters consumed. */ + +static int +try_rle (char *buf, int remaining, unsigned char *csum, char **p) +{ + int n; + + /* Always output the character. */ + *csum += buf[0]; + *(*p)++ = buf[0]; + + /* Don't go past '~'. */ + if (remaining > 97) + remaining = 97; + + for (n = 1; n < remaining; n++) + if (buf[n] != buf[0]) + break; + + /* N is the index of the first character not the same as buf[0]. + buf[0] is counted twice, so by decrementing N, we get the number + of characters the RLE sequence will replace. */ + n--; + + if (n < 3) + return 1; + + /* Skip the frame characters. The manual says to skip '+' and '-' + also, but there's no reason to. Unfortunately these two unusable + characters double the encoded length of a four byte zero + value. */ + while (n + 29 == '$' || n + 29 == '#') + n--; + + *csum += '*'; + *(*p)++ = '*'; + *csum += n + 29; + *(*p)++ = n + 29; + + return n + 1; +} + +/* Send a packet to the remote machine, with error checking. + The data of the packet is in BUF, and the length of the + packet is in CNT. Returns >= 0 on success, -1 otherwise. */ + +int +putpkt_binary (char *buf, int cnt) +{ + int i; + unsigned char csum = 0; + char *buf2; + char buf3[1]; + char *p; + + buf2 = malloc (PBUFSIZ); + + /* Copy the packet into buffer BUF2, encapsulating it + and giving it a checksum. */ + + p = buf2; + *p++ = '$'; + + for (i = 0; i < cnt;) + i += try_rle (buf + i, cnt - i, &csum, &p); + + *p++ = '#'; + *p++ = tohex ((csum >> 4) & 0xf); + *p++ = tohex (csum & 0xf); + + *p = '\0'; + + /* Send it over and over until we get a positive ack. */ + + do + { + int cc; + + if (write (remote_desc, buf2, p - buf2) != p - buf2) + { + perror ("putpkt(write)"); + free (buf2); + return -1; + } + + if (remote_debug) + { + fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2); + fflush (stderr); + } + cc = read (remote_desc, buf3, 1); + if (remote_debug) + { + fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]); + fflush (stderr); + } + + if (cc <= 0) + { + if (cc == 0) + fprintf (stderr, "putpkt(read): Got EOF\n"); + else + perror ("putpkt(read)"); + + free (buf2); + return -1; + } + + /* Check for an input interrupt while we're here. */ + if (buf3[0] == '\003' && current_inferior != NULL) + (*the_target->request_interrupt) (); + } + while (buf3[0] != '+'); + + free (buf2); + return 1; /* Success! */ +} + +/* Send a packet to the remote machine, with error checking. The data + of the packet is in BUF, and the packet should be a NUL-terminated + string. Returns >= 0 on success, -1 otherwise. */ + +int +putpkt (char *buf) +{ + return putpkt_binary (buf, strlen (buf)); +} + +/* Come here when we get an input interrupt from the remote side. This + interrupt should only be active while we are waiting for the child to do + something. About the only thing that should come through is a ^C, which + will cause us to request child interruption. */ + +static void +input_interrupt (int unused) +{ + fd_set readset; + struct timeval immediate = { 0, 0 }; + + /* Protect against spurious interrupts. This has been observed to + be a problem under NetBSD 1.4 and 1.5. */ + + FD_ZERO (&readset); + FD_SET (remote_desc, &readset); + if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0) + { + int cc; + char c = 0; + + cc = read (remote_desc, &c, 1); + + if (cc != 1 || c != '\003' || current_inferior == NULL) + { + fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n", + cc, c, c); + return; + } + + (*the_target->request_interrupt) (); + } +} + +/* Check if the remote side sent us an interrupt request (^C). */ +void +check_remote_input_interrupt_request (void) +{ + /* This function may be called before establishing communications, + therefore we need to validate the remote descriptor. */ + + if (remote_desc == INVALID_DESCRIPTOR) + return; + + input_interrupt (0); +} + +/* Asynchronous I/O support. SIGIO must be enabled when waiting, in order to + accept Control-C from the client, and must be disabled when talking to + the client. */ + +static void +unblock_async_io (void) +{ +#ifndef USE_WIN32API + sigset_t sigio_set; + + sigemptyset (&sigio_set); + sigaddset (&sigio_set, SIGIO); + sigprocmask (SIG_UNBLOCK, &sigio_set, NULL); +#endif +} + +/* Current state of asynchronous I/O. */ +static int async_io_enabled; + +/* Enable asynchronous I/O. */ +void +enable_async_io (void) +{ + if (async_io_enabled) + return; + +#ifndef USE_WIN32API + signal (SIGIO, input_interrupt); +#endif + async_io_enabled = 1; +} + +/* Disable asynchronous I/O. */ +void +disable_async_io (void) +{ + if (!async_io_enabled) + return; + +#ifndef USE_WIN32API + signal (SIGIO, SIG_IGN); +#endif + async_io_enabled = 0; +} + +void +initialize_async_io (void) +{ + /* Make sure that async I/O starts disabled. */ + async_io_enabled = 1; + disable_async_io (); + + /* Make sure the signal is unblocked. */ + unblock_async_io (); +} + +/* Returns next char from remote GDB. -1 if error. */ + +static int +readchar (void) +{ + static unsigned char buf[BUFSIZ]; + static int bufcnt = 0; + static unsigned char *bufp; + + if (bufcnt-- > 0) + return *bufp++; + + bufcnt = read (remote_desc, buf, sizeof (buf)); + + if (bufcnt <= 0) + { + if (bufcnt == 0) + fprintf (stderr, "readchar: Got EOF\n"); + else + perror ("readchar"); + + return -1; + } + + bufp = buf; + bufcnt--; + return *bufp++; +} + +/* Read a packet from the remote machine, with error checking, + and store it in BUF. Returns length of packet, or negative if error. */ + +int +getpkt (char *buf) +{ + char *bp; + unsigned char csum, c1, c2; + int c; + + while (1) + { + csum = 0; + + while (1) + { + c = readchar (); + if (c == '$') + break; + if (remote_debug) + { + fprintf (stderr, "[getpkt: discarding char '%c']\n", c); + fflush (stderr); + } + + if (c < 0) + return -1; + } + + bp = buf; + while (1) + { + c = readchar (); + if (c < 0) + return -1; + if (c == '#') + break; + *bp++ = c; + csum += c; + } + *bp = 0; + + c1 = fromhex (readchar ()); + c2 = fromhex (readchar ()); + + if (csum == (c1 << 4) + c2) + break; + + fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", + (c1 << 4) + c2, csum, buf); + write (remote_desc, "-", 1); + } + + if (remote_debug) + { + fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf); + fflush (stderr); + } + + write (remote_desc, "+", 1); + + if (remote_debug) + { + fprintf (stderr, "[sent ack]\n"); + fflush (stderr); + } + + return bp - buf; +} + +void +write_ok (char *buf) +{ + buf[0] = 'O'; + buf[1] = 'K'; + buf[2] = '\0'; +} + +void +write_enn (char *buf) +{ + /* Some day, we should define the meanings of the error codes... */ + buf[0] = 'E'; + buf[1] = '0'; + buf[2] = '1'; + buf[3] = '\0'; +} + +void +convert_int_to_ascii (unsigned char *from, char *to, int n) +{ + int nib; + int ch; + while (n--) + { + ch = *from++; + nib = ((ch & 0xf0) >> 4) & 0x0f; + *to++ = tohex (nib); + nib = ch & 0x0f; + *to++ = tohex (nib); + } + *to++ = 0; +} + + +void +convert_ascii_to_int (char *from, unsigned char *to, int n) +{ + int nib1, nib2; + while (n--) + { + nib1 = fromhex (*from++); + nib2 = fromhex (*from++); + *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f); + } +} + +static char * +outreg (int regno, char *buf) +{ + if ((regno >> 12) != 0) + *buf++ = tohex ((regno >> 12) & 0xf); + if ((regno >> 8) != 0) + *buf++ = tohex ((regno >> 8) & 0xf); + *buf++ = tohex ((regno >> 4) & 0xf); + *buf++ = tohex (regno & 0xf); + *buf++ = ':'; + collect_register_as_string (regno, buf); + buf += 2 * register_size (regno); + *buf++ = ';'; + + return buf; +} + +void +new_thread_notify (int id) +{ + char own_buf[256]; + + /* The `n' response is not yet part of the remote protocol. Do nothing. */ + if (1) + return; + + if (server_waiting == 0) + return; + + sprintf (own_buf, "n%x", id); + disable_async_io (); + putpkt (own_buf); + enable_async_io (); +} + +void +dead_thread_notify (int id) +{ + char own_buf[256]; + + /* The `x' response is not yet part of the remote protocol. Do nothing. */ + if (1) + return; + + sprintf (own_buf, "x%x", id); + disable_async_io (); + putpkt (own_buf); + enable_async_io (); +} + +void +prepare_resume_reply (char *buf, char status, unsigned char sig) +{ + int nib; + + *buf++ = status; + + nib = ((sig & 0xf0) >> 4); + *buf++ = tohex (nib); + nib = sig & 0x0f; + *buf++ = tohex (nib); + + if (status == 'T') + { + const char **regp = gdbserver_expedite_regs; + + if (the_target->stopped_by_watchpoint != NULL + && (*the_target->stopped_by_watchpoint) ()) + { + CORE_ADDR addr; + int i; + + strncpy (buf, "watch:", 6); + buf += 6; + + addr = (*the_target->stopped_data_address) (); + + /* Convert each byte of the address into two hexadecimal chars. + Note that we take sizeof (void *) instead of sizeof (addr); + this is to avoid sending a 64-bit address to a 32-bit GDB. */ + for (i = sizeof (void *) * 2; i > 0; i--) + { + *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf); + } + *buf++ = ';'; + } + + while (*regp) + { + buf = outreg (find_regno (*regp), buf); + regp ++; + } + + /* Formerly, if the debugger had not used any thread features we would not + burden it with a thread status response. This was for the benefit of + GDB 4.13 and older. However, in recent GDB versions the check + (``if (cont_thread != 0)'') does not have the desired effect because of + sillyness in the way that the remote protocol handles specifying a thread. + Since thread support relies on qSymbol support anyway, assume GDB can handle + threads. */ + + if (using_threads) + { + unsigned int gdb_id_from_wait; + + /* FIXME right place to set this? */ + thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; + gdb_id_from_wait = thread_to_gdb_id (current_inferior); + + if (debug_threads) + fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait); + /* This if (1) ought to be unnecessary. But remote_wait in GDB + will claim this event belongs to inferior_ptid if we do not + specify a thread, and there's no way for gdbserver to know + what inferior_ptid is. */ + if (1 || old_thread_from_wait != thread_from_wait) + { + general_thread = thread_from_wait; + sprintf (buf, "thread:%x;", gdb_id_from_wait); + buf += strlen (buf); + old_thread_from_wait = thread_from_wait; + } + } + + if (dlls_changed) + { + strcpy (buf, "library:;"); + buf += strlen (buf); + dlls_changed = 0; + } + } + /* For W and X, we're done. */ + *buf++ = 0; +} + +void +decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr) +{ + int i = 0, j = 0; + char ch; + *mem_addr_ptr = *len_ptr = 0; + + while ((ch = from[i++]) != ',') + { + *mem_addr_ptr = *mem_addr_ptr << 4; + *mem_addr_ptr |= fromhex (ch) & 0x0f; + } + + for (j = 0; j < 4; j++) + { + if ((ch = from[i++]) == 0) + break; + *len_ptr = *len_ptr << 4; + *len_ptr |= fromhex (ch) & 0x0f; + } +} + +void +decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr, + unsigned char *to) +{ + int i = 0; + char ch; + *mem_addr_ptr = *len_ptr = 0; + + while ((ch = from[i++]) != ',') + { + *mem_addr_ptr = *mem_addr_ptr << 4; + *mem_addr_ptr |= fromhex (ch) & 0x0f; + } + + while ((ch = from[i++]) != ':') + { + *len_ptr = *len_ptr << 4; + *len_ptr |= fromhex (ch) & 0x0f; + } + + convert_ascii_to_int (&from[i++], to, *len_ptr); +} + +int +decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr, + unsigned int *len_ptr, unsigned char *to) +{ + int i = 0; + char ch; + *mem_addr_ptr = *len_ptr = 0; + + while ((ch = from[i++]) != ',') + { + *mem_addr_ptr = *mem_addr_ptr << 4; + *mem_addr_ptr |= fromhex (ch) & 0x0f; + } + + while ((ch = from[i++]) != ':') + { + *len_ptr = *len_ptr << 4; + *len_ptr |= fromhex (ch) & 0x0f; + } + + if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i, + to, *len_ptr) != *len_ptr) + return -1; + + return 0; +} + +/* Decode a qXfer write request. */ +int +decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset, + unsigned int *len, unsigned char *data) +{ + char ch; + + /* Extract and NUL-terminate the annex. */ + *annex = buf; + while (*buf && *buf != ':') + buf++; + if (*buf == '\0') + return -1; + *buf++ = 0; + + /* Extract the offset. */ + *offset = 0; + while ((ch = *buf++) != ':') + { + *offset = *offset << 4; + *offset |= fromhex (ch) & 0x0f; + } + + /* Get encoded data. */ + packet_len -= buf - *annex; + *len = remote_unescape_input ((const gdb_byte *) buf, packet_len, + data, packet_len); + return 0; +} + +/* Ask GDB for the address of NAME, and return it in ADDRP if found. + Returns 1 if the symbol is found, 0 if it is not, -1 on error. */ + +int +look_up_one_symbol (const char *name, CORE_ADDR *addrp) +{ + char own_buf[266], *p, *q; + int len; + struct sym_cache *sym; + + /* Check the cache first. */ + for (sym = symbol_cache; sym; sym = sym->next) + if (strcmp (name, sym->name) == 0) + { + *addrp = sym->addr; + return 1; + } + + /* If we've passed the call to thread_db_look_up_symbols, then + anything not in the cache must not exist; we're not interested + in any libraries loaded after that point, only in symbols in + libpthread.so. It might not be an appropriate time to look + up a symbol, e.g. while we're trying to fetch registers. */ + if (all_symbols_looked_up) + return 0; + + /* Send the request. */ + strcpy (own_buf, "qSymbol:"); + hexify (own_buf + strlen ("qSymbol:"), name, strlen (name)); + if (putpkt (own_buf) < 0) + return -1; + + /* FIXME: Eventually add buffer overflow checking (to getpkt?) */ + len = getpkt (own_buf); + 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 + symbol. */ + 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) + { + warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf); + return -1; + } + + p = own_buf + strlen ("qSymbol:"); + q = p; + while (*q && *q != ':') + q++; + + /* Make sure we found a value for the symbol. */ + if (p == q || *q == '\0') + return 0; + + decode_address (addrp, p, q - p); + + /* Save the symbol in our cache. */ + sym = malloc (sizeof (*sym)); + sym->name = strdup (name); + sym->addr = *addrp; + sym->next = symbol_cache; + symbol_cache = sym; + + return 1; +} + +void +monitor_output (const char *msg) +{ + char *buf = malloc (strlen (msg) * 2 + 2); + + buf[0] = 'O'; + hexify (buf + 1, msg, 0); + + putpkt (buf); + free (buf); +} + +/* Return a malloc allocated string with special characters from TEXT + replaced by entity references. */ + +char * +xml_escape_text (const char *text) +{ + char *result; + int i, special; + + /* Compute the length of the result. */ + for (i = 0, special = 0; text[i] != '\0'; i++) + switch (text[i]) + { + case '\'': + case '\"': + special += 5; + break; + case '&': + special += 4; + break; + case '<': + case '>': + special += 3; + break; + default: + break; + } + + /* Expand the result. */ + result = malloc (i + special + 1); + for (i = 0, special = 0; text[i] != '\0'; i++) + switch (text[i]) + { + case '\'': + strcpy (result + i + special, "'"); + special += 5; + break; + case '\"': + strcpy (result + i + special, """); + special += 5; + break; + case '&': + strcpy (result + i + special, "&"); + special += 4; + break; + case '<': + strcpy (result + i + special, "<"); + special += 3; + break; + case '>': + strcpy (result + i + special, ">"); + special += 3; + break; + default: + result[i + special] = text[i]; + break; + } + result[i + special] = '\0'; + + return result; +}
remote-utils.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: linux-s390-low.c =================================================================== --- linux-s390-low.c (nonexistent) +++ linux-s390-low.c (revision 816) @@ -0,0 +1,139 @@ +/* GNU/Linux S/390 specific low level interface, for the remote server + for GDB. + Copyright (C) 2001, 2002, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. + + 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 3 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, see . */ + +/* This file is used for both 31-bit and 64-bit S/390 systems. */ + +#include "server.h" +#include "linux-low.h" + +#include + +#define s390_num_regs 51 + +static int s390_regmap[] = { + PT_PSWMASK, PT_PSWADDR, + + PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3, + PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, + PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, + PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15, + + PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3, + PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7, + PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11, + PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15, + + PT_FPC, + +#ifndef __s390x__ + PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI, + PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI, + PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI, + PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI, +#else + PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3, + PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7, + PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11, + PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15, +#endif +}; + +static int +s390_cannot_fetch_register (int regno) +{ + if (s390_regmap[regno] == -1) + return 1; + + return 0; +} + +static int +s390_cannot_store_register (int regno) +{ + if (s390_regmap[regno] == -1) + return 1; + + return 0; +} + +/* Provide only a fill function for the general register set. ps_lgetregs + will use this for NPTL support. */ + +static void s390_fill_gregset (void *buf) +{ + int i; + + for (i = 0; i < 34; i++) + collect_register (i, (char *) buf + s390_regmap[i]); +} + +struct regset_info target_regsets[] = { + { 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL }, + { 0, 0, -1, -1, NULL, NULL } +}; + + +static const unsigned char s390_breakpoint[] = { 0, 1 }; +#define s390_breakpoint_len 2 + +static CORE_ADDR +s390_get_pc () +{ + unsigned long pc; + collect_register_by_name ("pswa", &pc); +#ifndef __s390x__ + pc &= 0x7fffffff; +#endif + return pc; +} + +static void +s390_set_pc (CORE_ADDR newpc) +{ + unsigned long pc = newpc; +#ifndef __s390x__ + pc |= 0x80000000; +#endif + supply_register_by_name ("pswa", &pc); +} + +static int +s390_breakpoint_at (CORE_ADDR pc) +{ + unsigned char c[s390_breakpoint_len]; + read_inferior_memory (pc, c, s390_breakpoint_len); + return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0; +} + + +struct linux_target_ops the_low_target = { + s390_num_regs, + s390_regmap, + s390_cannot_fetch_register, + s390_cannot_store_register, + s390_get_pc, + s390_set_pc, + s390_breakpoint, + s390_breakpoint_len, + NULL, + s390_breakpoint_len, + s390_breakpoint_at, +}; +
linux-s390-low.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: target.h =================================================================== --- target.h (nonexistent) +++ target.h (revision 816) @@ -0,0 +1,234 @@ +/* Target operations for the remote server for GDB. + Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 + Free Software Foundation, Inc. + + Contributed by MontaVista Software. + + 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 3 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, see . */ + +#ifndef TARGET_H +#define TARGET_H + +/* This structure describes how to resume a particular thread (or + all threads) based on the client's request. If thread is -1, then + this entry applies to all threads. These are generally passed around + as an array, and terminated by a thread == -1 entry. */ + +struct thread_resume +{ + unsigned long thread; + + /* If non-zero, leave this thread stopped. */ + int leave_stopped; + + /* If non-zero, we want to single-step. */ + int step; + + /* If non-zero, send this signal when we resume. */ + int sig; +}; + +struct target_ops +{ + /* Start a new process. + + PROGRAM is a path to the program to execute. + ARGS is a standard NULL-terminated array of arguments, + to be passed to the inferior as ``argv''. + + Returns the new PID on success, -1 on failure. Registers the new + process with the process list. */ + + int (*create_inferior) (char *program, char **args); + + /* Attach to a running process. + + PID is the process ID to attach to, specified by the user + or a higher layer. + + Returns -1 if attaching is unsupported, 0 on success, and calls + error() otherwise. */ + + int (*attach) (unsigned long pid); + + /* Kill all inferiors. */ + + void (*kill) (void); + + /* Detach from all inferiors. + Return -1 on failure, and 0 on success. */ + + int (*detach) (void); + + /* Wait for inferiors to end. */ + + void (*join) (void); + + /* Return 1 iff the thread with process ID PID is alive. */ + + int (*thread_alive) (unsigned long pid); + + /* Resume the inferior process. */ + + void (*resume) (struct thread_resume *resume_info); + + /* Wait for the inferior process to change state. + + STATUS will be filled in with a response code to send to GDB. + + Returns the signal which caused the process to stop, in the + remote protocol numbering (e.g. TARGET_SIGNAL_STOP), or the + exit code as an integer if *STATUS is 'W'. */ + + unsigned char (*wait) (char *status); + + /* Fetch registers from the inferior process. + + If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */ + + void (*fetch_registers) (int regno); + + /* Store registers to the inferior process. + + If REGNO is -1, store all registers; otherwise, store at least REGNO. */ + + void (*store_registers) (int regno); + + /* Read memory from the inferior process. This should generally be + called through read_inferior_memory, which handles breakpoint shadowing. + + Read LEN bytes at MEMADDR into a buffer at MYADDR. + + Returns 0 on success and errno on failure. */ + + int (*read_memory) (CORE_ADDR memaddr, unsigned char *myaddr, int len); + + /* Write memory to the inferior process. This should generally be + called through write_inferior_memory, which handles breakpoint shadowing. + + Write LEN bytes from the buffer at MYADDR to MEMADDR. + + Returns 0 on success and errno on failure. */ + + int (*write_memory) (CORE_ADDR memaddr, const unsigned char *myaddr, + int len); + + /* Query GDB for the values of any symbols we're interested in. + This function is called whenever we receive a "qSymbols::" + query, which corresponds to every time more symbols (might) + become available. NULL if we aren't interested in any + symbols. */ + + void (*look_up_symbols) (void); + + /* Send an interrupt request to the inferior process, + however is appropriate. */ + + void (*request_interrupt) (void); + + /* Read auxiliary vector data from the inferior process. + + Read LEN bytes at OFFSET into a buffer at MYADDR. */ + + int (*read_auxv) (CORE_ADDR offset, unsigned char *myaddr, + unsigned int len); + + /* Insert and remove a hardware watchpoint. + Returns 0 on success, -1 on failure and 1 on unsupported. + The type is coded as follows: + 2 = write watchpoint + 3 = read watchpoint + 4 = access watchpoint + */ + + int (*insert_watchpoint) (char type, CORE_ADDR addr, int len); + int (*remove_watchpoint) (char type, CORE_ADDR addr, int len); + + /* Returns 1 if target was stopped due to a watchpoint hit, 0 otherwise. */ + + int (*stopped_by_watchpoint) (void); + + /* Returns the address associated with the watchpoint that hit, if any; + returns 0 otherwise. */ + + CORE_ADDR (*stopped_data_address) (void); + + /* Reports the text, data offsets of the executable. This is + needed for uclinux where the executable is relocated during load + time. */ + + int (*read_offsets) (CORE_ADDR *text, CORE_ADDR *data); + + /* Fetch the address associated with a specific thread local storage + area, determined by the specified THREAD, OFFSET, and LOAD_MODULE. + Stores it in *ADDRESS and returns zero on success; otherwise returns + an error code. A return value of -1 means this system does not + support the operation. */ + + int (*get_tls_address) (struct thread_info *thread, CORE_ADDR offset, + CORE_ADDR load_module, CORE_ADDR *address); + + /* Return a string identifying the current architecture, or NULL if + this operation is not supported. */ + const char *(*arch_string) (void); + + /* Read/Write from/to spufs using qXfer packets. */ + int (*qxfer_spu) (const char *annex, unsigned char *readbuf, + unsigned const char *writebuf, CORE_ADDR offset, int len); + + /* Fill BUF with an hostio error packet representing the last hostio + error. */ + void (*hostio_last_error) (char *buf); +}; + +extern struct target_ops *the_target; + +void set_target_ops (struct target_ops *); + +#define create_inferior(program, args) \ + (*the_target->create_inferior) (program, args) + +#define myattach(pid) \ + (*the_target->attach) (pid) + +#define kill_inferior() \ + (*the_target->kill) () + +#define detach_inferior() \ + (*the_target->detach) () + +#define mythread_alive(pid) \ + (*the_target->thread_alive) (pid) + +#define fetch_inferior_registers(regno) \ + (*the_target->fetch_registers) (regno) + +#define store_inferior_registers(regno) \ + (*the_target->store_registers) (regno) + +#define join_inferior() \ + (*the_target->join) () + +unsigned char mywait (char *statusp, int connected_wait); + +int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len); + +int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr, + int len); + +void set_desired_inferior (int id); + +#endif /* TARGET_H */
target.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.