mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-28 01:50:48 +00:00
Changes to implement the -mapped and -readnow options for commands that
read symbol tables.
This commit is contained in:
262
gdb/solib.c
262
gdb/solib.c
@@ -18,17 +18,19 @@ along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <link.h>
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <a.out.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "bfd.h"
|
||||
#include "symfile.h"
|
||||
#include "gdbcore.h"
|
||||
#include "command.h"
|
||||
#include "target.h"
|
||||
@@ -36,10 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "regex.h"
|
||||
#include "inferior.h"
|
||||
|
||||
extern char *getenv ();
|
||||
extern char *elf_interpreter (); /* Interpreter name from exec file */
|
||||
extern char *re_comp ();
|
||||
|
||||
#define MAX_PATH_SIZE 256 /* FIXME: Should be dynamic */
|
||||
|
||||
/* On SVR4 systems, for the initial implementation, use main() as the
|
||||
@@ -76,8 +74,6 @@ static CORE_ADDR flag_addr;
|
||||
#define LM_NAME(so) ((so) -> lm.l_name)
|
||||
static struct r_debug debug_copy;
|
||||
char shadow_contents[BREAKPOINT_MAX]; /* Stash old bkpt addr contents */
|
||||
extern CORE_ADDR proc_base_address ();
|
||||
extern int proc_address_to_fd ();
|
||||
|
||||
#endif /* !SVR4_SHARED_LIBS */
|
||||
|
||||
@@ -90,6 +86,7 @@ struct so_list {
|
||||
char symbols_loaded; /* flag: symbols read in yet? */
|
||||
char from_tty; /* flag: print msgs? */
|
||||
bfd *so_bfd; /* bfd for so_name */
|
||||
struct objfile *objfile; /* objfile for loaded lib */
|
||||
struct section_table *sections;
|
||||
struct section_table *sections_end;
|
||||
};
|
||||
@@ -98,6 +95,50 @@ static struct so_list *so_list_head; /* List of known shared objects */
|
||||
static CORE_ADDR debug_base; /* Base of dynamic linker structures */
|
||||
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
|
||||
|
||||
/* Local function prototypes */
|
||||
|
||||
static void
|
||||
special_symbol_handling PARAMS ((struct so_list *));
|
||||
|
||||
static void
|
||||
sharedlibrary_command PARAMS ((char *, int));
|
||||
|
||||
static int
|
||||
enable_break PARAMS ((void));
|
||||
|
||||
static int
|
||||
disable_break PARAMS ((void));
|
||||
|
||||
static void
|
||||
info_sharedlibrary_command PARAMS ((void));
|
||||
|
||||
static int
|
||||
symbol_add_stub PARAMS ((char *));
|
||||
|
||||
static struct so_list *
|
||||
find_solib PARAMS ((struct so_list *));
|
||||
|
||||
static struct link_map *
|
||||
first_link_map_member PARAMS ((void));
|
||||
|
||||
static CORE_ADDR
|
||||
locate_base PARAMS ((void));
|
||||
|
||||
static int
|
||||
look_for_base PARAMS ((int, CORE_ADDR));
|
||||
|
||||
static CORE_ADDR
|
||||
bfd_lookup_symbol PARAMS ((bfd *, char *));
|
||||
|
||||
static void
|
||||
solib_map_sections PARAMS ((struct so_list *));
|
||||
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
static void
|
||||
solib_add_common_symbols PARAMS ((struct rtc_symb *, struct objfile *));
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -179,56 +220,69 @@ solib_map_sections (so)
|
||||
}
|
||||
|
||||
/* Read all dynamically loaded common symbol definitions from the inferior
|
||||
and add them to the misc_function_vector. */
|
||||
and add them to the minimal symbol table for the shared library objfile. */
|
||||
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
static void
|
||||
solib_add_common_symbols (rtc_symp)
|
||||
solib_add_common_symbols (rtc_symp, objfile)
|
||||
struct rtc_symb *rtc_symp;
|
||||
struct objfile *objfile;
|
||||
{
|
||||
struct rtc_symb inferior_rtc_symb;
|
||||
struct nlist inferior_rtc_nlist;
|
||||
extern void discard_misc_bunches();
|
||||
int len;
|
||||
char *name;
|
||||
char *origname;
|
||||
|
||||
init_misc_bunches ();
|
||||
make_cleanup (discard_misc_bunches, 0);
|
||||
init_minimal_symbol_collection ();
|
||||
make_cleanup (discard_minimal_symbols, 0);
|
||||
|
||||
while (rtc_symp)
|
||||
{
|
||||
read_memory((CORE_ADDR)rtc_symp,
|
||||
&inferior_rtc_symb,
|
||||
sizeof(inferior_rtc_symb));
|
||||
read_memory((CORE_ADDR)inferior_rtc_symb.rtc_sp,
|
||||
&inferior_rtc_nlist,
|
||||
sizeof(inferior_rtc_nlist));
|
||||
if (inferior_rtc_nlist.n_type == N_COMM)
|
||||
{
|
||||
/* FIXME: The length of the symbol name is not available, but in the
|
||||
current implementation the common symbol is allocated immediately
|
||||
behind the name of the symbol. */
|
||||
int len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx;
|
||||
char *name, *origname;
|
||||
read_memory ((CORE_ADDR) rtc_symp,
|
||||
(char *) &inferior_rtc_symb,
|
||||
sizeof (inferior_rtc_symb));
|
||||
read_memory ((CORE_ADDR) inferior_rtc_symb.rtc_sp,
|
||||
(char *) &inferior_rtc_nlist,
|
||||
sizeof(inferior_rtc_nlist));
|
||||
if (inferior_rtc_nlist.n_type == N_COMM)
|
||||
{
|
||||
/* FIXME: The length of the symbol name is not available, but in the
|
||||
current implementation the common symbol is allocated immediately
|
||||
behind the name of the symbol. */
|
||||
len = inferior_rtc_nlist.n_value - inferior_rtc_nlist.n_un.n_strx;
|
||||
|
||||
origname = name = xmalloc (len);
|
||||
read_memory((CORE_ADDR)inferior_rtc_nlist.n_un.n_name, name, len);
|
||||
origname = name = xmalloc (len);
|
||||
read_memory ((CORE_ADDR) inferior_rtc_nlist.n_un.n_name, name, len);
|
||||
|
||||
/* Don't enter the symbol twice if the target is re-run. */
|
||||
/* Don't enter the symbol twice if the target is re-run. */
|
||||
|
||||
#ifdef NAMES_HAVE_UNDERSCORE
|
||||
if (*name == '_')
|
||||
name++;
|
||||
if (*name == '_')
|
||||
{
|
||||
name++;
|
||||
}
|
||||
#endif
|
||||
if (lookup_misc_func (name) < 0)
|
||||
prim_record_misc_function (obsavestring (name, strlen (name)),
|
||||
inferior_rtc_nlist.n_value,
|
||||
mf_bss);
|
||||
free (origname);
|
||||
}
|
||||
rtc_symp = inferior_rtc_symb.rtc_next;
|
||||
/* FIXME: Do we really want to exclude symbols which happen
|
||||
to match symbols for other locations in the inferior's
|
||||
address space, even when they are in different linkage units? */
|
||||
if (lookup_minimal_symbol (name, (struct objfile *) NULL) == NULL)
|
||||
{
|
||||
name = obsavestring (name, strlen (name),
|
||||
&objfile -> symbol_obstack);
|
||||
prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
|
||||
mst_bss);
|
||||
}
|
||||
free (origname);
|
||||
}
|
||||
rtc_symp = inferior_rtc_symb.rtc_next;
|
||||
}
|
||||
|
||||
condense_misc_bunches (1);
|
||||
/* Install any minimal symbols that have been collected as the current
|
||||
minimal symbols for this objfile. */
|
||||
|
||||
install_minimal_symbols (objfile);
|
||||
}
|
||||
|
||||
#endif /* SVR4_SHARED_LIBS */
|
||||
@@ -259,9 +313,9 @@ DESCRIPTION
|
||||
*/
|
||||
|
||||
static CORE_ADDR
|
||||
DEFUN (bfd_lookup_symbol, (abfd, symname),
|
||||
bfd *abfd AND
|
||||
char *symname)
|
||||
bfd_lookup_symbol (abfd, symname)
|
||||
bfd *abfd;
|
||||
char *symname;
|
||||
{
|
||||
unsigned int storage_needed;
|
||||
asymbol *sym;
|
||||
@@ -270,7 +324,6 @@ DEFUN (bfd_lookup_symbol, (abfd, symname),
|
||||
unsigned int i;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR symaddr = 0;
|
||||
enum misc_function_type mf_type;
|
||||
|
||||
storage_needed = get_symtab_upper_bound (abfd);
|
||||
|
||||
@@ -321,9 +374,9 @@ DESCRIPTION
|
||||
*/
|
||||
|
||||
static int
|
||||
DEFUN (look_for_base, (fd, baseaddr),
|
||||
int fd AND
|
||||
CORE_ADDR baseaddr)
|
||||
look_for_base (fd, baseaddr)
|
||||
int fd;
|
||||
CORE_ADDR baseaddr;
|
||||
{
|
||||
bfd *interp_bfd;
|
||||
CORE_ADDR address;
|
||||
@@ -401,15 +454,18 @@ DESCRIPTION
|
||||
For SunOS, the job is almost trivial, since the dynamic linker and
|
||||
all of it's structures are statically linked to the executable at
|
||||
link time. Thus the symbol for the address we are looking for has
|
||||
already been added to the misc function vector at the time the symbol
|
||||
file's symbols were read, and all we have to do is look it up there.
|
||||
already been added to the minimal symbol table for the executable's
|
||||
objfile at the time the symbol file's symbols were read, and all we
|
||||
have to do is look it up there. Note that we explicitly do NOT want
|
||||
to find the copies in the shared library.
|
||||
|
||||
The SVR4 version is much more complicated because the dynamic linker
|
||||
and it's structures are located in the shared C library, which gets
|
||||
run as the executable's "interpreter" by the kernel. We have to go
|
||||
to a lot more work to discover the address of DEBUG_BASE. Because
|
||||
of this complexity, we cache the value we find and return that value
|
||||
on subsequent invocations.
|
||||
on subsequent invocations. Note there is no copy in the 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-
|
||||
@@ -425,13 +481,17 @@ locate_base ()
|
||||
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
int i;
|
||||
struct minimal_symbol *msymbol;
|
||||
CORE_ADDR address = 0;
|
||||
|
||||
i = lookup_misc_func (DEBUG_BASE);
|
||||
if (i >= 0 && misc_function_vector[i].address != 0)
|
||||
/* For SunOS, we want to limit the search for DEBUG_BASE to the executable
|
||||
being debugged, since there is a duplicate named symbol in the shared
|
||||
library. We don't want the shared library versions. */
|
||||
|
||||
msymbol = lookup_minimal_symbol (DEBUG_BASE, symfile_objfile);
|
||||
if ((msymbol != NULL) && (msymbol -> address != 0))
|
||||
{
|
||||
address = misc_function_vector[i].address;
|
||||
address = msymbol -> address;
|
||||
}
|
||||
return (address);
|
||||
|
||||
@@ -461,19 +521,19 @@ first_link_map_member ()
|
||||
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
read_memory (debug_base, &dynamic_copy, sizeof (dynamic_copy));
|
||||
read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy));
|
||||
if (dynamic_copy.ld_version >= 2)
|
||||
{
|
||||
/* It is a version that we can deal with, so read in the secondary
|
||||
structure and find the address of the link map list from it. */
|
||||
read_memory ((CORE_ADDR) dynamic_copy.ld_un.ld_2, &ld_2_copy,
|
||||
read_memory ((CORE_ADDR) dynamic_copy.ld_un.ld_2, (char *) &ld_2_copy,
|
||||
sizeof (struct link_dynamic_2));
|
||||
lm = ld_2_copy.ld_loaded;
|
||||
}
|
||||
|
||||
#else /* SVR4_SHARED_LIBS */
|
||||
|
||||
read_memory (debug_base, &debug_copy, sizeof (struct r_debug));
|
||||
read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug));
|
||||
lm = debug_copy.r_map;
|
||||
|
||||
#endif /* !SVR4_SHARED_LIBS */
|
||||
@@ -483,7 +543,7 @@ first_link_map_member ()
|
||||
|
||||
/*
|
||||
|
||||
GLOBAL FUNCTION
|
||||
LOCAL FUNCTION
|
||||
|
||||
find_solib -- step through list of shared objects
|
||||
|
||||
@@ -504,7 +564,7 @@ DESCRIPTION
|
||||
in <link.h>.
|
||||
*/
|
||||
|
||||
struct so_list *
|
||||
static struct so_list *
|
||||
find_solib (so_list_ptr)
|
||||
struct so_list *so_list_ptr; /* Last lm or NULL for first one */
|
||||
{
|
||||
@@ -568,7 +628,8 @@ find_solib (so_list_ptr)
|
||||
so_list_head = new;
|
||||
}
|
||||
so_list_next = new;
|
||||
read_memory ((CORE_ADDR) lm, &(new -> lm), sizeof (struct link_map));
|
||||
read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),
|
||||
sizeof (struct link_map));
|
||||
/* For the SVR4 version, there is one entry that has no name
|
||||
(for the inferior executable) since it is not a shared object. */
|
||||
if (LM_NAME (new) != 0)
|
||||
@@ -591,8 +652,8 @@ symbol_add_stub (arg)
|
||||
{
|
||||
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
|
||||
|
||||
symbol_file_add (so -> so_name, so -> from_tty,
|
||||
(unsigned int) LM_ADDR (so), 0);
|
||||
so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,
|
||||
(unsigned int) LM_ADDR (so), 0, 0, 0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -644,10 +705,12 @@ solib_add (arg_string, from_tty, target)
|
||||
}
|
||||
else
|
||||
{
|
||||
so -> symbols_loaded = 1;
|
||||
so -> from_tty = from_tty;
|
||||
catch_errors (symbol_add_stub, (char *) so,
|
||||
"Error while reading shared library symbols:\n");
|
||||
|
||||
special_symbol_handling (so);
|
||||
so -> symbols_loaded = 1;
|
||||
so -> from_tty = from_tty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -737,7 +800,7 @@ info_sharedlibrary_command ()
|
||||
"Shared Object Library");
|
||||
header_done++;
|
||||
}
|
||||
printf ("%-12s", local_hex_string_custom (LM_ADDR (so), "08"));
|
||||
printf ("%-12s", local_hex_string_custom ((int) LM_ADDR (so), "08"));
|
||||
printf ("%-12s", local_hex_string_custom (so -> lmend, "08"));
|
||||
printf ("%-12s", so -> symbols_loaded ? "Yes" : "No");
|
||||
printf ("%s\n", so -> so_name);
|
||||
@@ -848,18 +911,14 @@ disable_break ()
|
||||
breakpoint address. Remove the breakpoint by writing the original
|
||||
contents back. */
|
||||
|
||||
read_memory (debug_addr, &debug_copy, sizeof (debug_copy));
|
||||
|
||||
/* Get common symbol definitions for the loaded object. */
|
||||
if (debug_copy.ldd_cp)
|
||||
solib_add_common_symbols (debug_copy.ldd_cp);
|
||||
read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy));
|
||||
|
||||
/* Set `in_debugger' to zero now. */
|
||||
|
||||
write_memory (flag_addr, &in_debugger, sizeof (in_debugger));
|
||||
write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger));
|
||||
|
||||
breakpoint_addr = (CORE_ADDR) debug_copy.ldd_bp_addr;
|
||||
write_memory (breakpoint_addr, &debug_copy.ldd_bp_inst,
|
||||
write_memory (breakpoint_addr, (char *) &debug_copy.ldd_bp_inst,
|
||||
sizeof (debug_copy.ldd_bp_inst));
|
||||
|
||||
#else /* SVR4_SHARED_LIBS */
|
||||
@@ -962,18 +1021,18 @@ enable_break ()
|
||||
|
||||
in_debugger = 1;
|
||||
|
||||
write_memory (flag_addr, &in_debugger, sizeof (in_debugger));
|
||||
write_memory (flag_addr, (char *) &in_debugger, sizeof (in_debugger));
|
||||
|
||||
#else /* SVR4_SHARED_LIBS */
|
||||
|
||||
#ifdef BKPT_AT_MAIN
|
||||
|
||||
int i;
|
||||
struct minimal_symbol *msymbol;
|
||||
|
||||
i = lookup_misc_func ("main");
|
||||
if (i >= 0 && misc_function_vector[i].address != 0)
|
||||
msymbol = lookup_minimal_symbol ("main", symfile_objfile);
|
||||
if ((msymbol != NULL) && (msymbol -> address != 0))
|
||||
{
|
||||
breakpoint_addr = misc_function_vector[i].address;
|
||||
breakpoint_addr = msymbol -> address;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1102,19 +1161,64 @@ solib_create_inferior_hook()
|
||||
|
||||
/*
|
||||
|
||||
GLOBAL FUNCTION
|
||||
LOCAL FUNCTION
|
||||
|
||||
special_symbol_handling -- additional shared library symbol handling
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
void special_symbol_handling (struct so_list *so)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Once the symbols from a shared object have been loaded in the usual
|
||||
way, we are called to do any system specific symbol handling that
|
||||
is needed.
|
||||
|
||||
For Suns, this consists of grunging around in the dynamic linkers
|
||||
structures to find symbol definitions for "common" symbols and
|
||||
adding them to the minimal symbol table for the corresponding
|
||||
objfile.
|
||||
|
||||
*/
|
||||
|
||||
static void
|
||||
special_symbol_handling (so)
|
||||
struct so_list *so;
|
||||
{
|
||||
#ifndef SVR4_SHARED_LIBS
|
||||
|
||||
/* Read the debugger structure from the inferior, just to make sure
|
||||
we have a current copy. */
|
||||
|
||||
read_memory (debug_addr, (char *) &debug_copy, sizeof (debug_copy));
|
||||
|
||||
/* Get common symbol definitions for the loaded object. */
|
||||
|
||||
if (debug_copy.ldd_cp)
|
||||
{
|
||||
solib_add_common_symbols (debug_copy.ldd_cp, so -> objfile);
|
||||
}
|
||||
|
||||
#endif /* !SVR4_SHARED_LIBS */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
LOCAL FUNCTION
|
||||
|
||||
sharedlibrary_command -- handle command to explicitly add library
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
void sharedlibrary_command (char *args, int from_tty)
|
||||
static void sharedlibrary_command (char *args, int from_tty)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
*/
|
||||
|
||||
void
|
||||
static void
|
||||
sharedlibrary_command (args, from_tty)
|
||||
char *args;
|
||||
int from_tty;
|
||||
|
||||
Reference in New Issue
Block a user