This commit was generated by cvs2svn to compensate for changes in r104990,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Mark Peek 2002-10-12 17:47:36 +00:00
commit ba3e1918be
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=104991
19 changed files with 1068 additions and 317 deletions

View File

@ -54,7 +54,7 @@ libstdcxx_flags='`case $$dir in libstdc++-v3 | libjava) ;; *) test ! -f $$r/$(TA
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
# know that we are building the simulator.
host_tools="texinfo byacc flex bison binutils ld gas gcc cgen sid sim gdb make patch prms send-pr gprof gdbtest tgas etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool ispell grep diff rcs cvssrc fileutils shellutils time textutils wdiff find emacs emacs19 uudecode hello tar gzip indent recode release sed utils guile perl apache inet gawk findutils snavigator libtool gettext zip"
host_tools="byacc flex bison binutils ld gas gcc cgen sid sim gdb make patch prms send-pr gprof gdbtest tgas etc expect dejagnu ash bash bzip2 m4 autoconf automake libtool ispell grep diff rcs cvssrc fileutils shellutils time textutils wdiff find emacs emacs19 uudecode hello tar gzip indent recode release sed utils guile perl apache inet gawk findutils snavigator libtool gettext zip"
# these libraries are built for the target environment, and are built after
# the host libraries and the host tools (which may be a cross compiler)

View File

@ -1,3 +1,108 @@
2002-07-19 GDB Administrator <gdbadmin@sourceware.cygnus.com>
GDB 5.2.1 released.
* version.in: Bump to version 5.2.1
* README, NEWS: Update to refer to GDB 5.2.1.
2002-07-19 Andrew Cagney <ac131313@redhat.com>
* Makefile.in (x86-64-tdep.o): Add $(objfiles_h).
* x86-64-tdep.c: Include "objfiles.h".
(x86_64_gdbarch_init): Set in_solib_call_trampoline to
in_plt_section. From 2002-07-18 Michal Ludvig <mludvig@suse.cz>.
2002-07-15 Andrew Cagney <ac131313@redhat.com>
From Gerhard Tonn <TON@de.ibm.com>:
* s390-nat.c (fill_fpregset, fill_gregset): Use regcache_collect
instead of supply_register.
2002-07-15 Andrew Cagney <ac131313@redhat.com>
* dwarf2cfi.c: Replace __func__ with "?func?".
2002-07-09 David O'Brien <obrien@FreeBSD.org>
Merge from mainline:
* gdbserver/gdbreplay.c: Include needed system headers.
(remote_open): Conditional strchr prototype.
(perror_with_name, remote_close, remote_open, expect, play): Static.
2002-07-09 Michal Ludvig <mludvig@suse.cz>
* NEWS: Note about dwarf2cfi improvements.
2002-07-09 Pierre Muller <muller@ics.u-strasbg.fr>
Merge from mainline:
2002-07-04 Pierre Muller <muller@ics.u-strasbg.fr>
* i386-nat.c (child_post_startup_inferior): New function
calling i386_cleanup_dregs if
I386_USE_GENERIC_WATCHPOINTS is defined.
* config/i386/nm-i386.h: define CHILD_POST_STARTUP_INFERIOR
conditional to acknowledge that i386-nat.c has its
own child_post_startup_inferior function.
2002-07-03 Michal Ludvig <mludvig@suse.cz>
Merge from mainline:
2002-06-21 Michal Ludvig <mludvig@suse.cz>
* dwarf2cfi.c (read_encoded_pointer): Don't handle pointer
encoding anymore.
(pointer_encoding, enum ptr_encoding): New.
(execute_cfa_program): Take care about pointer encoding.
(dwarf2_build_frame_info): Only call parse_frame_info for
.debug_frame and .eh_frame.
(parse_frame_info): New, derived from former dwarf2_build_frame_info.
fixed augmentation handling, added relative addressing,
ignore duplicate FDEs. Added comments.
* dwarf2cfi.c: Reindented.
2002-06-20 Michal Ludvig <mludvig@suse.cz>
* x86-64-tdep.c (x86_64_register_nr2name): Rename to
x86_64_register_name. Return type changed to 'const char *'.
(x86_64_register_name2nr): Rename to x86_64_register_number.
(x86_64_gdbarch_init): Update to reflect the change.
* x86-64-tdep.h: Ditto.
* x86-64-linux-nat.c (x86_64_fxsave_offset)
(supply_fpregset): Ditto.
2002-06-11 Michal Ludvig <mludvig@suse.cz>
* dwarf2cfi.c (unwind_tmp_obstack_init): New.
(unwind_tmp_obstack_free, parse_frame_info)
(update_context, cfi_read_fp, cfi_write_fp)
(cfi_frame_chain, cfi_init_extra_frame_info)
(cfi_virtual_frame_pointer): Use the above function.
* x86-64-tdep.c (x86_64_skip_prologue): Fix to work on functions
without debug information too.
2002-06-07 Michal Ludvig <mludvig@suse.cz>
* x86-64-linux-nat.c (x86_64_fxsave_offset): New.
(supply_fpregset, fill_fpregset): Don't call i387_*_fxsave,
better do the things actually here.
* x86-64-tdep.c (x86_64_register_name2nr): New.
(x86_64_register_name): Renamed to x86_64_register_nr2name.
(x86_64_gdbarch_init): Respect the above change.
* x86-64-tdep.h (x86_64_register_name2nr)
(x86_64_register_nr2name): Add prototypes.
* config/i386/x86-64linux.mt (TDEPFILES): Remove i387-tdep.o.
2002-06-28 Andrew Cagney <ac131313@redhat.com>
* Makefile.in (objfiles_h): Add $(bcache_h).
* objfiles.h: Include "bcache.h".
* Makefile.in (symtab_h): Remove $(bcache_h).
* symtab.h: Do not include "bcache.h".
2002-06-28 David O'Brien <obrien@FreeBSD.org>
Merge from mainline:
* config/i386/nm-fbsd.h: Include <sys/param.h>.
* config/i386/tm-fbsd.h: Likewise.
2002-06-22 Andrew Cagney <ac131313@redhat.com>
* NEWS: Mention below.

View File

@ -624,7 +624,7 @@ language_h = language.h
linespec_h = linespec.h
memattr_h = memattr.h
monitor_h = monitor.h
objfiles_h = objfiles.h
objfiles_h = objfiles.h $(bcache_h)
parser_defs_h = parser-defs.h $(doublest_h)
regcache_h = regcache.h
remote_h = remote.h
@ -635,7 +635,7 @@ solist_h = solist.h
source_h = source.h
stabsread_h = stabsread.h
symfile_h = symfile.h
symtab_h = symtab.h $(bcache_h)
symtab_h = symtab.h
target_h = target.h $(bfd_h) $(symtab_h) $(dcache_h) $(memattr_h)
terminal_h = terminal.h
top_h = top.h
@ -2135,9 +2135,9 @@ vax-tdep.o: vax-tdep.c $(OP_INCLUDE)/vax.h $(defs_h) $(symtab_h)
x86-64-linux-tdep.o : x86-64-linux-tdep.c $(defs_h) $(inferior_h) \
$(gdbcore_h) $(regcache_h) x86-64-tdep.h i386-tdep.h $(dwarf2cfi_h)
x86-64-tdep.o : x86-64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) $(gdbcmd_h) \
$(arch_utils_h) $(regcache_h) $(symfile_h) x86-64-tdep.h i386-tdep.h \
$(dwarf2cfi_h) gdb_assert.h
x86-64-tdep.o : x86-64-tdep.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdbcmd_h) $(arch_utils_h) $(regcache_h) $(symfile_h) x86-64-tdep.h \
i386-tdep.h $(dwarf2cfi_h) gdb_assert.h $(objfiles_h)
x86-64-linux-nat.o : x86-64-linux-nat.c $(defs_h) $(inferior_h) \
$(gdbcore_h) $(regcache_h) i387-nat.h gdb_assert.h x86-64-tdep.h \

View File

@ -1,7 +1,7 @@
What has changed in GDB?
(Organized release by release)
*** Changes since GDB 5.2:
*** Changes in GDB 5.2.1:
* New targets.
@ -17,6 +17,14 @@ gdb/439: gdb/291: On some ELF object files, gdb was reporting:
dwarf2read.c:1072: gdb-internal-error: sect_index_text not initialize
Fix, by Fred Fish, imported from mainline.
Dwarf2 .debug_frame & .eh_frame handler improved in many ways.
Surprisingly enough, it works now.
By Michal Ludvig, imported from mainline.
i386 hardware watchpoint support:
avoid misses on second run for some targets.
By Pierre Muller, imported from mainline.
*** Changes in GDB 5.2:
* New command "set trust-readonly-sections on[off]".

View File

@ -1,5 +1,5 @@
README for gdb-5.2 release
Updated 17 April, 2002 by Andrew Cagney
README for gdb-5.2.1 release
Updated 19 July, 2002 by Andrew Cagney
This is GDB, the GNU source-level debugger.
@ -20,7 +20,7 @@ Unpacking and Installation -- quick overview
In this release, the GDB debugger sources, the generic GNU include
files, the BFD ("binary file description") library, the readline
library, and other libraries all have directories of their own
underneath the gdb-5.2 directory. The idea is that a variety of GNU
underneath the gdb-5.2.1 directory. The idea is that a variety of GNU
tools can share a common copy of these things. Be aware of variation
over time--for example don't try to build gdb with a copy of bfd from
a release other than the gdb release (such as a binutils release),
@ -29,8 +29,8 @@ Configuration scripts and makefiles exist to cruise up and down this
directory tree and automatically build all the pieces in the right
order.
When you unpack the gdb-5.2.tar.gz file, you'll find a directory
called `gdb-5.2', which contains:
When you unpack the gdb-5.2.1.tar.gz file, you'll find a directory
called `gdb-5.2.1', which contains:
COPYING config.sub intl missing opcodes
COPYING.LIB configure libiberty mkinstalldirs readline
@ -44,7 +44,7 @@ called `gdb-5.2', which contains:
You can build GDB right in the source directory:
cd gdb-5.2
cd gdb-5.2.1
./configure
make
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
@ -58,12 +58,12 @@ You can build GDB in any empty build directory:
mkdir build
cd build
<full path to your sources>/gdb-5.2/configure
<full path to your sources>/gdb-5.2.1/configure
make
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
(Building GDB with DJGPP tools for MS-DOS/MS-Windows is slightly
different; see the file gdb-5.2/gdb/config/djgpp/README for details.)
different; see the file gdb-5.2.1/gdb/config/djgpp/README for details.)
This will configure and build all the libraries as well as GDB. If
`configure' can't determine your system type, specify one as its
@ -94,7 +94,7 @@ documentation and TeX (or `texi2roff') to typeset the printed version.
GDB includes an already formatted copy of the on-line Info version
of this manual in the `gdb/doc' subdirectory. The main Info file is
`gdb-5.2/gdb/doc/gdb.info', and it refers to subordinate files
`gdb-5.2.1/gdb/doc/gdb.info', and it refers to subordinate files
matching `gdb.info*' in the same directory. If necessary, you can
print out these files, or read them with any editor; but they are
easier to read using the `info' subsystem in GNU Emacs or the
@ -106,7 +106,7 @@ Info formatting programs, such as `texinfo-format-buffer' or
`makeinfo'.
If you have `makeinfo' installed, and are in the top level GDB
source directory (`gdb-5.2', in the case of version 5.2), you can make
source directory (`gdb-5.2.1', in the case of version 5.2.1), you can make
the Info file by typing:
cd gdb/doc
@ -115,7 +115,7 @@ the Info file by typing:
If you want to typeset and print copies of this manual, you need
TeX, a program to print its DVI output files, and `texinfo.tex', the
Texinfo definitions file. This file is included in the GDB
distribution, in the directory `gdb-5.2/texinfo'.
distribution, in the directory `gdb-5.2.1/texinfo'.
TeX is a typesetting program; it does not print files directly, but
produces output files called DVI files. To print a typeset document,
@ -129,11 +129,11 @@ without any extension or a `.dvi' extension.
This file tells TeX how to typeset a document written in Texinfo
format. On its own, TeX cannot read, much less typeset a Texinfo file.
`texinfo.tex' is distributed with GDB and is located in the
`gdb-5.2/texinfo' directory.
`gdb-5.2.1/texinfo' directory.
If you have TeX and a DVI printer program installed, you can typeset
and print this manual. First switch to the the `gdb' subdirectory of
the main source directory (for example, to `gdb-5.2/gdb') and then type:
the main source directory (for example, to `gdb-5.2.1/gdb') and then type:
make doc/gdb.dvi
@ -156,55 +156,55 @@ preparing GDB for installation; you can then use `make' to build the
a single directory, whose name is usually composed by appending the
version number to `gdb'.
For example, the GDB version 5.2 distribution is in the `gdb-5.2'
For example, the GDB version 5.2.1 distribution is in the `gdb-5.2.1'
directory. That directory contains:
`gdb-5.2/{COPYING,COPYING.LIB}'
`gdb-5.2.1/{COPYING,COPYING.LIB}'
Standard GNU license files. Please read them.
`gdb-5.2/bfd'
`gdb-5.2.1/bfd'
source for the Binary File Descriptor library
`gdb-5.2/config*'
`gdb-5.2.1/config*'
script for configuring GDB, along with other support files
`gdb-5.2/gdb'
`gdb-5.2.1/gdb'
the source specific to GDB itself
`gdb-5.2/include'
`gdb-5.2.1/include'
GNU include files
`gdb-5.2/libiberty'
`gdb-5.2.1/libiberty'
source for the `-liberty' free software library
`gdb-5.2/mmalloc'
`gdb-5.2.1/mmalloc'
source for the GNU memory-mapped malloc package
`gdb-5.2/opcodes'
`gdb-5.2.1/opcodes'
source for the library of opcode tables and disassemblers
`gdb-5.2/readline'
`gdb-5.2.1/readline'
source for the GNU command-line interface
NOTE: The readline library is compiled for use by GDB, but will
not be installed on your system when "make install" is issued.
`gdb-5.2/sim'
`gdb-5.2.1/sim'
source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc)
`gdb-5.2/intl'
`gdb-5.2.1/intl'
source for the GNU gettext library, for internationalization.
This is slightly modified from the standalone gettext
distribution you can get from GNU.
`gdb-5.2/texinfo'
`gdb-5.2.1/texinfo'
The `texinfo.tex' file, which you need in order to make a printed
manual using TeX.
`gdb-5.2/etc'
`gdb-5.2.1/etc'
Coding standards, useful files for editing GDB, and other
miscellanea.
`gdb-5.2/utils'
`gdb-5.2.1/utils'
A grab bag of random utilities.
Note: the following instructions are for building GDB on Unix or
@ -213,14 +213,14 @@ MS-DOS/MS-Windows are in the file gdb/config/djgpp/README.
The simplest way to configure and build GDB is to run `configure'
from the `gdb-VERSION-NUMBER' source directory, which in this example
is the `gdb-5.2' directory.
is the `gdb-5.2.1' directory.
First switch to the `gdb-VERSION-NUMBER' source directory if you are
not already in it; then run `configure'.
For example:
cd gdb-5.2
cd gdb-5.2.1
./configure
make
@ -236,8 +236,8 @@ you may need to run `sh' on it explicitly:
sh configure
If you run `configure' from a directory that contains source
directories for multiple libraries or programs, such as the `gdb-5.2'
source directory for version 5.2, `configure' creates configuration
directories for multiple libraries or programs, such as the `gdb-5.2.1'
source directory for version 5.2.1, `configure' creates configuration
files for every directory level underneath (unless you tell it not to,
with the `--norecursion' option).
@ -245,10 +245,10 @@ with the `--norecursion' option).
directories in the GDB distribution, if you only want to configure that
subdirectory; but be sure to specify a path to it.
For example, with version 5.2, type the following to configure only
For example, with version 5.2.1, type the following to configure only
the `bfd' subdirectory:
cd gdb-5.2/bfd
cd gdb-5.2.1/bfd
../configure
You can install `gdb' anywhere; it has no hardwired paths. However,
@ -277,13 +277,13 @@ directory. If the path to `configure' would be the same as the
argument to `--srcdir', you can leave out the `--srcdir' option; it
will be assumed.)
For example, with version 5.2, you can build GDB in a separate
For example, with version 5.2.1, you can build GDB in a separate
directory for a Sun 4 like this:
cd gdb-5.2
cd gdb-5.2.1
mkdir ../gdb-sun4
cd ../gdb-sun4
../gdb-5.2/configure
../gdb-5.2.1/configure
make
When `configure' builds a configuration using a remote source
@ -304,8 +304,8 @@ called `configure' (or one of its subdirectories).
The `Makefile' that `configure' generates in each source directory
also runs recursively. If you type `make' in a source directory such
as `gdb-5.2' (or in a separate configured directory configured with
`--srcdir=PATH/gdb-5.2'), you will build all the required libraries,
as `gdb-5.2.1' (or in a separate configured directory configured with
`--srcdir=PATH/gdb-5.2.1'), you will build all the required libraries,
and then build GDB.
When you have multiple hosts or targets configured in separate
@ -348,7 +348,7 @@ you can use it to test your guesses on abbreviations--for example:
Invalid configuration `i786v': machine `i786v' not recognized
`config.sub' is also distributed in the GDB source directory
(`gdb-5.2', for version 5.2).
(`gdb-5.2.1', for version 5.2.1).
`configure' options
@ -496,7 +496,7 @@ As an alternative, the bug report can be submitted, via e-mail, to the
address "bug-gdb@gnu.org".
When submitting a bug, please include the GDB version number (e.g.,
gdb-5.2), and how you configured it (e.g., "sun4" or "mach386 host,
gdb-5.2.1), and how you configured it (e.g., "sun4" or "mach386 host,
i586-intel-synopsys target"). Since GDB now supports so many
different configurations, it is important that you be precise about
this. If at all possible, you should include the actual banner that
@ -551,17 +551,17 @@ ftp://sources.redhat.com/pub/dejagnu/ will contain a recent snapshot.
Once DejaGNU is installed, you can run the tests in one of the
following ways:
(1) cd gdb-5.2
(1) cd gdb-5.2.1
make check-gdb
or
(2) cd gdb-5.2/gdb
(2) cd gdb-5.2.1/gdb
make check
or
(3) cd gdb-5.2/gdb/testsuite
(3) cd gdb-5.2.1/gdb/testsuite
make site.exp (builds the site specific file)
runtest -tool gdb GDB=../gdb (or GDB=<somepath> as appropriate)

View File

@ -28,6 +28,10 @@
#include "i386/nm-i386.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
/* Provide access to the i386 hardware debugging registers. */
#define I386_DR_LOW_SET_CONTROL(control) \

View File

@ -115,6 +115,10 @@ extern int i386_remove_hw_breakpoint (CORE_ADDR addr, void *shadow);
#define DECR_PC_AFTER_HW_BREAK 0
/* child_post_startup_inferior used to
reset all debug registers by calling i386_cleanup_dregs (). */
#define CHILD_POST_STARTUP_INFERIOR
#endif /* I386_USE_GENERIC_WATCHPOINTS */
#endif /* NM_I386_H */

View File

@ -1 +1 @@
@set GDBVN 4.18
@set GDBVN 5.2.1

View File

@ -34,7 +34,7 @@
Frame Descriptors. */
struct cie_unit
{
/* Offset of this unit in dwarf_frame_buffer. */
/* Offset of this unit in .debug_frame or .eh_frame. */
ULONGEST offset;
/* A null-terminated string that identifies the augmentation to this CIE or
@ -176,6 +176,15 @@ struct frame_state
struct objfile *objfile;
};
enum ptr_encoding
{
PE_absptr = DW_EH_PE_absptr,
PE_pcrel = DW_EH_PE_pcrel,
PE_textrel = DW_EH_PE_textrel,
PE_datarel = DW_EH_PE_datarel,
PE_funcrel = DW_EH_PE_funcrel
};
#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
@ -188,8 +197,6 @@ extern file_ptr dwarf_frame_offset;
extern unsigned int dwarf_frame_size;
extern file_ptr dwarf_eh_frame_offset;
extern unsigned int dwarf_eh_frame_size;
static char *dwarf_frame_buffer;
extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
@ -201,26 +208,28 @@ static void fde_chunks_need_space ();
static struct context *context_alloc ();
static struct frame_state *frame_state_alloc ();
static void unwind_tmp_obstack_init ();
static void unwind_tmp_obstack_free ();
static void context_cpy (struct context *dst, struct context *src);
static unsigned int read_1u (bfd *abfd, char **p);
static int read_1s (bfd *abfd, char **p);
static unsigned int read_2u (bfd *abfd, char **p);
static int read_2s (bfd *abfd, char **p);
static unsigned int read_4u (bfd *abfd, char **p);
static int read_4s (bfd *abfd, char **p);
static ULONGEST read_8u (bfd *abfd, char **p);
static LONGEST read_8s (bfd *abfd, char **p);
static unsigned int read_1u (bfd * abfd, char **p);
static int read_1s (bfd * abfd, char **p);
static unsigned int read_2u (bfd * abfd, char **p);
static int read_2s (bfd * abfd, char **p);
static unsigned int read_4u (bfd * abfd, char **p);
static int read_4s (bfd * abfd, char **p);
static ULONGEST read_8u (bfd * abfd, char **p);
static LONGEST read_8s (bfd * abfd, char **p);
static ULONGEST read_uleb128 (bfd *abfd, char **p);
static LONGEST read_sleb128 (bfd *abfd, char **p);
static CORE_ADDR read_pointer (bfd *abfd, char **p);
static CORE_ADDR read_encoded_pointer (bfd *abfd, char **p,
static ULONGEST read_uleb128 (bfd * abfd, char **p);
static LONGEST read_sleb128 (bfd * abfd, char **p);
static CORE_ADDR read_pointer (bfd * abfd, char **p);
static CORE_ADDR read_encoded_pointer (bfd * abfd, char **p,
unsigned char encoding);
static enum ptr_encoding pointer_encoding (unsigned char encoding);
static LONGEST read_initial_length (bfd *abfd, char *buf, int *bytes_read);
static ULONGEST read_length (bfd *abfd, char *buf, int *bytes_read,
static LONGEST read_initial_length (bfd * abfd, char *buf, int *bytes_read);
static ULONGEST read_length (bfd * abfd, char *buf, int *bytes_read,
int dwarf64);
static int is_cie (ULONGEST cie_id, int dwarf64);
@ -235,11 +244,12 @@ static void frame_state_for (struct context *context, struct frame_state *fs);
static void get_reg (char *reg, struct context *context, int regnum);
static CORE_ADDR execute_stack_op (struct objfile *objfile,
char *op_ptr, char *op_end,
struct context *context, CORE_ADDR initial);
struct context *context,
CORE_ADDR initial);
static void update_context (struct context *context, struct frame_state *fs,
int chain);
/* Memory allocation functions. */
static struct fde_unit *
fde_unit_alloc (void)
@ -301,17 +311,23 @@ frame_state_alloc ()
fs = (struct frame_state *) obstack_alloc (&unwind_tmp_obstack,
sizeof (struct frame_state));
memset (fs, 0, sizeof (struct frame_state));
fs->regs.reg = (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack,
regs_size);
fs->regs.reg =
(struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack, regs_size);
memset (fs->regs.reg, 0, regs_size);
return fs;
}
static void
unwind_tmp_obstack_init ()
{
obstack_init (&unwind_tmp_obstack);
}
static void
unwind_tmp_obstack_free ()
{
obstack_free (&unwind_tmp_obstack, NULL);
obstack_init (&unwind_tmp_obstack);
unwind_tmp_obstack_init ();
}
static void
@ -334,92 +350,92 @@ context_cpy (struct context *dst, struct context *src)
dreg = dst->reg;
*dst = *src;
dst->reg = dreg;
memcpy (dst->reg, src->reg, regs_size);
}
static unsigned int
read_1u (bfd *abfd, char **p)
read_1u (bfd * abfd, char **p)
{
unsigned ret;
ret= bfd_get_8 (abfd, (bfd_byte *) *p);
(*p) ++;
ret = bfd_get_8 (abfd, (bfd_byte *) * p);
(*p)++;
return ret;
}
static int
read_1s (bfd *abfd, char **p)
read_1s (bfd * abfd, char **p)
{
int ret;
ret= bfd_get_signed_8 (abfd, (bfd_byte *) *p);
(*p) ++;
ret = bfd_get_signed_8 (abfd, (bfd_byte *) * p);
(*p)++;
return ret;
}
static unsigned int
read_2u (bfd *abfd, char **p)
read_2u (bfd * abfd, char **p)
{
unsigned ret;
ret= bfd_get_16 (abfd, (bfd_byte *) *p);
(*p) ++;
ret = bfd_get_16 (abfd, (bfd_byte *) * p);
(*p)++;
return ret;
}
static int
read_2s (bfd *abfd, char **p)
read_2s (bfd * abfd, char **p)
{
int ret;
ret= bfd_get_signed_16 (abfd, (bfd_byte *) *p);
ret = bfd_get_signed_16 (abfd, (bfd_byte *) * p);
(*p) += 2;
return ret;
}
static unsigned int
read_4u (bfd *abfd, char **p)
read_4u (bfd * abfd, char **p)
{
unsigned int ret;
ret= bfd_get_32 (abfd, (bfd_byte *) *p);
ret = bfd_get_32 (abfd, (bfd_byte *) * p);
(*p) += 4;
return ret;
}
static int
read_4s (bfd *abfd, char **p)
read_4s (bfd * abfd, char **p)
{
int ret;
ret= bfd_get_signed_32 (abfd, (bfd_byte *) *p);
ret = bfd_get_signed_32 (abfd, (bfd_byte *) * p);
(*p) += 4;
return ret;
}
static ULONGEST
read_8u (bfd *abfd, char **p)
read_8u (bfd * abfd, char **p)
{
ULONGEST ret;
ret = bfd_get_64 (abfd, (bfd_byte *) *p);
ret = bfd_get_64 (abfd, (bfd_byte *) * p);
(*p) += 8;
return ret;
}
static LONGEST
read_8s (bfd *abfd, char **p)
read_8s (bfd * abfd, char **p)
{
LONGEST ret;
ret = bfd_get_signed_64 (abfd, (bfd_byte *) *p);
ret = bfd_get_signed_64 (abfd, (bfd_byte *) * p);
(*p) += 8;
return ret;
}
static ULONGEST
read_uleb128 (bfd *abfd, char **p)
read_uleb128 (bfd * abfd, char **p)
{
ULONGEST ret;
int i, shift;
@ -430,8 +446,8 @@ read_uleb128 (bfd *abfd, char **p)
i = 0;
while (1)
{
byte = bfd_get_8 (abfd, (bfd_byte *) *p);
(*p) ++;
byte = bfd_get_8 (abfd, (bfd_byte *) * p);
(*p)++;
ret |= ((unsigned long) (byte & 127) << shift);
if ((byte & 128) == 0)
{
@ -443,7 +459,7 @@ read_uleb128 (bfd *abfd, char **p)
}
static LONGEST
read_sleb128 (bfd *abfd, char **p)
read_sleb128 (bfd * abfd, char **p)
{
LONGEST ret;
int i, shift, size, num_read;
@ -456,8 +472,8 @@ read_sleb128 (bfd *abfd, char **p)
i = 0;
while (1)
{
byte = bfd_get_8 (abfd, (bfd_byte *) *p);
(*p) ++;
byte = bfd_get_8 (abfd, (bfd_byte *) * p);
(*p)++;
ret |= ((long) (byte & 127) << shift);
shift += 7;
if ((byte & 128) == 0)
@ -473,7 +489,7 @@ read_sleb128 (bfd *abfd, char **p)
}
static CORE_ADDR
read_pointer (bfd *abfd, char **p)
read_pointer (bfd * abfd, char **p)
{
switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
{
@ -486,8 +502,11 @@ read_pointer (bfd *abfd, char **p)
}
}
/* This functions only reads appropriate amount of data from *p
* and returns the resulting value. Calling function must handle
* different encoding possibilities itself! */
static CORE_ADDR
read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
{
CORE_ADDR ret;
@ -529,22 +548,33 @@ read_encoded_pointer (bfd *abfd, char **p, unsigned char encoding)
"read_encoded_pointer: unknown pointer encoding");
}
if (ret != 0)
switch (encoding & 0xf0)
{
case DW_EH_PE_absptr:
break;
case DW_EH_PE_pcrel:
ret += (CORE_ADDR) *p;
break;
case DW_EH_PE_textrel:
case DW_EH_PE_datarel:
case DW_EH_PE_funcrel:
default:
internal_error (__FILE__, __LINE__,
"read_encoded_pointer: unknown pointer encoding");
}
return ret;
}
/* Variable 'encoding' carries 3 different flags:
* - encoding & 0x0f : size of the address (handled in read_encoded_pointer())
* - encoding & 0x70 : type (absolute, relative, ...)
* - encoding & 0x80 : indirect flag (DW_EH_PE_indirect == 0x80). */
enum ptr_encoding
pointer_encoding (unsigned char encoding)
{
int ret;
if (encoding & DW_EH_PE_indirect)
warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect");
switch (encoding & 0x70)
{
case DW_EH_PE_absptr:
case DW_EH_PE_pcrel:
case DW_EH_PE_textrel:
case DW_EH_PE_datarel:
case DW_EH_PE_funcrel:
ret = encoding & 0x70;
break;
default:
internal_error (__FILE__, __LINE__, "CFI: unknown pointer encoding");
}
return ret;
}
@ -584,8 +614,8 @@ read_length (bfd * abfd, char *buf, int *bytes_read, int dwarf64)
}
static void
execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
struct context *context, struct frame_state *fs)
execute_cfa_program (struct objfile *objfile, char *insn_ptr, char *insn_end,
struct context *context, struct frame_state *fs)
{
struct frame_state_regs *unused_rs = NULL;
@ -604,7 +634,7 @@ execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
{
reg = insn & 0x3f;
uoffset = read_uleb128 (objfile->obfd, &insn_ptr);
offset = (long) uoffset * fs->data_align;
offset = (long) uoffset *fs->data_align;
fs->regs.reg[reg].how = REG_SAVED_OFFSET;
fs->regs.reg[reg].loc.offset = offset;
}
@ -619,6 +649,10 @@ execute_cfa_program ( struct objfile *objfile, char *insn_ptr, char *insn_end,
case DW_CFA_set_loc:
fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
fs->addr_encoding);
if (pointer_encoding (fs->addr_encoding) != PE_absptr)
warning ("CFI: DW_CFA_set_loc uses relative addressing");
break;
case DW_CFA_advance_loc1:
@ -806,13 +840,13 @@ frame_state_for (struct context *context, struct frame_state *fs)
if (fde == NULL)
return;
fs->pc = fde->initial_location;
if (fde->cie_ptr)
{
{
cie = fde->cie_ptr;
fs->code_align = cie->code_align;
fs->data_align = cie->data_align;
fs->retaddr_column = cie->ra;
@ -823,11 +857,10 @@ frame_state_for (struct context *context, struct frame_state *fs)
cie->data + cie->data_length, context, fs);
execute_cfa_program (cie->objfile, fde->data,
fde->data + fde->data_length, context, fs);
}
}
else
internal_error (__FILE__, __LINE__,
"%s(): Internal error: fde->cie_ptr==NULL !",
__func__);
internal_error (__FILE__, __LINE__,
"%s(): Internal error: fde->cie_ptr==NULL !", "?func?");
}
static void
@ -854,8 +887,7 @@ get_reg (char *reg, struct context *context, int regnum)
REGISTER_RAW_SIZE (regnum));
break;
default:
internal_error (__FILE__, __LINE__,
"get_reg: unknown register rule");
internal_error (__FILE__, __LINE__, "get_reg: unknown register rule");
}
}
@ -1208,8 +1240,8 @@ execute_stack_op (struct objfile *objfile,
case DW_OP_ne:
result = (LONGEST) first != (LONGEST) second;
break;
default: /* This label is here just to avoid warning. */
break;
default: /* This label is here just to avoid warning. */
break;
}
}
break;
@ -1255,8 +1287,11 @@ update_context (struct context *context, struct frame_state *fs, int chain)
CORE_ADDR cfa;
long i;
unwind_tmp_obstack_init ();
orig_context = context_alloc ();
context_cpy (orig_context, context);
/* Compute this frame's CFA. */
switch (fs->cfa_how)
{
@ -1267,9 +1302,9 @@ update_context (struct context *context, struct frame_state *fs, int chain)
case CFA_EXP:
/* ??? No way of knowing what register number is the stack pointer
to do the same sort of handling as above. Assume that if the
CFA calculation is so complicated as to require a stack program
that this will not be a problem. */
to do the same sort of handling as above. Assume that if the
CFA calculation is so complicated as to require a stack program
that this will not be a problem. */
{
char *exp = fs->cfa_exp;
ULONGEST len;
@ -1326,7 +1361,7 @@ update_context (struct context *context, struct frame_state *fs, int chain)
orig_context->reg[fs->regs.reg[i].loc.reg].loc.addr;
default:
internal_error (__FILE__, __LINE__,
"%s: unknown register rule", __func__);
"%s: unknown register rule", "?func?");
}
break;
case REG_SAVED_EXP:
@ -1344,7 +1379,7 @@ update_context (struct context *context, struct frame_state *fs, int chain)
break;
default:
internal_error (__FILE__, __LINE__,
"%s: unknown register rule", __func__);
"%s: unknown register rule", "?func?");
}
get_reg ((char *) &context->ra, context, fs->retaddr_column);
unwind_tmp_obstack_free ();
@ -1371,39 +1406,46 @@ compare_fde_unit (const void *a, const void *b)
}
/* Build the cie_chunks and fde_chunks tables from informations
in .debug_frame section. */
void
dwarf2_build_frame_info (struct objfile *objfile)
found in .debug_frame and .eh_frame sections. */
/* We can handle both of these sections almost in the same way, however there
are some exceptions:
- CIE ID is -1 in debug_frame, but 0 in eh_frame
- eh_frame may contain some more information that are used only by gcc
(eg. personality pointer, LSDA pointer, ...). Most of them we can ignore.
- In debug_frame FDE's item cie_id contains offset of it's parent CIE.
In eh_frame FDE's item cie_id is a relative pointer to the parent CIE.
Anyway we don't need to bother with this, because we are smart enough
to keep the pointer to the parent CIE of oncomming FDEs in 'last_cie'.
- Although debug_frame items can contain Augmentation as well as
eh_frame ones, I have never seen them non-empty. Thus only in eh_frame
we can encounter for example non-absolute pointers (Aug. 'R').
-- mludvig */
static void
parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
unsigned int frame_size, int eh_frame)
{
bfd *abfd = objfile->obfd;
asection *curr_section_ptr;
char *start = NULL;
char *end = NULL;
int from_eh = 0;
char *frame_buffer = NULL;
char *curr_section_name, *aug_data;
struct cie_unit *last_cie = NULL;
int last_dup_fde = 0;
int aug_len, i;
CORE_ADDR curr_section_vma = 0;
obstack_init (&unwind_tmp_obstack);
unwind_tmp_obstack_init ();
dwarf_frame_buffer = 0;
frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
if (dwarf_frame_offset)
{
dwarf_frame_buffer = dwarf2_read_section (objfile,
dwarf_frame_offset,
dwarf_frame_size);
start = frame_buffer;
end = frame_buffer + frame_size;
start = dwarf_frame_buffer;
end = dwarf_frame_buffer + dwarf_frame_size;
}
else if (dwarf_eh_frame_offset)
{
dwarf_frame_buffer = dwarf2_read_section (objfile,
dwarf_eh_frame_offset,
dwarf_eh_frame_size);
start = dwarf_frame_buffer;
end = dwarf_frame_buffer + dwarf_eh_frame_size;
from_eh = 1;
}
curr_section_name = eh_frame ? ".eh_frame" : ".debug_frame";
curr_section_ptr = bfd_get_section_by_name (abfd, curr_section_name);
if (curr_section_ptr)
curr_section_vma = curr_section_ptr->vma;
if (start)
{
@ -1411,9 +1453,8 @@ dwarf2_build_frame_info (struct objfile *objfile)
{
unsigned long length;
ULONGEST cie_id;
ULONGEST unit_offset = start - dwarf_frame_buffer;
int bytes_read;
int dwarf64;
ULONGEST unit_offset = start - frame_buffer;
int bytes_read, dwarf64;
char *block_end;
length = read_initial_length (abfd, start, &bytes_read);
@ -1421,10 +1462,16 @@ dwarf2_build_frame_info (struct objfile *objfile)
dwarf64 = (bytes_read == 12);
block_end = start + length;
if (length == 0)
{
start = block_end;
continue;
}
cie_id = read_length (abfd, start, &bytes_read, dwarf64);
start += bytes_read;
if ((from_eh && cie_id == 0) || is_cie (cie_id, dwarf64))
if ((eh_frame && cie_id == 0) || is_cie (cie_id, dwarf64))
{
struct cie_unit *cie = cie_unit_alloc ();
char *aug;
@ -1440,84 +1487,186 @@ dwarf2_build_frame_info (struct objfile *objfile)
start++; /* version */
cie->augmentation = aug = start;
while (*start)
start++;
start++; /* skip past NUL */
while (*start++); /* Skips last NULL as well */
cie->code_align = read_uleb128 (abfd, &start);
cie->data_align = read_sleb128 (abfd, &start);
cie->ra = read_1u (abfd, &start);
/* Augmentation:
z Indicates that a uleb128 is present to size the
augmentation section.
L Indicates the encoding (and thus presence) of
an LSDA pointer in the FDE augmentation.
R Indicates a non-default pointer encoding for
FDE code pointers.
P Indicates the presence of an encoding + language
personality routine in the CIE augmentation.
[This info comes from GCC's dwarf2out.c]
*/
if (*aug == 'z')
{
int xtra = read_uleb128 (abfd, &start);
start += xtra;
aug_len = read_uleb128 (abfd, &start);
aug_data = start;
start += aug_len;
++aug;
}
cie->data = start;
cie->data_length = block_end - cie->data;
while (*aug != '\0')
{
if (aug[0] == 'e' && aug[1] == 'h')
{
start += sizeof (void *);
aug += 2;
aug_data += sizeof (void *);
aug++;
}
else if (aug[0] == 'R')
{
cie->addr_encoding = *start++;
aug += 1;
}
cie->addr_encoding = *aug_data++;
else if (aug[0] == 'P')
{
CORE_ADDR ptr;
ptr = read_encoded_pointer (abfd, &start,
cie->addr_encoding);
aug += 1;
CORE_ADDR pers_addr;
int pers_addr_enc;
pers_addr_enc = *aug_data++;
/* We don't need pers_addr value and so we
don't care about it's encoding. */
pers_addr = read_encoded_pointer (abfd, &aug_data,
pers_addr_enc);
}
else if (aug[0] == 'L' && eh_frame)
{
int lsda_addr_enc;
/* Perhaps we should save this to CIE for later use?
Do we need it for something in GDB? */
lsda_addr_enc = *aug_data++;
}
else
warning ("%s(): unknown augmentation", __func__);
warning ("CFI warning: unknown augmentation \"%c\""
" in \"%s\" of\n"
"\t%s", aug[0], curr_section_name,
objfile->name);
aug++;
}
cie->data = start;
cie->data_length = block_end - start;
last_cie = cie;
}
else
{
struct fde_unit *fde;
struct cie_unit *cie;
int dup = 0;
CORE_ADDR init_loc;
fde_chunks_need_space ();
fde = fde_unit_alloc ();
fde_chunks.array[fde_chunks.elems++] = fde;
fde->initial_location = read_pointer (abfd, &start)
+ ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
fde->address_range = read_pointer (abfd, &start);
cie = cie_chunks;
while(cie)
{
if (cie->objfile == objfile)
/* We assume that debug_frame is in order
CIE,FDE,CIE,FDE,FDE,... and thus the CIE for this FDE
should be stored in last_cie pointer. If not, we'll
try to find it by the older way. */
if (last_cie)
cie = last_cie;
else
{
if (from_eh && (cie->offset == (unit_offset + bytes_read - cie_id)))
break;
if (!from_eh && (cie->offset == cie_id))
break;
warning ("CFI: last_cie == NULL. "
"Perhaps a malformed %s section in '%s'...?\n",
curr_section_name, objfile->name);
cie = cie_chunks;
while (cie)
{
if (cie->objfile == objfile)
{
if (eh_frame &&
(cie->offset ==
(unit_offset + bytes_read - cie_id)))
break;
if (!eh_frame && (cie->offset == cie_id))
break;
}
cie = cie->next;
}
if (!cie)
error ("CFI: can't find CIE pointer");
}
cie = cie->next;
}
if (!cie)
error ("%s(): can't find CIE pointer", __func__);
fde->cie_ptr = cie;
init_loc = read_encoded_pointer (abfd, &start,
cie->addr_encoding);
if (cie->augmentation[0] == 'z')
read_uleb128 (abfd, &start);
switch (pointer_encoding (cie->addr_encoding))
{
case PE_absptr:
break;
case PE_pcrel:
/* start-frame_buffer gives offset from
the beginning of actual section. */
init_loc += curr_section_vma + start - frame_buffer;
break;
default:
warning ("CFI: Unsupported pointer encoding\n");
}
fde->data = start;
fde->data_length = block_end - start;
/* For relocatable objects we must add an offset telling
where the section is actually mapped in the memory. */
init_loc += ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
/* If we have both .debug_frame and .eh_frame present in
a file, we must eliminate duplicate FDEs. For now we'll
run through all entries in fde_chunks and check it one
by one. Perhaps in the future we can implement a faster
searching algorithm. */
/* eh_frame==2 indicates, that this file has an already
parsed .debug_frame too. When eh_frame==1 it means, that no
.debug_frame is present and thus we don't need to check for
duplicities. eh_frame==0 means, that we parse .debug_frame
and don't need to care about duplicate FDEs, because
.debug_frame is parsed first. */
if (eh_frame == 2)
for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++)
{
/* We assume that FDEs in .debug_frame and .eh_frame
have the same order (if they are present, of course).
If we find a duplicate entry for one FDE and save
it's index to last_dup_fde it's very likely, that
we'll find an entry for the following FDE right after
the previous one. Thus in many cases we'll run this
loop only once. */
last_dup_fde = (last_dup_fde + i) % fde_chunks.elems;
if (fde_chunks.array[last_dup_fde]->initial_location
== init_loc)
{
dup = 1;
break;
}
}
/* Allocate a new entry only if this FDE isn't a duplicate of
something we have already seen. */
if (!dup)
{
fde_chunks_need_space ();
fde = fde_unit_alloc ();
fde_chunks.array[fde_chunks.elems++] = fde;
fde->initial_location = init_loc;
fde->address_range = read_encoded_pointer (abfd, &start,
cie->
addr_encoding);
fde->cie_ptr = cie;
/* Here we intentionally ignore augmentation data
from FDE, because we don't need them. */
if (cie->augmentation[0] == 'z')
start += read_uleb128 (abfd, &start);
fde->data = start;
fde->data_length = block_end - start;
}
}
start = block_end;
}
@ -1525,7 +1674,30 @@ dwarf2_build_frame_info (struct objfile *objfile)
sizeof (struct fde_unit *), compare_fde_unit);
}
}
/* We must parse both .debug_frame section and .eh_frame because
* not all frames must be present in both of these sections. */
void
dwarf2_build_frame_info (struct objfile *objfile)
{
int after_debug_frame = 0;
/* If we have .debug_frame then the parser is called with
eh_frame==0 for .debug_frame and eh_frame==2 for .eh_frame,
otherwise it's only called once for .eh_frame with argument
eh_frame==1. */
if (dwarf_frame_offset)
{
parse_frame_info (objfile, dwarf_frame_offset,
dwarf_frame_size, 0 /* = debug_frame */ );
after_debug_frame = 1;
}
if (dwarf_eh_frame_offset)
parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
1 /* = eh_frame */ + after_debug_frame);
}
/* Return the frame address. */
CORE_ADDR
@ -1535,6 +1707,8 @@ cfi_read_fp ()
struct frame_state *fs;
CORE_ADDR cfa;
unwind_tmp_obstack_init ();
context = context_alloc ();
fs = frame_state_alloc ();
@ -1544,7 +1718,9 @@ cfi_read_fp ()
update_context (context, fs, 0);
cfa = context->cfa;
unwind_tmp_obstack_free ();
return cfa;
}
@ -1556,6 +1732,8 @@ cfi_write_fp (CORE_ADDR val)
struct context *context;
struct frame_state *fs;
unwind_tmp_obstack_init ();
context = context_alloc ();
fs = frame_state_alloc ();
@ -1603,6 +1781,8 @@ cfi_frame_chain (struct frame_info *fi)
struct frame_state *fs;
CORE_ADDR cfa;
unwind_tmp_obstack_init ();
context = context_alloc ();
fs = frame_state_alloc ();
context_cpy (context, UNWIND_CONTEXT (fi));
@ -1619,7 +1799,7 @@ cfi_frame_chain (struct frame_info *fi)
cfa = context->cfa;
unwind_tmp_obstack_free ();
return cfa;
}
@ -1639,6 +1819,8 @@ cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
struct frame_state *fs;
unwind_tmp_obstack_init ();
fs = frame_state_alloc ();
fi->context = frame_obstack_alloc (sizeof (struct context));
UNWIND_CONTEXT (fi)->reg =
@ -1658,6 +1840,7 @@ cfi_init_extra_frame_info (int fromleaf, struct frame_info *fi)
frame_state_for (UNWIND_CONTEXT (fi), fs);
update_context (UNWIND_CONTEXT (fi), fs, 0);
}
unwind_tmp_obstack_free ();
}
@ -1678,7 +1861,7 @@ cfi_get_ra (struct frame_info *fi)
void
cfi_get_saved_register (char *raw_buffer,
int *optimized,
CORE_ADDR * addrp,
CORE_ADDR *addrp,
struct frame_info *frame,
int regnum, enum lval_type *lval)
{
@ -1765,6 +1948,8 @@ cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_reg,
struct context *context;
struct frame_state *fs;
unwind_tmp_obstack_init ();
context = context_alloc ();
fs = frame_state_alloc ();

View File

@ -0,0 +1,97 @@
/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB.
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 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 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "server.h"
#include "linux-low.h"
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif
int num_regs = 90;
#include <asm/ptrace.h>
/* Return the ptrace ``address'' of register REGNO. */
/* Matches mips_generic32_regs */
int regmap[] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
-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,
-1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
};
/* 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(). */
int
cannot_fetch_register (int regno)
{
if (regmap[regno] == -1)
return 1;
if (find_regno ("zero") == regno)
return 1;
return 0;
}
int
cannot_store_register (int regno)
{
if (regmap[regno] == -1)
return 1;
if (find_regno ("zero") == regno)
return 1;
if (find_regno ("cause") == regno)
return 1;
if (find_regno ("bad") == regno)
return 1;
if (find_regno ("fir") == regno)
return 1;
return 0;
}

View File

@ -0,0 +1,62 @@
/* GNU/Linux/PowerPC specific low level interface, for the remote server for
GDB.
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 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 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "server.h"
#include "linux-low.h"
#include <asm/ptrace.h>
int num_regs = 71;
/* Currently, don't check/send MQ. */
int 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,
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,
PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
PT_CTR * 4, PT_XER * 4, -1, };
int
cannot_store_register (int regno)
{
return 0;
}
int
cannot_fetch_register (int regno)
{
return 0;
}

View File

@ -230,6 +230,14 @@ i386_cleanup_dregs (void)
dr_status_mirror = 0;
}
/* Reset all debug registers at each new startup
to avoid missing watchpoints after restart. */
void
child_post_startup_inferior (ptid_t ptid)
{
i386_cleanup_dregs ();
}
/* Print the values of the mirrored debug registers.
This is called when maint_show_dr is non-zero. To set that
up, type "maint show-debug-regs" at GDB's prompt. */

View File

@ -22,6 +22,8 @@
#if !defined (OBJFILES_H)
#define OBJFILES_H
#include "bcache.h"
/* This structure maintains information on a per-objfile basis about the
"entry point" of the objfile, and the scope within which the entry point
exists. It is possible that gdb will see more than one objfile that is

View File

@ -0,0 +1,112 @@
name:mips
expedite:pc,sp
32:zero
32:at
32:v0
32:v1
32:a0
32:a1
32:a2
32:a3
32:t0
32:t1
32:t2
32:t3
32:t4
32:t5
32:t6
32:t7
32:s0
32:s1
32:s2
32:s3
32:s4
32:s5
32:s6
32:s7
32:t8
32:t9
32:k0
32:k1
32:gp
32:sp
32:s8
32:ra
32:sr
32:lo
32:hi
32:bad
32:cause
32:pc
32:f0
32:f1
32:f2
32:f3
32:f4
32:f5
32:f6
32:f7
32:f8
32:f9
32:f10
32:f11
32:f12
32:f13
32:f14
32:f15
32:f16
32:f17
32:f18
32:f19
32:f20
32:f21
32:f22
32:f23
32:f24
32:f25
32:f26
32:f27
32:f28
32:f29
32:f30
32:f31
32:fsr
32:fir
32:fp
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:

View File

@ -0,0 +1,62 @@
name:sh
expedite:pc,r14,r15
32:r0
32:r1
32:r2
32:r3
32:r4
32:r5
32:r6
32:r7
32:r8
32:r9
32:r10
32:r11
32:r12
32:r13
32:r14
32:r15
32:pc
32:pr
32:gbr
32:vbr
32:mach
32:macl
32:sr
32:fpul
32:fpscr
32:fr0
32:fr1
32:fr2
32:fr3
32:fr4
32:fr5
32:fr6
32:fr7
32:fr8
32:fr9
32:fr10
32:fr11
32:fr12
32:fr13
32:fr14
32:fr15
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:
32:

View File

@ -28,7 +28,6 @@
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free xfree
#include "bcache.h"
/* Don't do this; it means that if some .o's are compiled with GNU C
and some are not (easy to do accidentally the way we configure

View File

@ -25,7 +25,6 @@
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include "i387-nat.h"
#include "gdb_assert.h"
#include "x86-64-tdep.h"
@ -158,7 +157,7 @@ fill_gregset (elf_gregset_t * gregsetp, int regno)
for (i = 0; i < x86_64_num_gregs; i++)
if ((regno == -1 || regno == i))
read_register_gen (i, regp + x86_64_regmap[i]);
read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
}
/* Fetch all general-purpose registers from process/thread TID and
@ -195,23 +194,73 @@ store_regs (int tid, int regno)
/* Transfering floating-point registers between GDB, inferiors and cores. */
/* Fill GDB's register array with the floating-point register values in
*FPREGSETP. */
void
supply_fpregset (elf_fpregset_t * fpregsetp)
static void *
x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum)
{
i387_supply_fxsave ((char *) fpregsetp);
const char *reg_name;
int reg_index;
gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs);
reg_name = x86_64_register_name (regnum);
if (reg_name[0] == 's' && reg_name[1] == 't')
{
reg_index = reg_name[2] - '0';
return &fxsave->st_space[reg_index * 2];
}
if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
{
reg_index = reg_name[3] - '0';
return &fxsave->xmm_space[reg_index * 4];
}
if (strcmp (reg_name, "mxcsr") == 0)
return &fxsave->mxcsr;
return NULL;
}
/* Fill register REGNO (if it is a floating-point register) in
*FPREGSETP with the value in GDB's register array. If REGNO is -1,
do this for all registers. */
/* Fill GDB's register array with the floating-point and SSE register
values in *FXSAVE. This function masks off any of the reserved
bits in *FXSAVE. */
void
fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
supply_fpregset (elf_fpregset_t * fxsave)
{
i387_fill_fxsave ((char *) fpregsetp, regno);
int i, reg_st0, reg_mxcsr;
reg_st0 = x86_64_register_number ("st0");
reg_mxcsr = x86_64_register_number ("mxcsr");
gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
for (i = reg_st0; i <= reg_mxcsr; i++)
supply_register (i, x86_64_fxsave_offset (fxsave, i));
}
/* Fill register REGNUM (if it is a floating-point or SSE register) in
*FXSAVE with the value in GDB's register array. If REGNUM is -1, do
this for all registers. This function doesn't touch any of the
reserved bits in *FXSAVE. */
void
fill_fpregset (elf_fpregset_t * fxsave, int regnum)
{
int i, last_regnum = MXCSR_REGNUM;
void *ptr;
if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
last_regnum = FOP_REGNUM;
for (i = FP0_REGNUM; i <= last_regnum; i++)
if (regnum == -1 || regnum == i)
{
ptr = x86_64_fxsave_offset (fxsave, i);
if (ptr)
regcache_collect (i, ptr);
}
}
/* Fetch all floating-point registers from process/thread TID and store
@ -406,12 +455,6 @@ static struct core_fns linux_elf_core_fns = {
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
/* Record the value of the debug control register. */
static long debug_control_mirror;
/* Record which address associates with which register. */
static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
/* Return the address of register REGNUM. BLOCKEND is the value of
u.u_ar0, which should point to the registers. */
CORE_ADDR
@ -446,4 +489,3 @@ kernel_u_size (void)
{
return (sizeof (struct user));
}

View File

@ -28,6 +28,7 @@
#include "arch-utils.h"
#include "regcache.h"
#include "symfile.h"
#include "objfiles.h"
#include "x86-64-tdep.h"
#include "dwarf2cfi.h"
#include "gdb_assert.h"
@ -37,6 +38,7 @@
#define RDX_REGNUM 3
#define RDI_REGNUM 5
#define EFLAGS_REGNUM 17
#define ST0_REGNUM 22
#define XMM1_REGNUM 39
struct register_info
@ -49,63 +51,90 @@ struct register_info
/* x86_64_register_raw_size_table[i] is the number of bytes of storage in
GDB's register array occupied by register i. */
static struct register_info x86_64_register_info_table[] = {
{8, "rax", &builtin_type_int64},
{8, "rbx", &builtin_type_int64},
{8, "rcx", &builtin_type_int64},
{8, "rdx", &builtin_type_int64},
{8, "rsi", &builtin_type_int64},
{8, "rdi", &builtin_type_int64},
{8, "rbp", &builtin_type_void_func_ptr},
{8, "rsp", &builtin_type_void_func_ptr},
{8, "r8", &builtin_type_int64},
{8, "r9", &builtin_type_int64},
{8, "r10", &builtin_type_int64},
{8, "r11", &builtin_type_int64},
{8, "r12", &builtin_type_int64},
{8, "r13", &builtin_type_int64},
{8, "r14", &builtin_type_int64},
{8, "r15", &builtin_type_int64},
{8, "rip", &builtin_type_void_func_ptr},
{4, "eflags", &builtin_type_int32},
{4, "ds", &builtin_type_int32},
{4, "es", &builtin_type_int32},
{4, "fs", &builtin_type_int32},
{4, "gs", &builtin_type_int32},
{10, "st0", &builtin_type_i387_ext},
{10, "st1", &builtin_type_i387_ext},
{10, "st2", &builtin_type_i387_ext},
{10, "st3", &builtin_type_i387_ext},
{10, "st4", &builtin_type_i387_ext},
{10, "st5", &builtin_type_i387_ext},
{10, "st6", &builtin_type_i387_ext},
{10, "st7", &builtin_type_i387_ext},
{4, "fctrl", &builtin_type_int32},
{4, "fstat", &builtin_type_int32},
{4, "ftag", &builtin_type_int32},
{4, "fiseg", &builtin_type_int32},
{4, "fioff", &builtin_type_int32},
{4, "foseg", &builtin_type_int32},
{4, "fooff", &builtin_type_int32},
{4, "fop", &builtin_type_int32},
{16, "xmm0", &builtin_type_v4sf},
{16, "xmm1", &builtin_type_v4sf},
{16, "xmm2", &builtin_type_v4sf},
{16, "xmm3", &builtin_type_v4sf},
{16, "xmm4", &builtin_type_v4sf},
{16, "xmm5", &builtin_type_v4sf},
{16, "xmm6", &builtin_type_v4sf},
{16, "xmm7", &builtin_type_v4sf},
{16, "xmm8", &builtin_type_v4sf},
{16, "xmm9", &builtin_type_v4sf},
{16, "xmm10", &builtin_type_v4sf},
{16, "xmm11", &builtin_type_v4sf},
{16, "xmm12", &builtin_type_v4sf},
{16, "xmm13", &builtin_type_v4sf},
{16, "xmm14", &builtin_type_v4sf},
{16, "xmm15", &builtin_type_v4sf},
{4, "mxcsr", &builtin_type_int32}
/* 0 */ {8, "rax", &builtin_type_int64},
/* 1 */ {8, "rbx", &builtin_type_int64},
/* 2 */ {8, "rcx", &builtin_type_int64},
/* 3 */ {8, "rdx", &builtin_type_int64},
/* 4 */ {8, "rsi", &builtin_type_int64},
/* 5 */ {8, "rdi", &builtin_type_int64},
/* 6 */ {8, "rbp", &builtin_type_void_func_ptr},
/* 7 */ {8, "rsp", &builtin_type_void_func_ptr},
/* 8 */ {8, "r8", &builtin_type_int64},
/* 9 */ {8, "r9", &builtin_type_int64},
/* 10 */ {8, "r10", &builtin_type_int64},
/* 11 */ {8, "r11", &builtin_type_int64},
/* 12 */ {8, "r12", &builtin_type_int64},
/* 13 */ {8, "r13", &builtin_type_int64},
/* 14 */ {8, "r14", &builtin_type_int64},
/* 15 */ {8, "r15", &builtin_type_int64},
/* 16 */ {8, "rip", &builtin_type_void_func_ptr},
/* 17 */ {4, "eflags", &builtin_type_int32},
/* 18 */ {4, "ds", &builtin_type_int32},
/* 19 */ {4, "es", &builtin_type_int32},
/* 20 */ {4, "fs", &builtin_type_int32},
/* 21 */ {4, "gs", &builtin_type_int32},
/* 22 */ {10, "st0", &builtin_type_i387_ext},
/* 23 */ {10, "st1", &builtin_type_i387_ext},
/* 24 */ {10, "st2", &builtin_type_i387_ext},
/* 25 */ {10, "st3", &builtin_type_i387_ext},
/* 26 */ {10, "st4", &builtin_type_i387_ext},
/* 27 */ {10, "st5", &builtin_type_i387_ext},
/* 28 */ {10, "st6", &builtin_type_i387_ext},
/* 29 */ {10, "st7", &builtin_type_i387_ext},
/* 30 */ {4, "fctrl", &builtin_type_int32},
/* 31 */ {4, "fstat", &builtin_type_int32},
/* 32 */ {4, "ftag", &builtin_type_int32},
/* 33 */ {4, "fiseg", &builtin_type_int32},
/* 34 */ {4, "fioff", &builtin_type_int32},
/* 35 */ {4, "foseg", &builtin_type_int32},
/* 36 */ {4, "fooff", &builtin_type_int32},
/* 37 */ {4, "fop", &builtin_type_int32},
/* 38 */ {16, "xmm0", &builtin_type_v4sf},
/* 39 */ {16, "xmm1", &builtin_type_v4sf},
/* 40 */ {16, "xmm2", &builtin_type_v4sf},
/* 41 */ {16, "xmm3", &builtin_type_v4sf},
/* 42 */ {16, "xmm4", &builtin_type_v4sf},
/* 43 */ {16, "xmm5", &builtin_type_v4sf},
/* 44 */ {16, "xmm6", &builtin_type_v4sf},
/* 45 */ {16, "xmm7", &builtin_type_v4sf},
/* 46 */ {16, "xmm8", &builtin_type_v4sf},
/* 47 */ {16, "xmm9", &builtin_type_v4sf},
/* 48 */ {16, "xmm10", &builtin_type_v4sf},
/* 49 */ {16, "xmm11", &builtin_type_v4sf},
/* 50 */ {16, "xmm12", &builtin_type_v4sf},
/* 51 */ {16, "xmm13", &builtin_type_v4sf},
/* 52 */ {16, "xmm14", &builtin_type_v4sf},
/* 53 */ {16, "xmm15", &builtin_type_v4sf},
/* 54 */ {4, "mxcsr", &builtin_type_int32}
};
/* This array is a mapping from Dwarf-2 register
numbering to GDB's one. Dwarf-2 numbering is
defined in x86-64 ABI, section 3.6. */
static int x86_64_dwarf2gdb_regno_map[] = {
0, 1, 2, 3, /* RAX - RDX */
4, 5, 6, 7, /* RSI, RDI, RBP, RSP */
8, 9, 10, 11, /* R8 - R11 */
12, 13, 14, 15, /* R12 - R15 */
-1, /* RA - not mapped */
XMM1_REGNUM - 1, XMM1_REGNUM, /* XMM0 ... */
XMM1_REGNUM + 1, XMM1_REGNUM + 2,
XMM1_REGNUM + 3, XMM1_REGNUM + 4,
XMM1_REGNUM + 5, XMM1_REGNUM + 6,
XMM1_REGNUM + 7, XMM1_REGNUM + 8,
XMM1_REGNUM + 9, XMM1_REGNUM + 10,
XMM1_REGNUM + 11, XMM1_REGNUM + 12,
XMM1_REGNUM + 13, XMM1_REGNUM + 14, /* ... XMM15 */
ST0_REGNUM + 0, ST0_REGNUM + 1, /* ST0 ... */
ST0_REGNUM + 2, ST0_REGNUM + 3,
ST0_REGNUM + 4, ST0_REGNUM + 5,
ST0_REGNUM + 6, ST0_REGNUM + 7 /* ... ST7 */
};
static int x86_64_dwarf2gdb_regno_map_length =
sizeof (x86_64_dwarf2gdb_regno_map) /
sizeof (x86_64_dwarf2gdb_regno_map[0]);
/* Number of all registers */
#define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
sizeof (x86_64_register_info_table[0]))
@ -167,7 +196,7 @@ x86_64_register_convert_to_virtual (int regnum, struct type *type,
char *from, char *to)
{
char buf[12];
DOUBLEST d;
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
@ -198,6 +227,19 @@ x86_64_register_convert_to_raw (struct type *type, int regnum,
memcpy (to, from, FPU_REG_RAW_SIZE);
}
/* Dwarf-2 <-> GDB register numbers mapping. */
int
x86_64_dwarf2_reg_to_regnum (int dw_reg)
{
if (dw_reg < 0 || dw_reg > x86_64_dwarf2gdb_regno_map_length)
{
warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
return dw_reg;
}
return x86_64_dwarf2gdb_regno_map[dw_reg];
}
/* This is the variable that is set with "set disassembly-flavour", and
its legitimate values. */
static const char att_flavour[] = "att";
@ -331,18 +373,19 @@ classify_argument (struct type *type,
case TYPE_CODE_STRUCT:
{
int j;
for (j = 0; j < type->nfields; ++j)
for (j = 0; j < TYPE_NFIELDS (type); ++j)
{
int num = classify_argument (type->fields[j].type,
int num = classify_argument (TYPE_FIELDS (type)[j].type,
subclasses,
(type->fields[j].loc.bitpos
+ bit_offset) % 256);
(TYPE_FIELDS (type)[j].loc.
bitpos + bit_offset) % 256);
if (!num)
return 0;
for (i = 0; i < num; i++)
{
int pos =
(type->fields[j].loc.bitpos + bit_offset) / 8 / 8;
(TYPE_FIELDS (type)[j].loc.bitpos +
bit_offset) / 8 / 8;
classes[i + pos] =
merge_classes (subclasses[i], classes[i + pos]);
}
@ -353,7 +396,7 @@ classify_argument (struct type *type,
{
int num;
num = classify_argument (type->target_type,
num = classify_argument (TYPE_TARGET_TYPE (type),
subclasses, bit_offset);
if (!num)
return 0;
@ -372,10 +415,10 @@ classify_argument (struct type *type,
{
int j;
{
for (j = 0; j < type->nfields; ++j)
for (j = 0; j < TYPE_NFIELDS (type); ++j)
{
int num;
num = classify_argument (type->fields[j].type,
num = classify_argument (TYPE_FIELDS (type)[j].type,
subclasses, bit_offset);
if (!num)
return 0;
@ -385,6 +428,8 @@ classify_argument (struct type *type,
}
}
break;
default:
break;
}
/* Final merger cleanup. */
for (i = 0; i < words; i++)
@ -447,6 +492,8 @@ classify_argument (struct type *type,
}
case TYPE_CODE_VOID:
return 0;
default: /* Avoid warning. */
break;
}
internal_error (__FILE__, __LINE__,
"classify_argument: unknown argument type");
@ -609,7 +656,7 @@ x86_64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
static int int_parameter_registers[INT_REGS] = {
5 /* RDI */ , 4 /* RSI */ ,
3 /* RDX */ , 2 /* RCX */ ,
8 /* R8 */ , 9 /* R9 */
8 /* R8 */ , 9 /* R9 */
};
/* XMM0 - XMM15 */
static int sse_parameter_registers[SSE_REGS] = {
@ -752,13 +799,24 @@ x86_64_store_return_value (struct type *type, char *valbuf)
}
static char *
char *
x86_64_register_name (int reg_nr)
{
if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
return NULL;
return x86_64_register_info_table[reg_nr].name;
}
int
x86_64_register_number (const char *name)
{
int reg_nr;
for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++)
if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0)
return reg_nr;
return -1;
}
@ -800,10 +858,10 @@ x86_64_frameless_function_invocation (struct frame_info *frame)
CORE_ADDR
x86_64_skip_prologue (CORE_ADDR pc)
{
int i, firstline, currline;
int i;
struct symtab_and_line v_sal;
struct symbol *v_function;
CORE_ADDR salendaddr = 0, endaddr = 0;
CORE_ADDR endaddr;
/* We will handle only functions beginning with:
55 pushq %rbp
@ -817,7 +875,7 @@ x86_64_skip_prologue (CORE_ADDR pc)
/* First check, whether pc points to pushq %rbp, movq %rsp,%rbp. */
for (i = 0; i < PROLOG_BUFSIZE; i++)
if (prolog_expect[i] != prolog_buf[i])
return pc; /* ... no, it doesn't. Nothing to skip. */
return pc; /* ... no, it doesn't. Nothing to skip. */
/* OK, we have found the prologue and want PC of the first
non-prologue instruction. */
@ -831,18 +889,13 @@ x86_64_skip_prologue (CORE_ADDR pc)
if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
return pc;
firstline = v_sal.line;
currline = firstline;
salendaddr = v_sal.end;
endaddr = v_function->ginfo.value.block->endaddr;
for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
if (v_sal.symtab->linetable->item[i].line > firstline
&& v_sal.symtab->linetable->item[i].pc >= salendaddr
if (v_sal.symtab->linetable->item[i].pc >= pc
&& v_sal.symtab->linetable->item[i].pc < endaddr)
{
pc = v_sal.symtab->linetable->item[i].pc;
currline = v_sal.symtab->linetable->item[i].line;
break;
}
@ -859,7 +912,7 @@ x86_64_breakpoint_from_pc (CORE_ADDR * pc, int *lenptr)
}
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
x86_64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
@ -885,7 +938,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
break;
default:
internal_error (__FILE__, __LINE__,
"i386_gdbarch_init: unknown machine type");
"x86_64_gdbarch_init: unknown machine type");
}
break;
case bfd_mach_i386_i386:
@ -902,12 +955,12 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
return arches->gdbarch;
default:
internal_error (__FILE__, __LINE__,
"i386_gdbarch_init: unknown machine type");
"x86_64_gdbarch_init: unknown machine type");
}
break;
default:
internal_error (__FILE__, __LINE__,
"i386_gdbarch_init: unknown machine type");
"x86_64_gdbarch_init: unknown machine type");
}
}
@ -927,7 +980,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
break;
default:
internal_error (__FILE__, __LINE__,
"i386_gdbarch_init: unknown machine type");
"x86_64_gdbarch_init: unknown machine type");
}
set_gdbarch_long_bit (gdbarch, 64);
@ -967,7 +1020,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS); /* First FPU floating-point register. */
set_gdbarch_read_fp (gdbarch, cfi_read_fp);
set_gdbarch_write_fp (gdbarch, cfi_write_fp);
/* Discard from the stack the innermost frame, restoring all registers. */
set_gdbarch_pop_frame (gdbarch, x86_64_pop_frame);
@ -1056,8 +1108,11 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, x86_64_breakpoint_from_pc);
set_gdbarch_breakpoint_from_pc (gdbarch,
(gdbarch_breakpoint_from_pc_ftype *)
x86_64_breakpoint_from_pc);
set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
/* Amount PC must be decremented by after a breakpoint. This is often the
number of bytes in BREAKPOINT but not always. */
@ -1065,13 +1120,15 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Use dwarf2 debug frame informations. */
set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
return gdbarch;
}
void
_initialize_x86_64_tdep (void)
{
register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
register_gdbarch_init (bfd_arch_i386, x86_64_gdbarch_init);
/* Initialize the table saying where each register starts in the
register file. */

View File

@ -28,6 +28,10 @@
extern int x86_64_num_regs;
extern int x86_64_num_gregs;
int x86_64_register_number (const char *name);
char *x86_64_register_name (int reg_nr);
gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;