X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fobjfiles.c;h=f24bf59c879457bbbdd556ed2bdb0cadf51f0463;hb=f109cc3d9ef5ddcbd26afa98207b3eebaea9463f;hp=4f0dfd6d93922ff1ba9058bdff0e3a3b6b1d0910;hpb=72bba93b85e2e8c887df447c4237d0e7c21d07d8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 4f0dfd6d93..f24bf59c87 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1,5 +1,5 @@ /* GDB routines for manipulating objfiles. - Copyright 1992 Free Software Foundation, Inc. + Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -16,7 +16,7 @@ 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This file contains support routines for creating, manipulating, and destroying objfile structures. */ @@ -30,9 +30,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "target.h" #include -#include +#include "gdb_stat.h" #include -#include +#include "obstack.h" +#include "gdb_string.h" /* Prototypes for local functions */ @@ -44,14 +45,13 @@ open_existing_mapped_file PARAMS ((char *, long, int)); static int open_mapped_file PARAMS ((char *filename, long mtime, int mapped)); -static CORE_ADDR -map_to_address PARAMS ((void)); +static PTR +map_to_file PARAMS ((int)); #endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */ -/* Message to be printed before the error message, when an error occurs. */ - -extern char *error_pre_print; +static void +add_to_objfile_sections PARAMS ((bfd *, sec_ptr, PTR)); /* Externally visible variables that are owned by this module. See declarations in objfile.h for more info. */ @@ -59,6 +59,7 @@ extern char *error_pre_print; struct objfile *object_files; /* Linked list of all objfiles */ struct objfile *current_objfile; /* For symbol file being read in */ struct objfile *symfile_objfile; /* Main symbol table loaded from */ +struct objfile *rt_common_objfile; /* For runtime common symbols */ int mapped_symbol_files; /* Try to use mapped symbol files */ @@ -84,9 +85,10 @@ add_to_objfile_sections (abfd, asect, objfile_p_char) section.offset = 0; section.objfile = objfile; section.the_bfd_section = asect; + section.ovly_mapped = 0; section.addr = bfd_section_vma (abfd, asect); section.endaddr = section.addr + bfd_section_size (abfd, asect); - obstack_grow (&objfile->psymbol_obstack, §ion, sizeof(section)); + obstack_grow (&objfile->psymbol_obstack, (char *) §ion, sizeof(section)); objfile->sections_end = (struct obj_section *) (((unsigned long) objfile->sections_end) + 1); } @@ -123,10 +125,12 @@ allocate_objfile (abfd, mapped) int mapped; { struct objfile *objfile = NULL; + struct objfile *last_one = NULL; mapped |= mapped_symbol_files; #if !defined(NO_MMALLOC) && defined(HAVE_MMAP) + if (abfd != NULL) { /* If we can support mapped symbol files, try to open/reopen the @@ -145,11 +149,9 @@ allocate_objfile (abfd, mapped) mapped); if (fd >= 0) { - CORE_ADDR mapto; PTR md; - if (((mapto = map_to_address ()) == 0) || - ((md = mmalloc_attach (fd, (PTR) mapto)) == NULL)) + if ((md = map_to_file (fd)) == NULL) { close (fd); } @@ -160,6 +162,8 @@ allocate_objfile (abfd, mapped) objfile -> md = md; objfile -> mmfd = fd; /* Update pointers to functions to *our* copies */ + obstack_chunkfun (&objfile -> psymbol_cache.cache, xmmalloc); + obstack_freefun (&objfile -> psymbol_cache.cache, mfree); obstack_chunkfun (&objfile -> psymbol_obstack, xmmalloc); obstack_freefun (&objfile -> psymbol_obstack, mfree); obstack_chunkfun (&objfile -> symbol_obstack, xmmalloc); @@ -187,6 +191,9 @@ allocate_objfile (abfd, mapped) objfile -> mmfd = fd; objfile -> flags |= OBJF_MAPPED; mmalloc_setkey (objfile -> md, 0, objfile); + obstack_specify_allocation_with_arg (&objfile -> psymbol_cache.cache, + 0, 0, xmmalloc, mfree, + objfile -> md); obstack_specify_allocation_with_arg (&objfile -> psymbol_obstack, 0, 0, xmmalloc, mfree, objfile -> md); @@ -209,7 +216,7 @@ allocate_objfile (abfd, mapped) if (mapped) { - warning ("this version of gdb does not support mapped symbol tables."); + warning ("mapped symbol tables are not supported on this machine; missing or broken mmap()."); /* Turn off the global flag so we don't try to do mapped symbol tables any more, which shuts up gdb unless the user specifically gives the @@ -229,6 +236,8 @@ allocate_objfile (abfd, mapped) objfile = (struct objfile *) xmalloc (sizeof (struct objfile)); memset (objfile, 0, sizeof (struct objfile)); objfile -> md = NULL; + obstack_specify_allocation (&objfile -> psymbol_cache.cache, 0, 0, + xmalloc, free); obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, xmalloc, free); obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, xmalloc, @@ -246,25 +255,56 @@ allocate_objfile (abfd, mapped) { mfree (objfile -> md, objfile -> name); } - objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd)); - objfile -> mtime = bfd_get_mtime (abfd); + if (abfd != NULL) + { + objfile -> name = mstrsave (objfile -> md, bfd_get_filename (abfd)); + objfile -> mtime = bfd_get_mtime (abfd); - /* Build section table. */ + /* Build section table. */ - if (build_objfile_section_table (objfile)) - { - error ("Can't find the file sections in `%s': %s", - objfile -> name, bfd_errmsg (bfd_get_error ())); + if (build_objfile_section_table (objfile)) + { + error ("Can't find the file sections in `%s': %s", + objfile -> name, bfd_errmsg (bfd_get_error ())); + } } - /* Push this file onto the head of the linked list of other such files. */ - - objfile -> next = object_files; - object_files = objfile; + /* Add this file onto the tail of the linked list of other such files. */ + objfile -> next = NULL; + if (object_files == NULL) + object_files = objfile; + else + { + for (last_one = object_files; + last_one -> next; + last_one = last_one -> next); + last_one -> next = objfile; + } return (objfile); } +/* Put OBJFILE at the front of the list. */ + +void +objfile_to_front (objfile) + struct objfile *objfile; +{ + struct objfile **objp; + for (objp = &object_files; *objp != NULL; objp = &((*objp)->next)) + { + if (*objp == objfile) + { + /* Unhook it from where it is. */ + *objp = objfile->next; + /* Put it in the front. */ + objfile->next = object_files; + object_files = objfile; + break; + } + } +} + /* Unlink OBJFILE from the list of known objfiles, if it is found in the list. @@ -333,7 +373,9 @@ free_objfile (objfile) if (objfile -> obfd != NULL) { char *name = bfd_get_filename (objfile->obfd); - bfd_close (objfile -> obfd); + if (!bfd_close (objfile -> obfd)) + warning ("cannot close \"%s\": %s", + name, bfd_errmsg (bfd_get_error ())); free (name); } @@ -341,6 +383,12 @@ free_objfile (objfile) unlink_objfile (objfile); + /* If we are going to free the runtime common objfile, mark it + as unallocated. */ + + if (objfile == rt_common_objfile) + rt_common_objfile = NULL; + /* Before the symbol table code was redone to make it easier to selectively load and remove information particular to a specific linkage unit, gdb used to do these things whenever the monolithic @@ -398,6 +446,7 @@ free_objfile (objfile) if (objfile->static_psymbols.list) mfree (objfile->md, objfile->static_psymbols.list); /* Free the obstacks for non-reusable objfiles */ + obstack_free (&objfile -> psymbol_cache.cache, 0); obstack_free (&objfile -> psymbol_obstack, 0); obstack_free (&objfile -> symbol_obstack, 0); obstack_free (&objfile -> type_obstack, 0); @@ -428,9 +477,9 @@ objfile_relocate (objfile, new_offsets) struct objfile *objfile; struct section_offsets *new_offsets; { - struct section_offsets *delta = (struct section_offsets *) alloca - (sizeof (struct section_offsets) - + objfile->num_sections * sizeof (delta->offsets)); + struct section_offsets *delta = (struct section_offsets *) + alloca (sizeof (struct section_offsets) + + objfile->num_sections * sizeof (delta->offsets)); { int i; @@ -476,7 +525,7 @@ objfile_relocate (objfile, new_offsets) b = BLOCKVECTOR_BLOCK (bv, i); BLOCK_START (b) += ANOFFSET (delta, s->block_line_section); - BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); + BLOCK_END (b) += ANOFFSET (delta, s->block_line_section); for (j = 0; j < BLOCK_NSYMS (b); ++j) { @@ -489,7 +538,7 @@ objfile_relocate (objfile, new_offsets) || SYMBOL_CLASS (sym) == LOC_STATIC) && SYMBOL_SECTION (sym) >= 0) { - SYMBOL_VALUE_ADDRESS (sym) += + SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym)); } #ifdef MIPS_EFI_SYMBOL_NAME @@ -499,7 +548,8 @@ objfile_relocate (objfile, new_offsets) if (SYMBOL_CLASS (sym) == LOC_CONST && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE && STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0) - ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section)); + ecoff_relocate_efi (sym, ANOFFSET (delta, + s->block_line_section)); #endif } } @@ -511,28 +561,26 @@ objfile_relocate (objfile, new_offsets) ALL_OBJFILE_PSYMTABS (objfile, p) { - /* FIXME: specific to symbol readers which use gdb-stabs.h. - We can only get away with it since objfile_relocate is only - used on XCOFF, which lacks psymtabs, and for gdb-stabs.h - targets. */ p->textlow += ANOFFSET (delta, SECT_OFF_TEXT); p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT); } } { - struct partial_symbol *psym; + struct partial_symbol **psym; for (psym = objfile->global_psymbols.list; psym < objfile->global_psymbols.next; psym++) - if (SYMBOL_SECTION (psym) >= 0) - SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym)); + if (SYMBOL_SECTION (*psym) >= 0) + SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, + SYMBOL_SECTION (*psym)); for (psym = objfile->static_psymbols.list; psym < objfile->static_psymbols.next; psym++) - if (SYMBOL_SECTION (psym) >= 0) - SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym)); + if (SYMBOL_SECTION (*psym) >= 0) + SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, + SYMBOL_SECTION (*psym)); } { @@ -541,6 +589,9 @@ objfile_relocate (objfile, new_offsets) if (SYMBOL_SECTION (msym) >= 0) SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym)); } + /* Relocating different sections by different amounts may cause the symbols + to be out of order. */ + msymbols_sort (objfile); { int i; @@ -552,10 +603,10 @@ objfile_relocate (objfile, new_offsets) struct obj_section *s; bfd *abfd; - abfd = symfile_objfile->obfd; + abfd = objfile->obfd; - for (s = symfile_objfile->sections; - s < symfile_objfile->sections_end; ++s) + for (s = objfile->sections; + s < objfile->sections_end; ++s) { flagword flags; @@ -563,21 +614,45 @@ objfile_relocate (objfile, new_offsets) if (flags & SEC_CODE) { - s->addr += ANOFFSET (delta, SECT_OFF_TEXT); + s->addr += ANOFFSET (delta, SECT_OFF_TEXT); s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT); } else if (flags & (SEC_DATA | SEC_LOAD)) { - s->addr += ANOFFSET (delta, SECT_OFF_DATA); + s->addr += ANOFFSET (delta, SECT_OFF_DATA); s->endaddr += ANOFFSET (delta, SECT_OFF_DATA); } else if (flags & SEC_ALLOC) { - s->addr += ANOFFSET (delta, SECT_OFF_BSS); + s->addr += ANOFFSET (delta, SECT_OFF_BSS); s->endaddr += ANOFFSET (delta, SECT_OFF_BSS); } } } + + if (objfile->ei.entry_point != ~(CORE_ADDR)0) + objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT); + + if (objfile->ei.entry_func_lowpc != INVALID_ENTRY_LOWPC) + { + objfile->ei.entry_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.entry_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT); + } + + if (objfile->ei.entry_file_lowpc != INVALID_ENTRY_LOWPC) + { + objfile->ei.entry_file_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.entry_file_highpc += ANOFFSET (delta, SECT_OFF_TEXT); + } + + if (objfile->ei.main_func_lowpc != INVALID_ENTRY_LOWPC) + { + objfile->ei.main_func_lowpc += ANOFFSET (delta, SECT_OFF_TEXT); + objfile->ei.main_func_highpc += ANOFFSET (delta, SECT_OFF_TEXT); + } + + /* Relocate breakpoints as necessary, after things are relocated. */ + breakpoint_re_set (); } /* Many places in gdb want to test just to see if we have any partial @@ -761,67 +836,101 @@ open_mapped_file (filename, mtime, mapped) return (fd); } -/* Return the base address at which we would like the next objfile's - mapped data to start. - - For now, we use the kludge that the configuration specifies a base - address to which it is safe to map the first mmalloc heap, and an - increment to add to this address for each successive heap. There are - a lot of issues to deal with here to make this work reasonably, including: - - Avoid memory collisions with existing mapped address spaces - - Reclaim address spaces when their mmalloc heaps are unmapped - - When mmalloc heaps are shared between processes they have to be - mapped at the same addresses in each - - Once created, a mmalloc heap that is to be mapped back in must be - mapped at the original address. I.E. each objfile will expect to - be remapped at it's original address. This becomes a problem if - the desired address is already in use. - - etc, etc, etc. - - */ - - -static CORE_ADDR -map_to_address () +static PTR +map_to_file (fd) + int fd; { + PTR md; + CORE_ADDR mapto; -#if defined(MMAP_BASE_ADDRESS) && defined (MMAP_INCREMENT) - - static CORE_ADDR next = MMAP_BASE_ADDRESS; - CORE_ADDR mapto = next; - - next += MMAP_INCREMENT; - return (mapto); - -#else - - return (0); - -#endif - + md = mmalloc_attach (fd, (PTR) 0); + if (md != NULL) + { + mapto = (CORE_ADDR) mmalloc_getkey (md, 1); + md = mmalloc_detach (md); + if (md != NULL) + { + /* FIXME: should figure out why detach failed */ + md = NULL; + } + else if (mapto != (CORE_ADDR) NULL) + { + /* This mapping file needs to be remapped at "mapto" */ + md = mmalloc_attach (fd, (PTR) mapto); + } + else + { + /* This is a freshly created mapping file. */ + mapto = (CORE_ADDR) mmalloc_findbase (20 * 1024 * 1024); + if (mapto != 0) + { + /* To avoid reusing the freshly created mapping file, at the + address selected by mmap, we must truncate it before trying + to do an attach at the address we want. */ + ftruncate (fd, 0); + md = mmalloc_attach (fd, (PTR) mapto); + if (md != NULL) + { + mmalloc_setkey (md, 1, (PTR) mapto); + } + } + } + } + return (md); } #endif /* !defined(NO_MMALLOC) && defined(HAVE_MMAP) */ -/* Returns a section whose range includes PC or NULL if none found. */ +/* Returns a section whose range includes PC and SECTION, + or NULL if none found. Note the distinction between the return type, + struct obj_section (which is defined in gdb), and the input type + struct sec (which is a bfd-defined data type). The obj_section + contains a pointer to the bfd struct sec section. */ struct obj_section * -find_pc_section(pc) +find_pc_sect_section (pc, section) CORE_ADDR pc; + struct sec *section; { struct obj_section *s; struct objfile *objfile; ALL_OBJFILES (objfile) for (s = objfile->sections; s < objfile->sections_end; ++s) - if (s->addr <= pc - && pc < s->endaddr) + if ((section == 0 || section == s->the_bfd_section) && + s->addr <= pc && pc < s->endaddr) return(s); return(NULL); } + +/* Returns a section whose range includes PC or NULL if none found. + Backward compatibility, no section. */ + +struct obj_section * +find_pc_section(pc) + CORE_ADDR pc; +{ + return find_pc_sect_section (pc, find_pc_mapped_section (pc)); +} + + +/* In SVR4, we recognize a trampoline by it's section name. + That is, if the pc is in a section named ".plt" then we are in + a trampoline. */ + +int +in_plt_section(pc, name) + CORE_ADDR pc; + char *name; +{ + struct obj_section *s; + int retval = 0; + + s = find_pc_section(pc); + + retval = (s != NULL + && s->the_bfd_section->name != NULL + && STREQ (s->the_bfd_section->name, ".plt")); + return(retval); +}