mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-17 07:53:51 +08:00
2004-03-23 Andrew Cagney <cagney@redhat.com>
* tramp-frame.h, tramp-frame.h: New files. * Makefile.in (SFILES, tramp_frame_h, COMMON_OBS, tramp-frame.o): Update rules to include "tramp-frame.h" and "tramp-frame.c".
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
2004-03-23 Andrew Cagney <cagney@redhat.com>
|
2004-03-23 Andrew Cagney <cagney@redhat.com>
|
||||||
|
|
||||||
|
* tramp-frame.h, tramp-frame.h: New files.
|
||||||
|
* Makefile.in (SFILES, tramp_frame_h, COMMON_OBS, tramp-frame.o):
|
||||||
|
Update rules to include "tramp-frame.h" and "tramp-frame.c".
|
||||||
|
|
||||||
* Makefile.in: Update all dependencies.
|
* Makefile.in: Update all dependencies.
|
||||||
|
|
||||||
2004-03-23 Andrew Cagney <cagney@redhat.com>
|
2004-03-23 Andrew Cagney <cagney@redhat.com>
|
||||||
|
@ -541,6 +541,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
|
|||||||
stabsread.c stack.c std-regs.c symfile.c symmisc.c symtab.c \
|
stabsread.c stack.c std-regs.c symfile.c symmisc.c symtab.c \
|
||||||
target.c thread.c top.c tracepoint.c \
|
target.c thread.c top.c tracepoint.c \
|
||||||
trad-frame.c \
|
trad-frame.c \
|
||||||
|
tramp-frame.c \
|
||||||
typeprint.c \
|
typeprint.c \
|
||||||
ui-out.c utils.c ui-file.h ui-file.c \
|
ui-out.c utils.c ui-file.h ui-file.c \
|
||||||
user-regs.c \
|
user-regs.c \
|
||||||
@ -757,6 +758,7 @@ terminal_h = terminal.h
|
|||||||
top_h = top.h
|
top_h = top.h
|
||||||
tracepoint_h = tracepoint.h
|
tracepoint_h = tracepoint.h
|
||||||
trad_frame_h = trad-frame.h $(frame_h)
|
trad_frame_h = trad-frame.h $(frame_h)
|
||||||
|
tramp_frame_h = tramp-frame.h
|
||||||
typeprint_h = typeprint.h
|
typeprint_h = typeprint.h
|
||||||
ui_file_h = ui-file.h
|
ui_file_h = ui-file.h
|
||||||
ui_out_h = ui-out.h
|
ui_out_h = ui-out.h
|
||||||
@ -905,7 +907,8 @@ COMMON_OBS = $(DEPFILES) $(YYOBJ) \
|
|||||||
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \
|
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \
|
||||||
cp-namespace.o \
|
cp-namespace.o \
|
||||||
reggroups.o \
|
reggroups.o \
|
||||||
trad-frame.o
|
trad-frame.o \
|
||||||
|
tramp-frame.o
|
||||||
|
|
||||||
TSOBS = inflow.o
|
TSOBS = inflow.o
|
||||||
|
|
||||||
@ -2444,6 +2447,9 @@ tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(gdbtypes_h) \
|
|||||||
$(readline_history_h)
|
$(readline_history_h)
|
||||||
trad-frame.o: trad-frame.c $(defs_h) $(frame_h) $(trad_frame_h) \
|
trad-frame.o: trad-frame.c $(defs_h) $(frame_h) $(trad_frame_h) \
|
||||||
$(regcache_h)
|
$(regcache_h)
|
||||||
|
tramp-frame.o: tramp-frame.c $(defs_h) $(tramp_frame_h) $(frame_unwind_h) \
|
||||||
|
$(gdbcore_h) $(symtab_h) $(objfiles_h) $(target_h) $(trad_frame_h) \
|
||||||
|
$(frame_base_h)
|
||||||
typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
|
typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
|
||||||
$(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
|
$(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
|
||||||
$(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(typeprint_h) \
|
$(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(typeprint_h) \
|
||||||
|
162
gdb/tramp-frame.c
Normal file
162
gdb/tramp-frame.c
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/* Signal trampoline unwinder, for GDB the GNU Debugger.
|
||||||
|
|
||||||
|
Copyright 2004 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 "defs.h"
|
||||||
|
#include "tramp-frame.h"
|
||||||
|
#include "frame-unwind.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "symtab.h"
|
||||||
|
#include "objfiles.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "trad-frame.h"
|
||||||
|
#include "frame-base.h"
|
||||||
|
|
||||||
|
struct frame_data
|
||||||
|
{
|
||||||
|
const struct tramp_frame *tramp_frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tramp_frame_cache
|
||||||
|
{
|
||||||
|
CORE_ADDR func;
|
||||||
|
const struct tramp_frame *tramp_frame;
|
||||||
|
struct trad_frame_cache *trad_cache;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct trad_frame_cache *
|
||||||
|
tramp_frame_cache (struct frame_info *next_frame,
|
||||||
|
void **this_cache)
|
||||||
|
{
|
||||||
|
CORE_ADDR pc = frame_pc_unwind (next_frame);
|
||||||
|
struct tramp_frame_cache *tramp_cache = (*this_cache);
|
||||||
|
if (tramp_cache->trad_cache == NULL)
|
||||||
|
{
|
||||||
|
tramp_cache->trad_cache = trad_frame_cache_zalloc (next_frame);
|
||||||
|
tramp_cache->tramp_frame->init (tramp_cache->tramp_frame,
|
||||||
|
next_frame,
|
||||||
|
tramp_cache->trad_cache,
|
||||||
|
tramp_cache->func);
|
||||||
|
}
|
||||||
|
return tramp_cache->trad_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tramp_frame_this_id (struct frame_info *next_frame,
|
||||||
|
void **this_cache,
|
||||||
|
struct frame_id *this_id)
|
||||||
|
{
|
||||||
|
struct trad_frame_cache *trad_cache
|
||||||
|
= tramp_frame_cache (next_frame, this_cache);
|
||||||
|
trad_frame_get_id (trad_cache, this_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tramp_frame_prev_register (struct frame_info *next_frame,
|
||||||
|
void **this_cache,
|
||||||
|
int prev_regnum,
|
||||||
|
int *optimizedp,
|
||||||
|
enum lval_type * lvalp,
|
||||||
|
CORE_ADDR *addrp,
|
||||||
|
int *realnump, void *valuep)
|
||||||
|
{
|
||||||
|
struct trad_frame_cache *trad_cache
|
||||||
|
= tramp_frame_cache (next_frame, this_cache);
|
||||||
|
trad_frame_get_register (trad_cache, next_frame, prev_regnum, optimizedp,
|
||||||
|
lvalp, addrp, realnump, valuep);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
tramp_frame_start (CORE_ADDR pc, const struct tramp_frame *tramp)
|
||||||
|
{
|
||||||
|
int ti;
|
||||||
|
/* Search through the trampoline for one that matches the
|
||||||
|
instruction sequence around PC. */
|
||||||
|
for (ti = 0; tramp->insn[ti] != 0; ti++)
|
||||||
|
{
|
||||||
|
CORE_ADDR func = pc - tramp->insn_size * ti;
|
||||||
|
int i;
|
||||||
|
for (i = 0; 1; i++)
|
||||||
|
{
|
||||||
|
bfd_byte buf[sizeof (LONGEST)];
|
||||||
|
CORE_ADDR insn;
|
||||||
|
if (tramp->insn[i] == 0)
|
||||||
|
return func;
|
||||||
|
if (target_read_memory (func + i * tramp->insn_size, buf,
|
||||||
|
tramp->insn_size) != 0)
|
||||||
|
break;
|
||||||
|
insn = extract_unsigned_integer (buf, tramp->insn_size);
|
||||||
|
if (tramp->insn[i] != insn)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Trampoline doesn't match. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tramp_frame_sniffer (const struct frame_unwind *self,
|
||||||
|
struct frame_info *next_frame,
|
||||||
|
void **this_cache)
|
||||||
|
{
|
||||||
|
const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
|
||||||
|
CORE_ADDR pc = frame_pc_unwind (next_frame);
|
||||||
|
CORE_ADDR func;
|
||||||
|
char *name;
|
||||||
|
struct tramp_frame_cache *tramp_cache;
|
||||||
|
|
||||||
|
/* If the function has a valid symbol name, it isn't a
|
||||||
|
trampoline. */
|
||||||
|
find_pc_partial_function (pc, &name, NULL, NULL);
|
||||||
|
if (name != NULL)
|
||||||
|
return 0;
|
||||||
|
/* If the function lives in a valid section (even without a starting
|
||||||
|
point) it isn't a trampoline. */
|
||||||
|
if (find_pc_section (pc) != NULL)
|
||||||
|
return 0;
|
||||||
|
/* Finally, check that the trampoline matches at PC. */
|
||||||
|
func = tramp_frame_start (pc, tramp);
|
||||||
|
if (func == 0)
|
||||||
|
return 0;
|
||||||
|
tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
|
||||||
|
tramp_cache->func = func;
|
||||||
|
tramp_cache->tramp_frame = tramp;
|
||||||
|
(*this_cache) = tramp_cache;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tramp_frame_append (struct gdbarch *gdbarch,
|
||||||
|
const struct tramp_frame *tramp_frame)
|
||||||
|
{
|
||||||
|
struct frame_data *data;
|
||||||
|
struct frame_unwind *unwinder;
|
||||||
|
|
||||||
|
data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
|
||||||
|
unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
|
||||||
|
|
||||||
|
data->tramp_frame = tramp_frame;
|
||||||
|
unwinder->type = SIGTRAMP_FRAME;
|
||||||
|
unwinder->unwind_data = data;
|
||||||
|
unwinder->sniffer = tramp_frame_sniffer;
|
||||||
|
unwinder->this_id = tramp_frame_this_id;
|
||||||
|
unwinder->prev_register = tramp_frame_prev_register;
|
||||||
|
frame_unwind_register_unwinder (gdbarch, unwinder);
|
||||||
|
}
|
64
gdb/tramp-frame.h
Normal file
64
gdb/tramp-frame.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* Signal trampoline unwinder, for GDB the GNU Debugger.
|
||||||
|
|
||||||
|
Copyright 2004 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. */
|
||||||
|
|
||||||
|
#ifndef TRAMP_FRAME_H
|
||||||
|
#define TRAMP_FRAME_H
|
||||||
|
|
||||||
|
struct trad_frame;
|
||||||
|
struct frame_info;
|
||||||
|
struct trad_frame_cache;
|
||||||
|
|
||||||
|
/* A trampoline consists of a small sequence of instructions placed at
|
||||||
|
an unspecified location in the inferior's address space. The only
|
||||||
|
identifying attribute of the trampoline's address is that it does
|
||||||
|
not fall inside an object file's section.
|
||||||
|
|
||||||
|
The only way to identify a trampoline is to perform a brute force
|
||||||
|
examination of the instructions at and around the PC.
|
||||||
|
|
||||||
|
This module provides a convent interface for performing that
|
||||||
|
operation. */
|
||||||
|
|
||||||
|
/* A trampoline descriptor. */
|
||||||
|
|
||||||
|
struct tramp_frame
|
||||||
|
{
|
||||||
|
/* The trampoline's entire instruction sequence. Search for this in
|
||||||
|
the inferior at or around the frame's PC. It is assumed that the
|
||||||
|
PC is INSN_SIZE aligned, and that each element of TRAMP contains
|
||||||
|
one INSN_SIZE instruction. It is also assumed that TRAMP[0]
|
||||||
|
contains the first instruction of the trampoline and hence the
|
||||||
|
address of the instruction matching TRAMP[0] is the trampoline's
|
||||||
|
"func" address. */
|
||||||
|
int insn_size;
|
||||||
|
ULONGEST insn[8];
|
||||||
|
/* Initialize a trad-frame cache corresponding to the tramp-frame.
|
||||||
|
FUNC is the address of the instruction TRAMP[0] in memory. */
|
||||||
|
void (*init) (const struct tramp_frame *self,
|
||||||
|
struct frame_info *next_frame,
|
||||||
|
struct trad_frame_cache *this_cache,
|
||||||
|
CORE_ADDR func);
|
||||||
|
};
|
||||||
|
|
||||||
|
void tramp_frame_append (struct gdbarch *gdbarch,
|
||||||
|
const struct tramp_frame *tramp);
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user