From 54d478cdbad17a305f2684184a9999cc137ce529 Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Sun, 11 Sep 1994 11:43:40 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 13 ++- gdb/irix5-nat.c | 4 +- gdb/mdebugread.c | 23 +++-- gdb/osfsolib.c | 4 +- gdb/solib.c | 214 ++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 234 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 775a08240c3..e0d56eaaf14 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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. diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c index 2831b9c61bb..38cc0949ab9 100644 --- a/gdb/irix5-nat.c +++ b/gdb/irix5-nat.c @@ -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 (); } diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 8c314571bf9..5d1325d68d8 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -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 = ""; diff --git a/gdb/osfsolib.c b/gdb/osfsolib.c index 6232ea1b791..e42dec32a05 100644 --- a/gdb/osfsolib.c +++ b/gdb/osfsolib.c @@ -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 (); } diff --git a/gdb/solib.c b/gdb/solib.c index a328c3110d3..f42f24eae99 100644 --- a/gdb/solib.c +++ b/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 -- 2.39.5