mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-05 06:23:58 +08:00
* infrun.c (IN_SOLIB_TRAMPOLINE): Correct comment, trampolines
are in the .plt section. * minsyms.c (lookup_solib_trampoline_symbol_by_pc, find_solib_trampoline_target): New functions for handling stepping into -g compiled shared libraries. * symtab.h (lookup_solib_trampoline_symbol_by_pc, find_solib_trampoline_target): Add prototypes. * config/tm-sunos.h (IN_SOLIB_TRAMPOLINE, SKIP_TRAMPOLINE_CODE): Define to handle stepping into -g compiled shared libraries. * config/tm-sysv4.h (SKIP_TRAMPOLINE_CODE): Define to handle stepping into -g compiled shared libraries. * configure.in: Add mips-*-sysv4* support. * config/mips/mipsv4.mh, config/mips/mipsv4.mt, config/mips/tm-mipsv4.h, config/mips/xm-mipsv4.h, mipsv4-nat.c: New files for MIPS SVR4 support. * Makefile.in: Update for new mipsv4 files. * alpha-tdep.c (heuristic_proc_desc, find_proc_desc): Use read_next_frame_reg to obtain the frame relative stack pointer. * mips-tdep.c (heuristic_proc_desc): Use read_next_frame_reg to obtain the frame relative stack pointer. * mdebugread.c (parse_partial_symbols, psymtab_to_symtab1): Handle stStatic and stStaticProc symbols in stabs-in-ecoff output by entering them into the minimal symbol table. * printcmd.c (print_scalar_formatted): Do not try to unpack to a long for float formats. * solib.c: Include "elf/mips.h" only if DT_MIPS_RLD_MAP does not get defined in <link.h>. * solib.c (solib_add): Add shared library sections to the section table of the target before adding the symbols. * partial-stab.h: Relocate static and global functions. * dbxread.c (read_dbx_symtab): Remove unused variable end_of_text_address. Relocate text_addr when passing it to end_psymtab. For Alpha OSF/1 targets, enable gdb to set breakpoints in shared library functions before the executable is run. Retrieve dynamic symbols from stripped executables. * mipsread.c (read_alphacoff_dynamic_symtab): New function. * mipsread.c (mipscoff_symfile_read): Use it. Issue warning message if no debugging symbols were found. * alpha-tdep.c (alpha_skip_prologue): Silently return the unaltered pc if memory at the pc is not accessible and GDB_TARGET_HAS_SHARED_LIBS is defined. * config/alpha/nm-alpha.h (GDB_TARGET_HAS_SHARED_LIBS): Define, OSF/1 has shared libraries.
This commit is contained in:
@ -203,6 +203,7 @@ mips-nat.c
|
|||||||
mips-pinsn.c
|
mips-pinsn.c
|
||||||
mips-tdep.c
|
mips-tdep.c
|
||||||
mipsm3-nat.c
|
mipsm3-nat.c
|
||||||
|
mipsv4-nat.c
|
||||||
mipsread.c
|
mipsread.c
|
||||||
monitor.h
|
monitor.h
|
||||||
news-xdep.c
|
news-xdep.c
|
||||||
|
@ -1,3 +1,55 @@
|
|||||||
|
Thu Apr 7 17:25:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||||
|
Jim Kingdon (kingdon@cygnus.com)
|
||||||
|
|
||||||
|
* infrun.c (IN_SOLIB_TRAMPOLINE): Correct comment, trampolines
|
||||||
|
are in the .plt section.
|
||||||
|
* minsyms.c (lookup_solib_trampoline_symbol_by_pc,
|
||||||
|
find_solib_trampoline_target): New functions for handling
|
||||||
|
stepping into -g compiled shared libraries.
|
||||||
|
* symtab.h (lookup_solib_trampoline_symbol_by_pc,
|
||||||
|
find_solib_trampoline_target): Add prototypes.
|
||||||
|
* config/tm-sunos.h (IN_SOLIB_TRAMPOLINE, SKIP_TRAMPOLINE_CODE):
|
||||||
|
Define to handle stepping into -g compiled shared libraries.
|
||||||
|
* config/tm-sysv4.h (SKIP_TRAMPOLINE_CODE): Define to handle
|
||||||
|
stepping into -g compiled shared libraries.
|
||||||
|
|
||||||
|
Thu Apr 7 17:22:54 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||||
|
|
||||||
|
* configure.in: Add mips-*-sysv4* support.
|
||||||
|
* config/mips/mipsv4.mh, config/mips/mipsv4.mt,
|
||||||
|
config/mips/tm-mipsv4.h, config/mips/xm-mipsv4.h, mipsv4-nat.c:
|
||||||
|
New files for MIPS SVR4 support.
|
||||||
|
* Makefile.in: Update for new mipsv4 files.
|
||||||
|
* alpha-tdep.c (heuristic_proc_desc, find_proc_desc): Use
|
||||||
|
read_next_frame_reg to obtain the frame relative stack pointer.
|
||||||
|
* mips-tdep.c (heuristic_proc_desc): Use read_next_frame_reg to
|
||||||
|
obtain the frame relative stack pointer.
|
||||||
|
* mdebugread.c (parse_partial_symbols, psymtab_to_symtab1):
|
||||||
|
Handle stStatic and stStaticProc symbols in stabs-in-ecoff output
|
||||||
|
by entering them into the minimal symbol table.
|
||||||
|
* printcmd.c (print_scalar_formatted): Do not try to unpack to
|
||||||
|
a long for float formats.
|
||||||
|
* solib.c: Include "elf/mips.h" only if DT_MIPS_RLD_MAP does not
|
||||||
|
get defined in <link.h>.
|
||||||
|
* solib.c (solib_add): Add shared library sections to the section
|
||||||
|
table of the target before adding the symbols.
|
||||||
|
* partial-stab.h: Relocate static and global functions.
|
||||||
|
* dbxread.c (read_dbx_symtab): Remove unused variable
|
||||||
|
end_of_text_address. Relocate text_addr when passing it
|
||||||
|
to end_psymtab.
|
||||||
|
|
||||||
|
For Alpha OSF/1 targets, enable gdb to set breakpoints in shared
|
||||||
|
library functions before the executable is run. Retrieve dynamic
|
||||||
|
symbols from stripped executables.
|
||||||
|
* mipsread.c (read_alphacoff_dynamic_symtab): New function.
|
||||||
|
* mipsread.c (mipscoff_symfile_read): Use it. Issue warning message
|
||||||
|
if no debugging symbols were found.
|
||||||
|
* alpha-tdep.c (alpha_skip_prologue): Silently return the unaltered
|
||||||
|
pc if memory at the pc is not accessible and GDB_TARGET_HAS_SHARED_LIBS
|
||||||
|
is defined.
|
||||||
|
* config/alpha/nm-alpha.h (GDB_TARGET_HAS_SHARED_LIBS): Define,
|
||||||
|
OSF/1 has shared libraries.
|
||||||
|
|
||||||
Thu Apr 7 15:11:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
Thu Apr 7 15:11:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||||
|
|
||||||
* dbxread.c (read_dbx_dynamic_symtab): Adjust for recent changes
|
* dbxread.c (read_dbx_dynamic_symtab): Adjust for recent changes
|
||||||
|
@ -329,7 +329,7 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame)
|
|||||||
CORE_ADDR start_pc, limit_pc;
|
CORE_ADDR start_pc, limit_pc;
|
||||||
FRAME next_frame;
|
FRAME next_frame;
|
||||||
{
|
{
|
||||||
CORE_ADDR sp = next_frame ? next_frame->frame : read_register (SP_REGNUM);
|
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
|
||||||
CORE_ADDR cur_pc;
|
CORE_ADDR cur_pc;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
int has_frame_reg = 0;
|
int has_frame_reg = 0;
|
||||||
@ -456,7 +456,7 @@ find_proc_desc(pc, next_frame)
|
|||||||
if (PC_IN_CALL_DUMMY (pc, 0, 0))
|
if (PC_IN_CALL_DUMMY (pc, 0, 0))
|
||||||
{
|
{
|
||||||
struct linked_proc_info *link;
|
struct linked_proc_info *link;
|
||||||
CORE_ADDR sp = next_frame ? next_frame->frame : read_register (SP_REGNUM);
|
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
|
||||||
alpha_extra_func_info_t found_proc_desc = NULL;
|
alpha_extra_func_info_t found_proc_desc = NULL;
|
||||||
long min_distance = LONG_MAX;
|
long min_distance = LONG_MAX;
|
||||||
|
|
||||||
@ -913,6 +913,18 @@ alpha_skip_prologue (pc, lenient)
|
|||||||
unsigned long inst;
|
unsigned long inst;
|
||||||
int offset;
|
int offset;
|
||||||
CORE_ADDR post_prologue_pc;
|
CORE_ADDR post_prologue_pc;
|
||||||
|
char buf[4];
|
||||||
|
|
||||||
|
#ifdef GDB_TARGET_HAS_SHARED_LIBS
|
||||||
|
/* Silently return the unaltered pc upon memory errors.
|
||||||
|
This could happen on OSF/1 if decode_line_1 tries to skip the
|
||||||
|
prologue for quickstarted shared library functions when the
|
||||||
|
shared library is not yet mapped in.
|
||||||
|
Reading target memory is slow over serial lines, so we perform
|
||||||
|
this check only if the target has shared libraries. */
|
||||||
|
if (target_read_memory (pc, buf, 4))
|
||||||
|
return pc;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* See if we can determine the end of the prologue via the symbol table.
|
/* See if we can determine the end of the prologue via the symbol table.
|
||||||
If so, then return either PC, or the PC after the prologue, whichever
|
If so, then return either PC, or the PC after the prologue, whichever
|
||||||
@ -931,7 +943,6 @@ alpha_skip_prologue (pc, lenient)
|
|||||||
or in the gcc frame. */
|
or in the gcc frame. */
|
||||||
for (offset = 0; offset < 100; offset += 4)
|
for (offset = 0; offset < 100; offset += 4)
|
||||||
{
|
{
|
||||||
char buf[4];
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = read_memory_nobpt (pc + offset, buf, 4);
|
status = read_memory_nobpt (pc + offset, buf, 4);
|
||||||
|
@ -94,6 +94,7 @@ mips-sgi-irix3*) gdb_host=irix3 ;;
|
|||||||
mips-sgi-irix4*) gdb_host=irix4 ;;
|
mips-sgi-irix4*) gdb_host=irix4 ;;
|
||||||
mips-sgi-irix5*) gdb_host=irix5 ;;
|
mips-sgi-irix5*) gdb_host=irix5 ;;
|
||||||
mips-sony-*) gdb_host=news-mips ;;
|
mips-sony-*) gdb_host=news-mips ;;
|
||||||
|
mips-*-sysv4*) gdb_host=mipsv4 ;;
|
||||||
mips-*-sysv*) gdb_host=riscos ;;
|
mips-*-sysv*) gdb_host=riscos ;;
|
||||||
mips-*-riscos*) gdb_host=riscos ;;
|
mips-*-riscos*) gdb_host=riscos ;;
|
||||||
mips-*-mach*) gdb_host=mipsm3 ;;
|
mips-*-mach*) gdb_host=mipsm3 ;;
|
||||||
@ -280,6 +281,7 @@ mips*-little-*) gdb_target=littlemips ;;
|
|||||||
mips*-sgi-irix5*) gdb_target=irix5 ;;
|
mips*-sgi-irix5*) gdb_target=irix5 ;;
|
||||||
mips*-sgi-*) gdb_target=irix3 ;;
|
mips*-sgi-*) gdb_target=irix3 ;;
|
||||||
mips*-sony-*) gdb_target=bigmips ;;
|
mips*-sony-*) gdb_target=bigmips ;;
|
||||||
|
mips*-*-sysv4*) gdb_target=mipsv4 ;;
|
||||||
mips*-*-sysv*) gdb_target=bigmips ;;
|
mips*-*-sysv*) gdb_target=bigmips ;;
|
||||||
mips*-*-riscos*) gdb_target=bigmips ;;
|
mips*-*-riscos*) gdb_target=bigmips ;;
|
||||||
mips*-*-mach*) gdb_target=mipsm3 ;;
|
mips*-*-mach*) gdb_target=mipsm3 ;;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Read dbx symbol tables and convert to internal format, for GDB.
|
/* Read dbx symbol tables and convert to internal format, for GDB.
|
||||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
|
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
@ -984,9 +984,6 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
|
|||||||
struct cleanup *back_to;
|
struct cleanup *back_to;
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
|
|
||||||
/* End of the text segment of the executable file. */
|
|
||||||
CORE_ADDR end_of_text_addr;
|
|
||||||
|
|
||||||
/* Current partial symtab */
|
/* Current partial symtab */
|
||||||
struct partial_symtab *pst;
|
struct partial_symtab *pst;
|
||||||
|
|
||||||
@ -1100,7 +1097,8 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
|
|||||||
end_psymtab (pst, psymtab_include_list, includes_used,
|
end_psymtab (pst, psymtab_include_list, includes_used,
|
||||||
symnum * symbol_size,
|
symnum * symbol_size,
|
||||||
(lowest_text_address == (CORE_ADDR)-1
|
(lowest_text_address == (CORE_ADDR)-1
|
||||||
? text_addr : lowest_text_address)
|
? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
|
||||||
|
: lowest_text_address)
|
||||||
+ text_size,
|
+ text_size,
|
||||||
dependency_list, dependencies_used);
|
dependency_list, dependencies_used);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ hook_stop_stub PARAMS ((char *));
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For SVR4 shared libraries, each call goes through a small piece of
|
/* For SVR4 shared libraries, each call goes through a small piece of
|
||||||
trampoline code in the ".init" section. IN_SOLIB_TRAMPOLINE evaluates
|
trampoline code in the ".plt" section. IN_SOLIB_TRAMPOLINE evaluates
|
||||||
to nonzero if we are current stopped in one of these. */
|
to nonzero if we are current stopped in one of these. */
|
||||||
#ifndef IN_SOLIB_TRAMPOLINE
|
#ifndef IN_SOLIB_TRAMPOLINE
|
||||||
#define IN_SOLIB_TRAMPOLINE(pc,name) 0
|
#define IN_SOLIB_TRAMPOLINE(pc,name) 0
|
||||||
@ -1714,7 +1714,7 @@ signals_info (signum_exp, from_tty)
|
|||||||
|
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
/* These ugly casts brought to you by the native VAX compiler. */
|
/* These ugly casts brought to you by the native VAX compiler. */
|
||||||
for (oursig = 0;
|
for (oursig = TARGET_SIGNAL_FIRST;
|
||||||
(int)oursig < (int)TARGET_SIGNAL_LAST;
|
(int)oursig < (int)TARGET_SIGNAL_LAST;
|
||||||
oursig = (enum target_signal)((int)oursig + 1))
|
oursig = (enum target_signal)((int)oursig + 1))
|
||||||
{
|
{
|
||||||
|
@ -2332,6 +2332,16 @@ parse_partial_symbols (objfile, section_offsets)
|
|||||||
long isym;
|
long isym;
|
||||||
|
|
||||||
sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
||||||
|
if (sh.st == stStaticProc)
|
||||||
|
{
|
||||||
|
namestring = debug_info->ss + fh->issBase + sh.iss;
|
||||||
|
prim_record_minimal_symbol_and_info (namestring,
|
||||||
|
sh.value,
|
||||||
|
mst_file_text,
|
||||||
|
NULL,
|
||||||
|
SECT_OFF_TEXT,
|
||||||
|
objfile);
|
||||||
|
}
|
||||||
procaddr = sh.value;
|
procaddr = sh.value;
|
||||||
|
|
||||||
isym = AUX_GET_ISYM (fh->fBigendian,
|
isym = AUX_GET_ISYM (fh->fBigendian,
|
||||||
@ -2350,6 +2360,42 @@ parse_partial_symbols (objfile, section_offsets)
|
|||||||
pst->texthigh = high;
|
pst->texthigh = high;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (sh.st == stStatic)
|
||||||
|
{
|
||||||
|
switch (sh.sc)
|
||||||
|
{
|
||||||
|
case scUndefined:
|
||||||
|
case scNil:
|
||||||
|
case scAbs:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case scData:
|
||||||
|
case scSData:
|
||||||
|
case scRData:
|
||||||
|
case scPData:
|
||||||
|
case scXData:
|
||||||
|
namestring = debug_info->ss + fh->issBase + sh.iss;
|
||||||
|
sh.value += ANOFFSET (section_offsets, SECT_OFF_DATA);
|
||||||
|
prim_record_minimal_symbol_and_info (namestring,
|
||||||
|
sh.value,
|
||||||
|
mst_file_data,
|
||||||
|
NULL,
|
||||||
|
SECT_OFF_DATA,
|
||||||
|
objfile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
namestring = debug_info->ss + fh->issBase + sh.iss;
|
||||||
|
sh.value += ANOFFSET (section_offsets, SECT_OFF_BSS);
|
||||||
|
prim_record_minimal_symbol_and_info (namestring,
|
||||||
|
sh.value,
|
||||||
|
mst_file_bss,
|
||||||
|
NULL,
|
||||||
|
SECT_OFF_BSS,
|
||||||
|
objfile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#define SET_NAMESTRING() \
|
#define SET_NAMESTRING() \
|
||||||
@ -2913,7 +2959,8 @@ psymtab_to_symtab_1 (pst, filename)
|
|||||||
/* Handle encoded stab line number. */
|
/* Handle encoded stab line number. */
|
||||||
record_line (current_subfile, sh.index, valu);
|
record_line (current_subfile, sh.index, valu);
|
||||||
}
|
}
|
||||||
else if (sh.st == stProc || sh.st == stStaticProc || sh.st == stEnd)
|
else if (sh.st == stProc || sh.st == stStaticProc
|
||||||
|
|| sh.st == stStatic || sh.st == stEnd)
|
||||||
/* These are generated by gcc-2.x, do not complain */
|
/* These are generated by gcc-2.x, do not complain */
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
|
@ -601,3 +601,48 @@ install_minimal_symbols (objfile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if PC is in a shared library trampoline code stub.
|
||||||
|
Return minimal symbol for the trampoline entry or NULL if PC is not
|
||||||
|
in a trampoline code stub. */
|
||||||
|
|
||||||
|
struct minimal_symbol *
|
||||||
|
lookup_solib_trampoline_symbol_by_pc (pc)
|
||||||
|
CORE_ADDR pc;
|
||||||
|
{
|
||||||
|
struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
|
||||||
|
|
||||||
|
if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
|
||||||
|
return msymbol;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If PC is in a shared library trampoline code stub, return the
|
||||||
|
address of the `real' function belonging to the stub.
|
||||||
|
Return 0 if PC is not in a trampoline code stub or if the real
|
||||||
|
function is not found in the minimal symbol table.
|
||||||
|
|
||||||
|
We may fail to find the right function if a function with the
|
||||||
|
same name is defined in more than one shared library, but this
|
||||||
|
is considered bad programming style. We could return 0 if we find
|
||||||
|
a duplicate function in case this matters someday. */
|
||||||
|
|
||||||
|
CORE_ADDR
|
||||||
|
find_solib_trampoline_target (pc)
|
||||||
|
CORE_ADDR pc;
|
||||||
|
{
|
||||||
|
struct objfile *objfile;
|
||||||
|
struct minimal_symbol *msymbol;
|
||||||
|
struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc);
|
||||||
|
|
||||||
|
if (tsymbol != NULL)
|
||||||
|
{
|
||||||
|
ALL_MSYMBOLS (objfile, msymbol)
|
||||||
|
{
|
||||||
|
if (MSYMBOL_TYPE (msymbol) == mst_text
|
||||||
|
&& STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (tsymbol)))
|
||||||
|
return SYMBOL_VALUE_ADDRESS (msymbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
311
gdb/mipsread.c
311
gdb/mipsread.c
@ -1,6 +1,6 @@
|
|||||||
/* Read a symbol table in MIPS' format (Third-Eye).
|
/* Read a symbol table in MIPS' format (Third-Eye).
|
||||||
Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993 Free Software
|
Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994
|
||||||
Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work
|
Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU. Major work
|
||||||
by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
|
by Per Bothner, John Gilmore and Ian Lance Taylor at Cygnus Support.
|
||||||
|
|
||||||
@ -24,6 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
mdebugread.c. */
|
mdebugread.c. */
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include "bfd.h"
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
@ -31,10 +33,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "stabsread.h"
|
#include "stabsread.h"
|
||||||
#include "gdb-stabs.h"
|
#include "gdb-stabs.h"
|
||||||
|
|
||||||
|
#include "coff/sym.h"
|
||||||
#include "coff/internal.h"
|
#include "coff/internal.h"
|
||||||
#include "coff/ecoff.h"
|
#include "coff/ecoff.h"
|
||||||
#include "libcoff.h" /* Private BFD COFF information. */
|
#include "libcoff.h" /* Private BFD COFF information. */
|
||||||
#include "libecoff.h" /* Private BFD ECOFF information. */
|
#include "libecoff.h" /* Private BFD ECOFF information. */
|
||||||
|
#include "elf/common.h"
|
||||||
|
#include "elf/mips.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mipscoff_new_init PARAMS ((struct objfile *));
|
mipscoff_new_init PARAMS ((struct objfile *));
|
||||||
@ -52,6 +57,10 @@ mipscoff_symfile_finish PARAMS ((struct objfile *));
|
|||||||
static struct section_offsets *
|
static struct section_offsets *
|
||||||
mipscoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
|
mipscoff_symfile_offsets PARAMS ((struct objfile *, CORE_ADDR));
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_alphacoff_dynamic_symtab PARAMS ((struct section_offsets *,
|
||||||
|
struct objfile *objfile));
|
||||||
|
|
||||||
/* Initialize anything that needs initializing when a completely new
|
/* Initialize anything that needs initializing when a completely new
|
||||||
symbol file is specified (not just adding some symbols from another
|
symbol file is specified (not just adding some symbols from another
|
||||||
file, e.g. a shared library). */
|
file, e.g. a shared library). */
|
||||||
@ -93,11 +102,23 @@ mipscoff_symfile_read (objfile, section_offsets, mainline)
|
|||||||
process it and define symbols accordingly. */
|
process it and define symbols accordingly. */
|
||||||
|
|
||||||
if (ecoff_slurp_symbolic_info (abfd) == false)
|
if (ecoff_slurp_symbolic_info (abfd) == false)
|
||||||
error ("Error reading symbol table: %s", bfd_errmsg (bfd_error));
|
error ("Error reading symbol table: %s", bfd_errmsg (bfd_get_error ()));
|
||||||
|
|
||||||
mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
|
mdebug_build_psymtabs (objfile, &ecoff_backend (abfd)->debug_swap,
|
||||||
&ecoff_data (abfd)->debug_info, section_offsets);
|
&ecoff_data (abfd)->debug_info, section_offsets);
|
||||||
|
|
||||||
|
/* Add the dynamic symbols if we are reading the main symbol table. */
|
||||||
|
|
||||||
|
if (mainline)
|
||||||
|
read_alphacoff_dynamic_symtab (section_offsets, objfile);
|
||||||
|
|
||||||
|
if (!have_partial_symbols ())
|
||||||
|
{
|
||||||
|
wrap_here ("");
|
||||||
|
printf_filtered ("(no debugging symbols found)...");
|
||||||
|
wrap_here ("");
|
||||||
|
}
|
||||||
|
|
||||||
/* Install any minimal symbols that have been collected as the current
|
/* Install any minimal symbols that have been collected as the current
|
||||||
minimal symbols for this objfile. */
|
minimal symbols for this objfile. */
|
||||||
|
|
||||||
@ -138,6 +159,290 @@ mipscoff_symfile_offsets (objfile, addr)
|
|||||||
return section_offsets;
|
return section_offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Alpha OSF/1 encapsulates the dynamic symbols in ELF format in a
|
||||||
|
standard coff section. The ELF format for the symbols differs from
|
||||||
|
the format defined in elf/external.h. It seems that a normal ELF 32 bit
|
||||||
|
format is used, and the representation only changes because longs are
|
||||||
|
64 bit on the alpha. In addition, the handling of text/data section
|
||||||
|
indices for symbols is different from the ELF ABI.
|
||||||
|
As the BFD linker currently does not support dynamic linking on the alpha,
|
||||||
|
there seems to be no reason to pollute BFD with another mixture of object
|
||||||
|
file formats for now. */
|
||||||
|
|
||||||
|
/* Format of an alpha external ELF symbol. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char st_name[4]; /* Symbol name, index in string tbl */
|
||||||
|
unsigned char st_pad[4]; /* Pad to long word boundary */
|
||||||
|
unsigned char st_value[8]; /* Value of the symbol */
|
||||||
|
unsigned char st_size[4]; /* Associated symbol size */
|
||||||
|
unsigned char st_info[1]; /* Type and binding attributes */
|
||||||
|
unsigned char st_other[1]; /* No defined meaning, 0 */
|
||||||
|
unsigned char st_shndx[2]; /* Associated section index */
|
||||||
|
} Elfalpha_External_Sym;
|
||||||
|
|
||||||
|
/* Format of an alpha external ELF dynamic info structure. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char d_tag[4]; /* Tag */
|
||||||
|
unsigned char d_pad[4]; /* Pad to long word boundary */
|
||||||
|
union {
|
||||||
|
unsigned char d_ptr[8]; /* Pointer value */
|
||||||
|
unsigned char d_val[4]; /* Integer value */
|
||||||
|
} d_un;
|
||||||
|
} Elfalpha_External_Dyn;
|
||||||
|
|
||||||
|
/* Struct to obtain the section pointers for alpha dynamic symbol info. */
|
||||||
|
|
||||||
|
struct alphacoff_dynsecinfo {
|
||||||
|
asection *sym_sect; /* Section pointer for .dynsym section */
|
||||||
|
asection *str_sect; /* Section pointer for .dynstr section */
|
||||||
|
asection *dyninfo_sect; /* Section pointer for .dynamic section */
|
||||||
|
asection *got_sect; /* Section pointer for .got section */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
alphacoff_locate_sections PARAMS ((bfd *, asection *, void *));
|
||||||
|
|
||||||
|
/* We are called once per section from read_alphacoff_dynamic_symtab.
|
||||||
|
We need to examine each section we are passed, check to see
|
||||||
|
if it is something we are interested in processing, and
|
||||||
|
if so, stash away some access information for the section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
alphacoff_locate_sections (ignore_abfd, sectp, sip)
|
||||||
|
bfd *ignore_abfd;
|
||||||
|
asection *sectp;
|
||||||
|
PTR sip;
|
||||||
|
{
|
||||||
|
register struct alphacoff_dynsecinfo *si;
|
||||||
|
|
||||||
|
si = (struct alphacoff_dynsecinfo *) sip;
|
||||||
|
|
||||||
|
if (STREQ (sectp->name, ".dynsym"))
|
||||||
|
{
|
||||||
|
si->sym_sect = sectp;
|
||||||
|
}
|
||||||
|
else if (STREQ (sectp->name, ".dynstr"))
|
||||||
|
{
|
||||||
|
si->str_sect = sectp;
|
||||||
|
}
|
||||||
|
else if (STREQ (sectp->name, ".dynamic"))
|
||||||
|
{
|
||||||
|
si->dyninfo_sect = sectp;
|
||||||
|
}
|
||||||
|
else if (STREQ (sectp->name, ".got"))
|
||||||
|
{
|
||||||
|
si->got_sect = sectp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan an alpha dynamic symbol table for symbols of interest and
|
||||||
|
add them to the minimal symbol table. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_alphacoff_dynamic_symtab (section_offsets, objfile)
|
||||||
|
struct section_offsets *section_offsets;
|
||||||
|
struct objfile *objfile;
|
||||||
|
{
|
||||||
|
bfd *abfd = objfile->obfd;
|
||||||
|
struct alphacoff_dynsecinfo si;
|
||||||
|
char *sym_secptr;
|
||||||
|
char *str_secptr;
|
||||||
|
char *dyninfo_secptr;
|
||||||
|
char *got_secptr;
|
||||||
|
bfd_size_type sym_secsize;
|
||||||
|
bfd_size_type str_secsize;
|
||||||
|
bfd_size_type dyninfo_secsize;
|
||||||
|
bfd_size_type got_secsize;
|
||||||
|
int sym_count;
|
||||||
|
int i;
|
||||||
|
int stripped;
|
||||||
|
Elfalpha_External_Sym *x_symp;
|
||||||
|
char *dyninfo_p;
|
||||||
|
char *dyninfo_end;
|
||||||
|
int got_entry_size = 8;
|
||||||
|
int dt_mips_local_gotno = -1;
|
||||||
|
int dt_mips_gotsym = -1;
|
||||||
|
|
||||||
|
|
||||||
|
/* We currently only know how to handle alpha dynamic symbols. */
|
||||||
|
if (bfd_get_arch (abfd) != bfd_arch_alpha)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Locate the dynamic symbols sections and read them in. */
|
||||||
|
memset ((char *) &si, 0, sizeof (si));
|
||||||
|
bfd_map_over_sections (abfd, alphacoff_locate_sections, (PTR) &si);
|
||||||
|
if (si.sym_sect == NULL
|
||||||
|
|| si.str_sect == NULL
|
||||||
|
|| si.dyninfo_sect == NULL
|
||||||
|
|| si.got_sect == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sym_secsize = bfd_get_section_size_before_reloc (si.sym_sect);
|
||||||
|
str_secsize = bfd_get_section_size_before_reloc (si.str_sect);
|
||||||
|
dyninfo_secsize = bfd_get_section_size_before_reloc (si.dyninfo_sect);
|
||||||
|
got_secsize = bfd_get_section_size_before_reloc (si.got_sect);
|
||||||
|
sym_secptr = alloca (sym_secsize);
|
||||||
|
str_secptr = alloca (str_secsize);
|
||||||
|
dyninfo_secptr = alloca (dyninfo_secsize);
|
||||||
|
got_secptr = alloca (got_secsize);
|
||||||
|
|
||||||
|
if (!bfd_get_section_contents (abfd, si.sym_sect, sym_secptr,
|
||||||
|
(file_ptr)0, sym_secsize))
|
||||||
|
return;
|
||||||
|
if (!bfd_get_section_contents (abfd, si.str_sect, str_secptr,
|
||||||
|
(file_ptr)0, str_secsize))
|
||||||
|
return;
|
||||||
|
if (!bfd_get_section_contents (abfd, si.dyninfo_sect, dyninfo_secptr,
|
||||||
|
(file_ptr)0, dyninfo_secsize))
|
||||||
|
return;
|
||||||
|
if (!bfd_get_section_contents (abfd, si.got_sect, got_secptr,
|
||||||
|
(file_ptr)0, got_secsize))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Find the number of local GOT entries and the index for the
|
||||||
|
the first dynamic symbol in the GOT. */
|
||||||
|
for (dyninfo_p = dyninfo_secptr, dyninfo_end = dyninfo_p + dyninfo_secsize;
|
||||||
|
dyninfo_p < dyninfo_end;
|
||||||
|
dyninfo_p += sizeof (Elfalpha_External_Dyn))
|
||||||
|
{
|
||||||
|
Elfalpha_External_Dyn *x_dynp = (Elfalpha_External_Dyn *)dyninfo_p;
|
||||||
|
long dyn_tag;
|
||||||
|
|
||||||
|
dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_tag);
|
||||||
|
if (dyn_tag == DT_NULL)
|
||||||
|
break;
|
||||||
|
else if (dyn_tag == DT_MIPS_LOCAL_GOTNO)
|
||||||
|
{
|
||||||
|
dt_mips_local_gotno = bfd_h_get_32 (abfd,
|
||||||
|
(bfd_byte *) x_dynp->d_un.d_val);
|
||||||
|
}
|
||||||
|
else if (dyn_tag == DT_MIPS_GOTSYM)
|
||||||
|
{
|
||||||
|
dt_mips_gotsym = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp->d_un.d_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dt_mips_local_gotno < 0 || dt_mips_gotsym < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Scan all dynamic symbols and enter them into the minimal symbol table
|
||||||
|
if appropriate. */
|
||||||
|
sym_count = sym_secsize / sizeof (Elfalpha_External_Sym);
|
||||||
|
stripped = (bfd_get_symcount (abfd) == 0);
|
||||||
|
|
||||||
|
/* Skip first symbol, which is a null dummy. */
|
||||||
|
for (i = 1, x_symp = (Elfalpha_External_Sym *) sym_secptr + 1;
|
||||||
|
i < sym_count;
|
||||||
|
i++, x_symp++)
|
||||||
|
{
|
||||||
|
unsigned long strx;
|
||||||
|
char *name;
|
||||||
|
bfd_vma sym_value;
|
||||||
|
unsigned char sym_info;
|
||||||
|
unsigned int sym_shndx;
|
||||||
|
int isglobal;
|
||||||
|
enum minimal_symbol_type ms_type;
|
||||||
|
|
||||||
|
strx = bfd_h_get_32 (abfd, (bfd_byte *) x_symp->st_name);
|
||||||
|
if (strx >= str_secsize)
|
||||||
|
continue;
|
||||||
|
name = str_secptr + strx;
|
||||||
|
if (*name == '\0' || *name == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sym_value = bfd_h_get_64 (abfd, (bfd_byte *) x_symp->st_value);
|
||||||
|
sym_info = bfd_h_get_8 (abfd, (bfd_byte *) x_symp->st_info);
|
||||||
|
sym_shndx = bfd_h_get_16 (abfd, (bfd_byte *) x_symp->st_shndx);
|
||||||
|
isglobal = (ELF_ST_BIND (sym_info) == STB_GLOBAL);
|
||||||
|
|
||||||
|
if (sym_shndx == SHN_UNDEF)
|
||||||
|
{
|
||||||
|
/* Handle undefined functions which are defined in a shared
|
||||||
|
library. */
|
||||||
|
if (ELF_ST_TYPE (sym_info) != STT_FUNC
|
||||||
|
|| ELF_ST_BIND (sym_info) != STB_GLOBAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ms_type = mst_solib_trampoline;
|
||||||
|
|
||||||
|
/* If sym_value is nonzero, it points to the shared library
|
||||||
|
trampoline entry, which is what we are looking for.
|
||||||
|
|
||||||
|
If sym_value is zero, then we have to get the GOT entry
|
||||||
|
for the symbol.
|
||||||
|
If the GOT entry is nonzero, it represents the quickstart
|
||||||
|
address of the function and we use that as the symbol value.
|
||||||
|
|
||||||
|
If the GOT entry is zero, the function address has to be resolved
|
||||||
|
by the runtime loader before the executable is started.
|
||||||
|
We are unable to find any meaningful address for these
|
||||||
|
functions in the executable file, so we skip them. */
|
||||||
|
if (sym_value == 0)
|
||||||
|
{
|
||||||
|
int got_entry_offset =
|
||||||
|
(i - dt_mips_gotsym + dt_mips_local_gotno) * got_entry_size;
|
||||||
|
|
||||||
|
if (got_entry_offset < 0 || got_entry_offset >= got_secsize)
|
||||||
|
continue;
|
||||||
|
sym_value =
|
||||||
|
bfd_h_get_64 (abfd,
|
||||||
|
(bfd_byte *) (got_secptr + got_entry_offset));
|
||||||
|
if (sym_value == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Symbols defined in the executable itself. We only care about
|
||||||
|
them if this is a stripped executable, otherwise they have
|
||||||
|
been retrieved from the normal symbol table already. */
|
||||||
|
if (!stripped)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sym_shndx == SHN_MIPS_TEXT)
|
||||||
|
{
|
||||||
|
if (isglobal)
|
||||||
|
ms_type = mst_text;
|
||||||
|
else
|
||||||
|
ms_type = mst_file_text;
|
||||||
|
sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
||||||
|
}
|
||||||
|
else if (sym_shndx == SHN_MIPS_DATA)
|
||||||
|
{
|
||||||
|
if (isglobal)
|
||||||
|
ms_type = mst_data;
|
||||||
|
else
|
||||||
|
ms_type = mst_file_data;
|
||||||
|
sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA);
|
||||||
|
}
|
||||||
|
else if (sym_shndx == SHN_MIPS_ACOMMON)
|
||||||
|
{
|
||||||
|
if (isglobal)
|
||||||
|
ms_type = mst_bss;
|
||||||
|
else
|
||||||
|
ms_type = mst_file_bss;
|
||||||
|
sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS);
|
||||||
|
}
|
||||||
|
else if (sym_shndx == SHN_ABS)
|
||||||
|
{
|
||||||
|
ms_type = mst_abs;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prim_record_minimal_symbol (obsavestring (name,
|
||||||
|
strlen (name),
|
||||||
|
&objfile -> symbol_obstack),
|
||||||
|
sym_value,
|
||||||
|
ms_type,
|
||||||
|
objfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
static struct sym_fns ecoff_sym_fns =
|
static struct sym_fns ecoff_sym_fns =
|
||||||
|
148
gdb/mipsv4-nat.c
Normal file
148
gdb/mipsv4-nat.c
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* Native support for MIPS running SVR4, for GDB.
|
||||||
|
Copyright 1994 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "inferior.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/procfs.h>
|
||||||
|
#include <setjmp.h> /* For JB_XXX. */
|
||||||
|
|
||||||
|
/* Size of elements in jmpbuf */
|
||||||
|
|
||||||
|
#define JB_ELEMENT_SIZE 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See the comment in m68k-tdep.c regarding the utility of these functions.
|
||||||
|
*
|
||||||
|
* These definitions are from the MIPS SVR4 ABI, so they may work for
|
||||||
|
* any MIPS SVR4 target.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
supply_gregset (gregsetp)
|
||||||
|
gregset_t *gregsetp;
|
||||||
|
{
|
||||||
|
register int regi;
|
||||||
|
register greg_t *regp = &(*gregsetp)[0];
|
||||||
|
|
||||||
|
for(regi = 0; regi <= CXT_RA; regi++)
|
||||||
|
supply_register (regi, (char *)(regp + regi));
|
||||||
|
|
||||||
|
supply_register (PC_REGNUM, (char *)(regp + CXT_EPC));
|
||||||
|
supply_register (HI_REGNUM, (char *)(regp + CXT_MDHI));
|
||||||
|
supply_register (LO_REGNUM, (char *)(regp + CXT_MDLO));
|
||||||
|
supply_register (CAUSE_REGNUM, (char *)(regp + CXT_CAUSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fill_gregset (gregsetp, regno)
|
||||||
|
gregset_t *gregsetp;
|
||||||
|
int regno;
|
||||||
|
{
|
||||||
|
int regi;
|
||||||
|
register greg_t *regp = &(*gregsetp)[0];
|
||||||
|
|
||||||
|
for (regi = 0; regi <= 32; regi++)
|
||||||
|
if ((regno == -1) || (regno == regi))
|
||||||
|
*(regp + regi) = *(greg_t *) ®isters[REGISTER_BYTE (regi)];
|
||||||
|
|
||||||
|
if ((regno == -1) || (regno == PC_REGNUM))
|
||||||
|
*(regp + CXT_EPC) = *(greg_t *) ®isters[REGISTER_BYTE (PC_REGNUM)];
|
||||||
|
|
||||||
|
if ((regno == -1) || (regno == CAUSE_REGNUM))
|
||||||
|
*(regp + CXT_CAUSE) = *(greg_t *) ®isters[REGISTER_BYTE (PS_REGNUM)];
|
||||||
|
|
||||||
|
if ((regno == -1) || (regno == HI_REGNUM))
|
||||||
|
*(regp + CXT_MDHI) = *(greg_t *) ®isters[REGISTER_BYTE (HI_REGNUM)];
|
||||||
|
|
||||||
|
if ((regno == -1) || (regno == LO_REGNUM))
|
||||||
|
*(regp + CXT_MDLO) = *(greg_t *) ®isters[REGISTER_BYTE (LO_REGNUM)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we do the same thing for floating-point registers.
|
||||||
|
* We don't bother to condition on FP0_REGNUM since any
|
||||||
|
* reasonable MIPS configuration has an R3010 in it.
|
||||||
|
*
|
||||||
|
* Again, see the comments in m68k-tdep.c.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
supply_fpregset (fpregsetp)
|
||||||
|
fpregset_t *fpregsetp;
|
||||||
|
{
|
||||||
|
register int regi;
|
||||||
|
|
||||||
|
for (regi = 0; regi < 32; regi++)
|
||||||
|
supply_register (FP0_REGNUM + regi,
|
||||||
|
(char *)&fpregsetp->fp_r.fp_regs[regi]);
|
||||||
|
|
||||||
|
supply_register (FCRCS_REGNUM, (char *)&fpregsetp->fp_csr);
|
||||||
|
|
||||||
|
/* FIXME: how can we supply FCRIR_REGNUM? The ABI doesn't tell us. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fill_fpregset (fpregsetp, regno)
|
||||||
|
fpregset_t *fpregsetp;
|
||||||
|
int regno;
|
||||||
|
{
|
||||||
|
int regi;
|
||||||
|
char *from, *to;
|
||||||
|
|
||||||
|
for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
|
||||||
|
{
|
||||||
|
if ((regno == -1) || (regno == regi))
|
||||||
|
{
|
||||||
|
from = (char *) ®isters[REGISTER_BYTE (regi)];
|
||||||
|
to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
|
||||||
|
memcpy(to, from, REGISTER_RAW_SIZE (regi));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((regno == -1) || (regno == FCRCS_REGNUM))
|
||||||
|
fpregsetp->fp_csr = *(unsigned *) ®isters[REGISTER_BYTE(FCRCS_REGNUM)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Figure out where the longjmp will land.
|
||||||
|
We expect the first arg to be a pointer to the jmp_buf structure from which
|
||||||
|
we extract the pc (_JB_PC) that we will land at. The pc is copied into PC.
|
||||||
|
This routine returns true on success. */
|
||||||
|
|
||||||
|
int
|
||||||
|
get_longjmp_target (pc)
|
||||||
|
CORE_ADDR *pc;
|
||||||
|
{
|
||||||
|
char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
|
||||||
|
CORE_ADDR jb_addr;
|
||||||
|
|
||||||
|
jb_addr = read_register (A0_REGNUM);
|
||||||
|
|
||||||
|
if (target_read_memory (jb_addr + _JB_PC * JB_ELEMENT_SIZE, buf,
|
||||||
|
TARGET_PTR_BIT / TARGET_CHAR_BIT))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* Shared code to pre-read a stab (dbx-style), when building a psymtab.
|
/* Shared code to pre-read a stab (dbx-style), when building a psymtab.
|
||||||
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
|
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
@ -496,6 +496,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
||||||
#ifdef DBXREAD_ONLY
|
#ifdef DBXREAD_ONLY
|
||||||
/* Kludges for ELF/STABS with Sun ACC */
|
/* Kludges for ELF/STABS with Sun ACC */
|
||||||
last_function_name = namestring;
|
last_function_name = namestring;
|
||||||
@ -517,6 +518,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
are put into the global psymtab like one would expect.
|
are put into the global psymtab like one would expect.
|
||||||
They're also in the minimal symbol table. */
|
They're also in the minimal symbol table. */
|
||||||
case 'F':
|
case 'F':
|
||||||
|
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
||||||
#ifdef DBXREAD_ONLY
|
#ifdef DBXREAD_ONLY
|
||||||
/* Kludges for ELF/STABS with Sun ACC */
|
/* Kludges for ELF/STABS with Sun ACC */
|
||||||
last_function_name = namestring;
|
last_function_name = namestring;
|
||||||
|
@ -74,11 +74,6 @@ static unsigned int max_symbolic_offset = UINT_MAX;
|
|||||||
printing a symbolic value as `<symbol at filename:linenum>' if set. */
|
printing a symbolic value as `<symbol at filename:linenum>' if set. */
|
||||||
static int print_symbol_filename = 0;
|
static int print_symbol_filename = 0;
|
||||||
|
|
||||||
/* Switch for quick display of symbolic addresses -- only uses minsyms,
|
|
||||||
not full search of symtabs. */
|
|
||||||
|
|
||||||
int fast_symbolic_addr = 1;
|
|
||||||
|
|
||||||
/* Number of auto-display expression currently being displayed.
|
/* Number of auto-display expression currently being displayed.
|
||||||
So that we can disable it if we get an error or a signal within it.
|
So that we can disable it if we get an error or a signal within it.
|
||||||
-1 when not doing one. */
|
-1 when not doing one. */
|
||||||
@ -374,7 +369,8 @@ print_scalar_formatted (valaddr, type, format, size, stream)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val_long = unpack_long (type, valaddr);
|
if (format != 'f')
|
||||||
|
val_long = unpack_long (type, valaddr);
|
||||||
|
|
||||||
/* If we are printing it as unsigned, truncate it in case it is actually
|
/* If we are printing it as unsigned, truncate it in case it is actually
|
||||||
a negative signed value (e.g. "print/u (short)-1" should print 65535
|
a negative signed value (e.g. "print/u (short)-1" should print 65535
|
||||||
@ -533,15 +529,15 @@ print_address_symbolic (addr, stream, do_demangle, leadin)
|
|||||||
/* First try to find the address in the symbol table, then
|
/* First try to find the address in the symbol table, then
|
||||||
in the minsyms. Take the closest one. */
|
in the minsyms. Take the closest one. */
|
||||||
|
|
||||||
if (fast_symbolic_addr)
|
/* This is defective in the sense that it only finds text symbols. So
|
||||||
{
|
really this is kind of pointless--we should make sure that the
|
||||||
/* This is defective in the sense that it only finds text symbols. */
|
minimal symbols have everything we need (by changing that we could
|
||||||
symbol = find_pc_function (addr);
|
save some memory, but for many debug format--ELF/DWARF or
|
||||||
if (symbol)
|
anything/stabs--it would be inconvenient to eliminate those minimal
|
||||||
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
|
symbols anyway). */
|
||||||
}
|
symbol = find_pc_function (addr);
|
||||||
else
|
if (symbol)
|
||||||
find_addr_symbol (addr, &symtab, &name_location);
|
name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (symbol));
|
||||||
|
|
||||||
if (symbol)
|
if (symbol)
|
||||||
{
|
{
|
||||||
@ -2183,13 +2179,6 @@ environment, the value is printed in its own window.");
|
|||||||
&setprintlist),
|
&setprintlist),
|
||||||
&showprintlist);
|
&showprintlist);
|
||||||
|
|
||||||
add_show_from_set (
|
|
||||||
add_set_cmd ("fast-symbolic-addr", no_class, var_boolean,
|
|
||||||
(char *)&fast_symbolic_addr,
|
|
||||||
"Set fast printing of symbolic addresses (using minimal symbols).",
|
|
||||||
&setprintlist),
|
|
||||||
&showprintlist);
|
|
||||||
|
|
||||||
examine_b_type = init_type (TYPE_CODE_INT, 1, 0, NULL, NULL);
|
examine_b_type = init_type (TYPE_CODE_INT, 1, 0, NULL, NULL);
|
||||||
examine_h_type = init_type (TYPE_CODE_INT, 2, 0, NULL, NULL);
|
examine_h_type = init_type (TYPE_CODE_INT, 2, 0, NULL, NULL);
|
||||||
examine_w_type = init_type (TYPE_CODE_INT, 4, 0, NULL, NULL);
|
examine_w_type = init_type (TYPE_CODE_INT, 4, 0, NULL, NULL);
|
||||||
|
294
gdb/solib.c
294
gdb/solib.c
@ -1,5 +1,5 @@
|
|||||||
/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
|
/* Handle SunOS and SVR4 shared libraries for GDB, the GNU Debugger.
|
||||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
@ -30,6 +30,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#ifndef SVR4_SHARED_LIBS
|
#ifndef SVR4_SHARED_LIBS
|
||||||
/* SunOS shared libs need the nlist structure. */
|
/* SunOS shared libs need the nlist structure. */
|
||||||
#include <a.out.h>
|
#include <a.out.h>
|
||||||
|
#else
|
||||||
|
#include "libelf.h"
|
||||||
|
#ifndef DT_MIPS_RLD_MAP
|
||||||
|
#include "elf/mips.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
@ -71,15 +76,12 @@ static char *bkpt_names[] = {
|
|||||||
|
|
||||||
/* Symbols which are used to locate the base of the link map structures. */
|
/* Symbols which are used to locate the base of the link map structures. */
|
||||||
|
|
||||||
|
#ifndef SVR4_SHARED_LIBS
|
||||||
static char *debug_base_symbols[] = {
|
static char *debug_base_symbols[] = {
|
||||||
#ifdef SVR4_SHARED_LIBS
|
"_DYNAMIC",
|
||||||
"_r_debug", /* Most SVR4 systems, Solaris 2.1, 2.2 */
|
|
||||||
"r_debug", /* Solaris 2.3 */
|
|
||||||
#else
|
|
||||||
"_DYNAMIC", /* SunOS */
|
|
||||||
#endif
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* local data declarations */
|
/* local data declarations */
|
||||||
|
|
||||||
@ -164,11 +166,8 @@ solib_map_sections PARAMS ((struct so_list *));
|
|||||||
|
|
||||||
#ifdef SVR4_SHARED_LIBS
|
#ifdef SVR4_SHARED_LIBS
|
||||||
|
|
||||||
static int
|
|
||||||
look_for_base PARAMS ((int, CORE_ADDR));
|
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
bfd_lookup_symbol PARAMS ((bfd *, char *));
|
elf_locate_base PARAMS ((void));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -250,7 +249,7 @@ solib_map_sections (so)
|
|||||||
if (build_section_table (abfd, &so -> sections, &so -> sections_end))
|
if (build_section_table (abfd, &so -> sections, &so -> sections_end))
|
||||||
{
|
{
|
||||||
error ("Can't find the file sections in `%s': %s",
|
error ("Can't find the file sections in `%s': %s",
|
||||||
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
|
bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p = so -> sections; p < so -> sections_end; p++)
|
for (p = so -> sections; p < so -> sections_end; p++)
|
||||||
@ -261,7 +260,7 @@ solib_map_sections (so)
|
|||||||
p -> addr += (CORE_ADDR) LM_ADDR (so);
|
p -> addr += (CORE_ADDR) LM_ADDR (so);
|
||||||
p -> endaddr += (CORE_ADDR) LM_ADDR (so);
|
p -> endaddr += (CORE_ADDR) LM_ADDR (so);
|
||||||
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
|
so -> lmend = (CORE_ADDR) max (p -> endaddr, so -> lmend);
|
||||||
if (STREQ (p -> sec_ptr -> name, ".text"))
|
if (STREQ (p -> the_bfd_section -> name, ".text"))
|
||||||
{
|
{
|
||||||
so -> textsection = p;
|
so -> textsection = p;
|
||||||
}
|
}
|
||||||
@ -355,162 +354,95 @@ solib_add_common_symbols (rtc_symp, objfile)
|
|||||||
|
|
||||||
#endif /* SVR4_SHARED_LIBS */
|
#endif /* SVR4_SHARED_LIBS */
|
||||||
|
|
||||||
|
|
||||||
#ifdef SVR4_SHARED_LIBS
|
#ifdef SVR4_SHARED_LIBS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
LOCAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
bfd_lookup_symbol -- lookup the value for a specific symbol
|
elf_locate_base -- locate the base address of dynamic linker structs
|
||||||
|
for SVR4 elf targets.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
|
CORE_ADDR elf_locate_base (void)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
An expensive way to lookup the value of a single symbol for
|
For SVR4 elf targets the address of the dynamic linker's runtime
|
||||||
bfd's that are only temporary anyway. This is used by the
|
structure is contained within the dynamic info section in the
|
||||||
shared library support to find the address of the debugger
|
executable file. The dynamic section is also mapped into the
|
||||||
interface structures in the shared library.
|
inferior address space. Because the runtime loader fills in the
|
||||||
|
real address before starting the inferior, we have to read in the
|
||||||
|
dynamic info section from the inferior address space.
|
||||||
|
If there are any errors while trying to find the address, we
|
||||||
|
silently return 0, otherwise the found address is returned.
|
||||||
|
|
||||||
Note that 0 is specifically allowed as an error return (no
|
|
||||||
such symbol).
|
|
||||||
|
|
||||||
FIXME: See if there is a less "expensive" way of doing this.
|
|
||||||
Also see if there is already another bfd or gdb function
|
|
||||||
that specifically does this, and if so, use it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static CORE_ADDR
|
|
||||||
bfd_lookup_symbol (abfd, symname)
|
|
||||||
bfd *abfd;
|
|
||||||
char *symname;
|
|
||||||
{
|
|
||||||
unsigned int storage_needed;
|
|
||||||
asymbol *sym;
|
|
||||||
asymbol **symbol_table;
|
|
||||||
unsigned int number_of_symbols;
|
|
||||||
unsigned int i;
|
|
||||||
struct cleanup *back_to;
|
|
||||||
CORE_ADDR symaddr = 0;
|
|
||||||
|
|
||||||
storage_needed = get_symtab_upper_bound (abfd);
|
|
||||||
|
|
||||||
if (storage_needed > 0)
|
|
||||||
{
|
|
||||||
symbol_table = (asymbol **) xmalloc (storage_needed);
|
|
||||||
back_to = make_cleanup (free, (PTR)symbol_table);
|
|
||||||
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
|
|
||||||
|
|
||||||
for (i = 0; i < number_of_symbols; i++)
|
|
||||||
{
|
|
||||||
sym = *symbol_table++;
|
|
||||||
if (STREQ (sym -> name, symname))
|
|
||||||
{
|
|
||||||
/* Bfd symbols are section relative. */
|
|
||||||
symaddr = sym -> value + sym -> section -> vma;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
do_cleanups (back_to);
|
|
||||||
}
|
|
||||||
return (symaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
LOCAL FUNCTION
|
|
||||||
|
|
||||||
look_for_base -- examine file for each mapped address segment
|
|
||||||
|
|
||||||
SYNOPSYS
|
|
||||||
|
|
||||||
static int look_for_base (int fd, CORE_ADDR baseaddr)
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
|
|
||||||
This function is passed to proc_iterate_over_mappings, which
|
|
||||||
causes it to get called once for each mapped address space, with
|
|
||||||
an open file descriptor for the file mapped to that space, and the
|
|
||||||
base address of that mapped space.
|
|
||||||
|
|
||||||
Our job is to find the debug base symbol in the file that this
|
|
||||||
fd is open on, if it exists, and if so, initialize the dynamic
|
|
||||||
linker structure base address debug_base.
|
|
||||||
|
|
||||||
Note that this is a computationally expensive proposition, since
|
|
||||||
we basically have to open a bfd on every call, so we specifically
|
|
||||||
avoid opening the exec file.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static CORE_ADDR
|
||||||
look_for_base (fd, baseaddr)
|
elf_locate_base ()
|
||||||
int fd;
|
|
||||||
CORE_ADDR baseaddr;
|
|
||||||
{
|
{
|
||||||
bfd *interp_bfd;
|
struct elf_internal_shdr *dyninfo_sect;
|
||||||
CORE_ADDR address;
|
int dyninfo_sect_size;
|
||||||
char **symbolp;
|
CORE_ADDR dyninfo_addr;
|
||||||
|
char *buf;
|
||||||
|
char *bufend;
|
||||||
|
|
||||||
/* If the fd is -1, then there is no file that corresponds to this
|
/* Find the start address of the .dynamic section. */
|
||||||
mapped memory segment, so skip it. Also, if the fd corresponds
|
if (exec_bfd == NULL || bfd_get_flavour (exec_bfd) != bfd_target_elf_flavour)
|
||||||
to the exec file, skip it as well. */
|
return 0;
|
||||||
|
dyninfo_sect = bfd_elf_find_section (exec_bfd, ".dynamic");
|
||||||
|
if (dyninfo_sect == NULL)
|
||||||
|
return 0;
|
||||||
|
dyninfo_addr = dyninfo_sect->sh_addr;
|
||||||
|
|
||||||
if ((fd == -1) || fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd))
|
/* Read in .dynamic section, silently ignore errors. */
|
||||||
|
dyninfo_sect_size = dyninfo_sect->sh_size;
|
||||||
|
buf = alloca (dyninfo_sect_size);
|
||||||
|
if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Find the DT_DEBUG entry in the the .dynamic section.
|
||||||
|
For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
|
||||||
|
no DT_DEBUG entries. */
|
||||||
|
/* FIXME: In lack of a 64 bit ELF ABI the following code assumes
|
||||||
|
a 32 bit ELF ABI target. */
|
||||||
|
for (bufend = buf + dyninfo_sect_size;
|
||||||
|
buf < bufend;
|
||||||
|
buf += sizeof (Elf32_External_Dyn))
|
||||||
{
|
{
|
||||||
return (0);
|
Elf32_External_Dyn *x_dynp = (Elf32_External_Dyn *)buf;
|
||||||
}
|
long dyn_tag;
|
||||||
|
CORE_ADDR dyn_ptr;
|
||||||
|
|
||||||
/* Try to open whatever random file this fd corresponds to. Note that
|
dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_tag);
|
||||||
we have no way currently to find the filename. Don't gripe about
|
if (dyn_tag == DT_NULL)
|
||||||
any problems we might have, just fail. */
|
break;
|
||||||
|
else if (dyn_tag == DT_DEBUG)
|
||||||
if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (!bfd_check_format (interp_bfd, bfd_object))
|
|
||||||
{
|
|
||||||
bfd_close (interp_bfd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now try to find our debug base symbol in this file, which we at
|
|
||||||
least know to be a valid ELF executable or shared library. */
|
|
||||||
|
|
||||||
for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++)
|
|
||||||
{
|
|
||||||
address = bfd_lookup_symbol (interp_bfd, *symbolp);
|
|
||||||
if (address != 0)
|
|
||||||
{
|
{
|
||||||
break;
|
dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
|
||||||
|
return dyn_ptr;
|
||||||
|
}
|
||||||
|
else if (dyn_tag == DT_MIPS_RLD_MAP)
|
||||||
|
{
|
||||||
|
char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT];
|
||||||
|
|
||||||
|
/* DT_MIPS_RLD_MAP contains a pointer to the address
|
||||||
|
of the dynamic link structure. */
|
||||||
|
dyn_ptr = bfd_h_get_32 (exec_bfd, (bfd_byte *) x_dynp->d_un.d_ptr);
|
||||||
|
if (target_read_memory (dyn_ptr, pbuf, sizeof (pbuf)))
|
||||||
|
return 0;
|
||||||
|
return extract_unsigned_integer (pbuf, sizeof (pbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (address == 0)
|
|
||||||
{
|
|
||||||
bfd_close (interp_bfd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Eureka! We found the symbol. But now we may need to relocate it
|
/* DT_DEBUG entry not found. */
|
||||||
by the base address. If the symbol's value is less than the base
|
return 0;
|
||||||
address of the shared library, then it hasn't yet been relocated
|
|
||||||
by the dynamic linker, and we have to do it ourself. FIXME: Note
|
|
||||||
that we make the assumption that the first segment that corresponds
|
|
||||||
to the shared library has the base address to which the library
|
|
||||||
was relocated. */
|
|
||||||
|
|
||||||
if (address < baseaddr)
|
|
||||||
{
|
|
||||||
address += baseaddr;
|
|
||||||
}
|
|
||||||
debug_base = address;
|
|
||||||
bfd_close (interp_bfd);
|
|
||||||
return (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* SVR4_SHARED_LIBS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -540,20 +472,13 @@ DESCRIPTION
|
|||||||
have to do is look it up there. Note that we explicitly do NOT want
|
have to do is look it up there. Note that we explicitly do NOT want
|
||||||
to find the copies in the shared library.
|
to find the copies in the shared library.
|
||||||
|
|
||||||
The SVR4 version is much more complicated because the dynamic linker
|
The SVR4 version is a bit more complicated because the address
|
||||||
and it's structures are located in the shared C library, which gets
|
is contained somewhere in the dynamic info section. We have to go
|
||||||
run as the executable's "interpreter" by the kernel. We have to go
|
|
||||||
to a lot more work to discover the address of the debug base symbol.
|
to a lot more work to discover the address of the debug base symbol.
|
||||||
Because of this complexity, we cache the value we find and return that
|
Because of this complexity, we cache the value we find and return that
|
||||||
value on subsequent invocations. Note there is no copy in the
|
value on subsequent invocations. Note there is no copy in the
|
||||||
executable symbol tables.
|
executable symbol tables.
|
||||||
|
|
||||||
Note that we can assume nothing about the process state at the time
|
|
||||||
we need to find this address. We may be stopped on the first instruc-
|
|
||||||
tion of the interpreter (C shared library), the first instruction of
|
|
||||||
the executable itself, or somewhere else entirely (if we attached
|
|
||||||
to the process for example).
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
@ -585,14 +510,12 @@ locate_base ()
|
|||||||
|
|
||||||
/* Check to see if we have a currently valid address, and if so, avoid
|
/* Check to see if we have a currently valid address, and if so, avoid
|
||||||
doing all this work again and just return the cached address. If
|
doing all this work again and just return the cached address. If
|
||||||
we have no cached address, ask the /proc support interface to iterate
|
we have no cached address, try to locate it in the dynamic info
|
||||||
over the list of mapped address segments, calling look_for_base() for
|
section. */
|
||||||
each segment. When we are done, we will have either found the base
|
|
||||||
address or not. */
|
|
||||||
|
|
||||||
if (debug_base == 0)
|
if (debug_base == 0)
|
||||||
{
|
{
|
||||||
proc_iterate_over_mappings (look_for_base);
|
debug_base = elf_locate_base ();
|
||||||
}
|
}
|
||||||
return (debug_base);
|
return (debug_base);
|
||||||
|
|
||||||
@ -808,35 +731,10 @@ solib_add (arg_string, from_tty, target)
|
|||||||
error ("Invalid regexp: %s", re_err);
|
error ("Invalid regexp: %s", re_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Getting new symbols may change our opinion about what is
|
/* Add the shared library sections to the section table of the
|
||||||
frameless. */
|
specified target, if any. We have to do this before reading the
|
||||||
reinit_frame_cache ();
|
symbol files as symbol_file_add calls reinit_frame_cache and
|
||||||
|
creating a new frame might access memory in the shared library. */
|
||||||
while ((so = find_solib (so)) != NULL)
|
|
||||||
{
|
|
||||||
if (so -> so_name[0] && re_exec (so -> so_name))
|
|
||||||
{
|
|
||||||
so -> from_tty = from_tty;
|
|
||||||
if (so -> symbols_loaded)
|
|
||||||
{
|
|
||||||
if (from_tty)
|
|
||||||
{
|
|
||||||
printf_unfiltered ("Symbols already loaded for %s\n", so -> so_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (catch_errors
|
|
||||||
(symbol_add_stub, (char *) so,
|
|
||||||
"Error while reading shared library symbols:\n",
|
|
||||||
RETURN_MASK_ALL))
|
|
||||||
{
|
|
||||||
so_last = so;
|
|
||||||
so -> symbols_loaded = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now add the shared library sections to the section table of the
|
|
||||||
specified target, if any. */
|
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
/* Count how many new section_table entries there are. */
|
/* Count how many new section_table entries there are. */
|
||||||
@ -883,6 +781,30 @@ solib_add (arg_string, from_tty, target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now add the symbol files. */
|
||||||
|
while ((so = find_solib (so)) != NULL)
|
||||||
|
{
|
||||||
|
if (so -> so_name[0] && re_exec (so -> so_name))
|
||||||
|
{
|
||||||
|
so -> from_tty = from_tty;
|
||||||
|
if (so -> symbols_loaded)
|
||||||
|
{
|
||||||
|
if (from_tty)
|
||||||
|
{
|
||||||
|
printf_unfiltered ("Symbols already loaded for %s\n", so -> so_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (catch_errors
|
||||||
|
(symbol_add_stub, (char *) so,
|
||||||
|
"Error while reading shared library symbols:\n",
|
||||||
|
RETURN_MASK_ALL))
|
||||||
|
{
|
||||||
|
so_last = so;
|
||||||
|
so -> symbols_loaded = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Calling this once at the end means that we put all the minimal
|
/* Calling this once at the end means that we put all the minimal
|
||||||
symbols for commons into the objfile for the last shared library.
|
symbols for commons into the objfile for the last shared library.
|
||||||
Since they are in common, this should not be a problem. If we
|
Since they are in common, this should not be a problem. If we
|
||||||
|
29
gdb/symtab.h
29
gdb/symtab.h
@ -26,8 +26,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#define obstack_chunk_alloc xmalloc
|
#define obstack_chunk_alloc xmalloc
|
||||||
#define obstack_chunk_free free
|
#define obstack_chunk_free free
|
||||||
|
|
||||||
/* GNU C supports enums that are bitfields. Some old compilers don't. */
|
/* Don't do this; it means that if some .o's are compiled with GNU C
|
||||||
#if defined(__GNUC__) && !defined(BYTE_BITFIELD)
|
and some are not (easy to do accidentally the way we configure
|
||||||
|
things; also it is a pain to have to "make clean" every time you
|
||||||
|
want to switch compilers), then GDB dies a horrible death. */
|
||||||
|
/* GNU C supports enums that are bitfields. Some compilers don't. */
|
||||||
|
#if 0 && defined(__GNUC__) && !defined(BYTE_BITFIELD)
|
||||||
#define BYTE_BITFIELD :8;
|
#define BYTE_BITFIELD :8;
|
||||||
#else
|
#else
|
||||||
#define BYTE_BITFIELD /*nothing*/
|
#define BYTE_BITFIELD /*nothing*/
|
||||||
@ -57,6 +61,9 @@ struct general_symbol_info
|
|||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
/* The fact that this is a long not a LONGEST mainly limits the
|
||||||
|
range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not
|
||||||
|
sure that is a big deal. */
|
||||||
long value;
|
long value;
|
||||||
|
|
||||||
struct block *block;
|
struct block *block;
|
||||||
@ -299,6 +306,15 @@ struct minimal_symbol
|
|||||||
mst_data, /* Generally initialized data */
|
mst_data, /* Generally initialized data */
|
||||||
mst_bss, /* Generally uninitialized data */
|
mst_bss, /* Generally uninitialized data */
|
||||||
mst_abs, /* Generally absolute (nonrelocatable) */
|
mst_abs, /* Generally absolute (nonrelocatable) */
|
||||||
|
/* GDB uses mst_solib_trampoline for the start address of a shared
|
||||||
|
library trampoline entry. Breakpoints for shared library functions
|
||||||
|
are put there if the shared library is not yet loaded.
|
||||||
|
After the shared library is loaded, lookup_minimal_symbol will
|
||||||
|
prefer the minimal symbol from the shared library (usually
|
||||||
|
a mst_text symbol) over the mst_solib_trampoline symbol, and the
|
||||||
|
breakpoints will be moved to their true address in the shared
|
||||||
|
library via breakpoint_re_set. */
|
||||||
|
mst_solib_trampoline, /* Shared library trampoline code */
|
||||||
/* For the mst_file* types, the names are only guaranteed to be unique
|
/* For the mst_file* types, the names are only guaranteed to be unique
|
||||||
within a given .o file. */
|
within a given .o file. */
|
||||||
mst_file_text, /* Static version of mst_text */
|
mst_file_text, /* Static version of mst_text */
|
||||||
@ -1016,6 +1032,12 @@ lookup_minimal_symbol PARAMS ((const char *, struct objfile *));
|
|||||||
extern struct minimal_symbol *
|
extern struct minimal_symbol *
|
||||||
lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR));
|
lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR));
|
||||||
|
|
||||||
|
extern struct minimal_symbol *
|
||||||
|
lookup_solib_trampoline_symbol_by_pc PARAMS ((CORE_ADDR));
|
||||||
|
|
||||||
|
extern CORE_ADDR
|
||||||
|
find_solib_trampoline_target PARAMS ((CORE_ADDR));
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
init_minimal_symbol_collection PARAMS ((void));
|
init_minimal_symbol_collection PARAMS ((void));
|
||||||
|
|
||||||
@ -1097,6 +1119,9 @@ maintenance_print_msymbols PARAMS ((char *, int));
|
|||||||
void
|
void
|
||||||
maintenance_print_objfiles PARAMS ((char *, int));
|
maintenance_print_objfiles PARAMS ((char *, int));
|
||||||
|
|
||||||
|
void
|
||||||
|
maintenance_check_symtabs PARAMS ((char *, int));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
|
Reference in New Issue
Block a user