* irix5-nat.c, osfsolib.c, solib.c (solib_add): Simplify last
change by replacing `symbols_added' with `so_last'. * mdebugread.c (parse_external, parse_partial_symbols): Ignore global common symbols, they will be resolved by the runtime loader. * mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref): Handle scSCommon like scCommon symbols.
This commit is contained in:
parent
dd37f21531
commit
54d478cdba
5 changed files with 234 additions and 24 deletions
|
@ -1,3 +1,12 @@
|
|||
Sun Sep 11 04:36:47 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||
|
||||
* irix5-nat.c, osfsolib.c, solib.c (solib_add): Simplify last
|
||||
change by replacing `symbols_added' with `so_last'.
|
||||
* mdebugread.c (parse_external, parse_partial_symbols): Ignore
|
||||
global common symbols, they will be resolved by the runtime loader.
|
||||
* mdebugread.c (parse_symbol, parse_partial_symbols, cross_ref):
|
||||
Handle scSCommon like scCommon symbols.
|
||||
|
||||
Sat Sep 10 01:43:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
|
||||
|
||||
* corelow.c (add_solib_stub): Copy to_sections changes from
|
||||
|
@ -24,8 +33,8 @@ Thu Sep 8 17:14:43 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
|||
(read_frame): Don't print bad checksum information unless
|
||||
remote_debugging. Don't use repeat count unless it's > 0.
|
||||
* remote-e7000.c (expect): When echoing, ignore multiple newlines.
|
||||
(e7000_insert_breakpoint, e7000_remove_breakpoint, target_ops): Optionally
|
||||
cope with BC style breakpoints.
|
||||
(e7000_insert_breakpoint, e7000_remove_breakpoint, target_ops):
|
||||
Optionally cope with BC style breakpoints.
|
||||
(e7000_command): After command send directly to the E7000 mark
|
||||
registers as changed.
|
||||
(why_stop, e7000_wait: Understand BC style stop condition.
|
||||
|
|
|
@ -607,7 +607,6 @@ solib_add (arg_string, from_tty, target)
|
|||
char *re_err;
|
||||
int count;
|
||||
int old;
|
||||
int symbols_added = 0;
|
||||
|
||||
if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
|
||||
{
|
||||
|
@ -682,14 +681,13 @@ solib_add (arg_string, from_tty, target)
|
|||
{
|
||||
so_last = so;
|
||||
so -> symbols_loaded = 1;
|
||||
symbols_added = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Getting new symbols may change our opinion about what is
|
||||
frameless. */
|
||||
if (symbols_added)
|
||||
if (so_last)
|
||||
reinit_frame_cache ();
|
||||
}
|
||||
|
||||
|
|
|
@ -716,7 +716,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
|
|||
class = LOC_STATIC;
|
||||
b = top_stack->cur_block;
|
||||
s = new_symbol (name);
|
||||
if (sh->sc == scCommon)
|
||||
if (sh->sc == scCommon || sh->sc == scSCommon)
|
||||
{
|
||||
/* It is a FORTRAN common block. At least for SGI Fortran the
|
||||
address is not in the symbol; we need to fix it later in
|
||||
|
@ -886,7 +886,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
|
|||
goto structured_common;
|
||||
|
||||
case stBlock: /* Either a lexical block, or some type */
|
||||
if (sh->sc != scInfo && sh->sc != scCommon)
|
||||
if (sh->sc != scInfo && sh->sc != scCommon && sh->sc != scSCommon)
|
||||
goto case_stBlock_code; /* Lexical block */
|
||||
|
||||
type_code = TYPE_CODE_UNDEF; /* We have a type. */
|
||||
|
@ -1140,7 +1140,7 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
|
|||
break;
|
||||
|
||||
case stEnd: /* end (of anything) */
|
||||
if (sh->sc == scInfo || sh->sc == scCommon)
|
||||
if (sh->sc == scInfo || sh->sc == scCommon || sh->sc == scSCommon)
|
||||
{
|
||||
/* Finished with type */
|
||||
top_stack->cur_type = 0;
|
||||
|
@ -1962,6 +1962,11 @@ parse_external (es, bigend, section_offsets)
|
|||
break;
|
||||
case stGlobal:
|
||||
case stLabel:
|
||||
/* Global common symbols are resolved by the runtime loader,
|
||||
ignore them. */
|
||||
if (es->asym.sc == scCommon || es->asym.sc == scSCommon)
|
||||
break;
|
||||
|
||||
/* Note that the case of a symbol with indexNil must be handled
|
||||
anyways by parse_symbol(). */
|
||||
parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets);
|
||||
|
@ -2226,7 +2231,7 @@ parse_partial_symbols (objfile, section_offsets)
|
|||
svalue += ANOFFSET (section_offsets, SECT_OFF_TEXT);
|
||||
break;
|
||||
case stGlobal:
|
||||
if (ext_in->asym.sc == scCommon)
|
||||
if (ext_in->asym.sc == scCommon || ext_in->asym.sc == scSCommon)
|
||||
{
|
||||
/* The value of a common symbol is its size, not its address.
|
||||
Ignore it. */
|
||||
|
@ -2648,7 +2653,8 @@ parse_partial_symbols (objfile, section_offsets)
|
|||
case stBlock: /* { }, str, un, enum*/
|
||||
/* Do not create a partial symbol for cc unnamed aggregates
|
||||
and gcc empty aggregates. */
|
||||
if ((sh.sc == scInfo || sh.sc == scCommon)
|
||||
if ((sh.sc == scInfo
|
||||
|| sh.sc == scCommon || sh.sc == scSCommon)
|
||||
&& sh.iss != 0
|
||||
&& sh.index != cur_sdx + 2)
|
||||
{
|
||||
|
@ -2758,6 +2764,11 @@ parse_partial_symbols (objfile, section_offsets)
|
|||
debug_info->ssext + psh->iss);
|
||||
/* Fall through, pretend it's global. */
|
||||
case stGlobal:
|
||||
/* Global common symbols are resolved by the runtime loader,
|
||||
ignore them. */
|
||||
if (psh->sc == scCommon || psh->sc == scSCommon)
|
||||
continue;
|
||||
|
||||
class = LOC_STATIC;
|
||||
break;
|
||||
}
|
||||
|
@ -3392,7 +3403,7 @@ cross_ref (fd, ax, tpp, type_code, pname, bigend, sym_name)
|
|||
|| (sh.st != stBlock && sh.st != stTypedef && sh.st != stIndirect
|
||||
&& sh.st != stStruct && sh.st != stUnion
|
||||
&& sh.st != stEnum))
|
||||
&& (sh.sc != scCommon || sh.st != stBlock))
|
||||
&& (sh.st != stBlock || (sh.sc != scCommon && sh.sc != scSCommon)))
|
||||
{
|
||||
/* File indirect entry is corrupt. */
|
||||
*pname = "<illegal>";
|
||||
|
|
|
@ -473,7 +473,6 @@ solib_add (arg_string, from_tty, target)
|
|||
char *re_err;
|
||||
int count;
|
||||
int old;
|
||||
int symbols_added = 0;
|
||||
|
||||
if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
|
||||
{
|
||||
|
@ -550,14 +549,13 @@ solib_add (arg_string, from_tty, target)
|
|||
{
|
||||
so_last = so;
|
||||
so -> symbols_loaded = 1;
|
||||
symbols_added = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Getting new symbols may change our opinion about what is
|
||||
frameless. */
|
||||
if (symbols_added)
|
||||
if (so_last)
|
||||
reinit_frame_cache ();
|
||||
}
|
||||
|
||||
|
|
214
gdb/solib.c
214
gdb/solib.c
|
@ -357,6 +357,189 @@ solib_add_common_symbols (rtc_symp, objfile)
|
|||
|
||||
#ifdef SVR4_SHARED_LIBS
|
||||
|
||||
#ifdef HANDLE_SVR4_EXEC_EMULATORS
|
||||
|
||||
/*
|
||||
Solaris BCP (the part of Solaris which allows it to run SunOS4
|
||||
a.out files) throws in another wrinkle. Solaris does not fill
|
||||
in the usual a.out link map structures when running BCP programs,
|
||||
the only way to get at them is via groping around in the dynamic
|
||||
linker.
|
||||
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.
|
||||
|
||||
Note that we can assume nothing about the process state at the time
|
||||
we need to find these structures. We may be stopped on the first
|
||||
instruction 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 char *debug_base_symbols[] = {
|
||||
"r_debug", /* Solaris 2.3 */
|
||||
"_r_debug", /* Solaris 2.1, 2.2 */
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
look_for_base PARAMS ((int, CORE_ADDR));
|
||||
|
||||
static CORE_ADDR
|
||||
bfd_lookup_symbol PARAMS ((bfd *, char *));
|
||||
|
||||
/*
|
||||
|
||||
LOCAL FUNCTION
|
||||
|
||||
bfd_lookup_symbol -- lookup the value for a specific symbol
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname)
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
An expensive way to lookup the value of a single symbol for
|
||||
bfd's that are only temporary anyway. This is used by the
|
||||
shared library support to find the address of the debugger
|
||||
interface structures in the shared library.
|
||||
|
||||
Note that 0 is specifically allowed as an error return (no
|
||||
such symbol).
|
||||
*/
|
||||
|
||||
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 = bfd_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
|
||||
look_for_base (fd, baseaddr)
|
||||
int fd;
|
||||
CORE_ADDR baseaddr;
|
||||
{
|
||||
bfd *interp_bfd;
|
||||
CORE_ADDR address = 0;
|
||||
char **symbolp;
|
||||
|
||||
/* If the fd is -1, then there is no file that corresponds to this
|
||||
mapped memory segment, so skip it. Also, if the fd corresponds
|
||||
to the exec file, skip it as well. */
|
||||
|
||||
if (fd == -1
|
||||
|| (exec_bfd != NULL
|
||||
&& fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd)))
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Try to open whatever random file this fd corresponds to. Note that
|
||||
we have no way currently to find the filename. Don't gripe about
|
||||
any problems we might have, just fail. */
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (address == 0)
|
||||
{
|
||||
bfd_close (interp_bfd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Eureka! We found the symbol. But now we may need to relocate it
|
||||
by the base address. If the symbol's value is less than the base
|
||||
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 /* HANDLE_SVR4_EXEC_EMULATORS */
|
||||
|
||||
/*
|
||||
|
||||
LOCAL FUNCTION
|
||||
|
@ -391,8 +574,6 @@ elf_locate_base ()
|
|||
char *bufend;
|
||||
|
||||
/* Find the start address of the .dynamic section. */
|
||||
if (exec_bfd == NULL || bfd_get_flavour (exec_bfd) != bfd_target_elf_flavour)
|
||||
return 0;
|
||||
dyninfo_sect = bfd_elf_find_section (exec_bfd, ".dynamic");
|
||||
if (dyninfo_sect == NULL)
|
||||
return 0;
|
||||
|
@ -511,11 +692,18 @@ locate_base ()
|
|||
/* 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
|
||||
we have no cached address, try to locate it in the dynamic info
|
||||
section. */
|
||||
section for ELF executables. */
|
||||
|
||||
if (debug_base == 0)
|
||||
{
|
||||
debug_base = elf_locate_base ();
|
||||
if (exec_bfd != NULL
|
||||
&& bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
|
||||
debug_base = elf_locate_base ();
|
||||
#ifdef HANDLE_SVR4_EXEC_EMULATORS
|
||||
/* Try it the hard way for emulated executables. */
|
||||
else if (inferior_pid != 0)
|
||||
proc_iterate_over_mappings (look_for_base);
|
||||
#endif
|
||||
}
|
||||
return (debug_base);
|
||||
|
||||
|
@ -690,9 +878,12 @@ symbol_add_stub (arg)
|
|||
{
|
||||
register struct so_list *so = (struct so_list *) arg; /* catch_errs bogon */
|
||||
|
||||
so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,
|
||||
(unsigned int) so -> textsection -> addr,
|
||||
0, 0, 0);
|
||||
so -> objfile =
|
||||
symbol_file_add (so -> so_name, so -> from_tty,
|
||||
(so->textsection == NULL
|
||||
? 0
|
||||
: (unsigned int) so -> textsection -> addr),
|
||||
0, 0, 0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -732,9 +923,7 @@ solib_add (arg_string, from_tty, target)
|
|||
}
|
||||
|
||||
/* Add the shared library sections to the section table of the
|
||||
specified target, if any. We have to do this before reading the
|
||||
symbol files as symbol_file_add calls reinit_frame_cache and
|
||||
creating a new frame might access memory in the shared library. */
|
||||
specified target, if any. */
|
||||
if (target)
|
||||
{
|
||||
/* Count how many new section_table entries there are. */
|
||||
|
@ -805,6 +994,11 @@ solib_add (arg_string, from_tty, target)
|
|||
}
|
||||
}
|
||||
|
||||
/* Getting new symbols may change our opinion about what is
|
||||
frameless. */
|
||||
if (so_last)
|
||||
reinit_frame_cache ();
|
||||
|
||||
/* Calling this once at the end means that we put all the minimal
|
||||
symbols for commons into the objfile for the last shared library.
|
||||
Since they are in common, this should not be a problem. If we
|
||||
|
|
Loading…
Reference in a new issue