X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsomread.c;h=fcd02bdddfd40de479ed18e3c93385d9044f1bc2;hb=838275403d9c8ef648b889e348500cfc1b9fab40;hp=d9d3e7bb72b4bb57724b099135ebdbf6d4f5e52f;hpb=b2259038ba4e56f7b9e09f4e909596ef2d795b40;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/somread.c b/gdb/somread.c index d9d3e7bb72..fcd02bdddf 100644 --- a/gdb/somread.c +++ b/gdb/somread.c @@ -1,5 +1,5 @@ /* Read HP PA/Risc object files for GDB. - Copyright (C) 1991-2013 Free Software Foundation, Inc. + Copyright (C) 1991-2014 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. This file is part of GDB. @@ -27,7 +27,6 @@ #include "stabsread.h" #include "gdb-stabs.h" #include "complaints.h" -#include "gdb_string.h" #include "demangle.h" #include "som.h" #include "libhppa.h" @@ -46,6 +45,7 @@ static void som_symtab_read (bfd *abfd, struct objfile *objfile, struct section_offsets *section_offsets) { + struct cleanup *cleanup; struct gdbarch *gdbarch = get_objfile_arch (objfile); unsigned int number_of_symbols; int val, dynamic; @@ -53,20 +53,16 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, asection *shlib_info; struct som_external_symbol_dictionary_record *buf, *bufp, *endbufp; char *symname; - CONST int symsize = sizeof (struct som_external_symbol_dictionary_record); - CORE_ADDR text_offset, data_offset; + const int symsize = sizeof (struct som_external_symbol_dictionary_record); - text_offset = ANOFFSET (section_offsets, 0); - data_offset = ANOFFSET (section_offsets, 1); - number_of_symbols = bfd_get_symcount (abfd); /* Allocate a buffer to read in the debug info. We avoid using alloca because the memory size could be so large that we could hit the stack size limit. */ buf = xmalloc (symsize * number_of_symbols); - make_cleanup (xfree, buf); + cleanup = make_cleanup (xfree, buf); bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET); val = bfd_bread (buf, symsize * number_of_symbols, abfd); if (val != symsize * number_of_symbols) @@ -94,7 +90,7 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, more accurate to check for a nonzero text offset, but they have not provided any information about why that test is more accurate. */ - dynamic = (text_offset != 0); + dynamic = (ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile)) != 0); endbufp = buf + number_of_symbols; for (bufp = buf; bufp < endbufp; ++bufp) @@ -106,9 +102,36 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, unsigned int symbol_scope = (flags >> SOM_SYMBOL_SCOPE_SH) & SOM_SYMBOL_SCOPE_MASK; CORE_ADDR symbol_value = bfd_getb32 (bufp->symbol_value); + asection *section = NULL; QUIT; + /* Compute the section. */ + switch (symbol_scope) + { + case SS_EXTERNAL: + if (symbol_type != ST_STORAGE) + section = bfd_und_section_ptr; + else + section = bfd_com_section_ptr; + break; + + case SS_UNSAT: + if (symbol_type != ST_STORAGE) + section = bfd_und_section_ptr; + else + section = bfd_com_section_ptr; + break; + + case SS_UNIVERSAL: + section = bfd_section_from_som_symbol (abfd, bufp); + break; + + case SS_LOCAL: + section = bfd_section_from_som_symbol (abfd, bufp); + break; + } + switch (symbol_scope) { case SS_UNIVERSAL: @@ -125,7 +148,6 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, case ST_MILLICODE: symname = bfd_getb32 (bufp->name) + stringtab; ms_type = mst_text; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; @@ -138,20 +160,17 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, ms_type = mst_solib_trampoline; else ms_type = mst_text; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; case ST_STUB: symname = bfd_getb32 (bufp->name) + stringtab; ms_type = mst_solib_trampoline; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; case ST_DATA: symname = bfd_getb32 (bufp->name) + stringtab; - symbol_value += data_offset; ms_type = mst_data; break; default: @@ -173,7 +192,6 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, case ST_CODE: symname = bfd_getb32 (bufp->name) + stringtab; ms_type = mst_file_text; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); check_strange_names: @@ -204,7 +222,6 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, case ST_MILLICODE: symname = bfd_getb32 (bufp->name) + stringtab; ms_type = mst_file_text; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; @@ -215,21 +232,18 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, using mst_file_text vs mst_solib_trampoline here like we do for SS_UNIVERSAL and SS_EXTERNAL symbols above. */ ms_type = mst_file_text; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; case ST_STUB: symname = bfd_getb32 (bufp->name) + stringtab; ms_type = mst_solib_trampoline; - symbol_value += text_offset; symbol_value = gdbarch_addr_bits_remove (gdbarch, symbol_value); break; case ST_DATA: symname = bfd_getb32 (bufp->name) + stringtab; - symbol_value += data_offset; ms_type = mst_file_data; goto check_strange_names; @@ -250,7 +264,6 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, case ST_STORAGE: case ST_DATA: symname = bfd_getb32 (bufp->name) + stringtab; - symbol_value += data_offset; ms_type = mst_data; break; @@ -267,8 +280,36 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, error (_("Invalid symbol data; bad HP string table offset: %s"), plongest (bfd_getb32 (bufp->name))); - prim_record_minimal_symbol (symname, symbol_value, ms_type, objfile); + if (bfd_is_const_section (section)) + { + struct obj_section *iter; + + ALL_OBJFILE_OSECTIONS (objfile, iter) + { + CORE_ADDR start; + CORE_ADDR len; + + if (bfd_is_const_section (iter->the_bfd_section)) + continue; + + start = bfd_get_section_vma (iter->objfile->obfd, + iter->the_bfd_section); + len = bfd_get_section_size (iter->the_bfd_section); + if (start <= symbol_value && symbol_value < start + len) + { + section = iter->the_bfd_section; + break; + } + } + } + + prim_record_minimal_symbol_and_info (symname, symbol_value, ms_type, + gdb_bfd_section_index (objfile->obfd, + section), + objfile); } + + do_cleanups (cleanup); } /* Scan and build partial symbols for a symbol file. @@ -287,7 +328,7 @@ som_symtab_read (bfd *abfd, struct objfile *objfile, for real. We look for sections with specific names, to tell us what debug - format to look for: FIXME!!! + format to look for. somstab_build_psymtabs() handles STABS symbols. @@ -361,31 +402,105 @@ som_symfile_init (struct objfile *objfile) objfile->flags |= OBJF_REORDERED; } +/* An object of this type is passed to find_section_offset. */ + +struct find_section_offset_arg +{ + /* The objfile. */ + + struct objfile *objfile; + + /* Flags to invert. */ + + flagword invert; + + /* Flags to look for. */ + + flagword flags; + + /* A text section with non-zero size, if any. */ + + asection *best_section; + + /* An empty text section, if any. */ + + asection *empty_section; +}; + +/* A callback for bfd_map_over_sections that tries to find a section + with particular flags in an objfile. */ + +static void +find_section_offset (bfd *abfd, asection *sect, void *arg) +{ + struct find_section_offset_arg *info = arg; + flagword aflag; + + aflag = bfd_get_section_flags (abfd, sect); + + aflag ^= info->invert; + + if ((aflag & info->flags) == info->flags) + { + if (bfd_section_size (abfd, sect) > 0) + { + if (info->best_section == NULL) + info->best_section = sect; + } + else + { + if (info->empty_section == NULL) + info->empty_section = sect; + } + } +} + +/* Set a section index from a BFD. */ + +static void +set_section_index (struct objfile *objfile, flagword invert, flagword flags, + int *index_ptr) +{ + struct find_section_offset_arg info; + + info.objfile = objfile; + info.best_section = NULL; + info.empty_section = NULL; + info.invert = invert; + info.flags = flags; + bfd_map_over_sections (objfile->obfd, find_section_offset, &info); + + if (info.best_section) + *index_ptr = info.best_section->index; + else if (info.empty_section) + *index_ptr = info.empty_section->index; +} + /* SOM specific parsing routine for section offsets. Plain and simple for now. */ static void -som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) +som_symfile_offsets (struct objfile *objfile, + const struct section_addr_info *addrs) { int i; CORE_ADDR text_addr; + asection *sect; objfile->num_sections = bfd_count_sections (objfile->obfd); objfile->section_offsets = (struct section_offsets *) obstack_alloc (&objfile->objfile_obstack, SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)); - /* FIXME: ezannoni 2000-04-20 The section names in SOM are not - .text, .data, etc, but $TEXT$, $DATA$,... We should initialize - SET_OFF_* from bfd. (See default_symfile_offsets()). But I don't - know the correspondence between SOM sections and GDB's idea of - section names. So for now we default to what is was before these - changes. */ - objfile->sect_index_text = 0; - objfile->sect_index_data = 1; - objfile->sect_index_bss = 2; - objfile->sect_index_rodata = 3; + set_section_index (objfile, 0, SEC_ALLOC | SEC_CODE, + &objfile->sect_index_text); + set_section_index (objfile, 0, SEC_ALLOC | SEC_DATA, + &objfile->sect_index_data); + set_section_index (objfile, SEC_LOAD, SEC_ALLOC | SEC_LOAD, + &objfile->sect_index_bss); + set_section_index (objfile, 0, SEC_ALLOC | SEC_READONLY, + &objfile->sect_index_rodata); /* First see if we're a shared library. If so, get the section offsets from the library, else get them from addrs. */ @@ -394,7 +509,7 @@ som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) /* Note: Here is OK to compare with ".text" because this is the name that gdb itself gives to that section, not the SOM name. */ - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) + for (i = 0; i < addrs->num_sections; i++) if (strcmp (addrs->other[i].name, ".text") == 0) break; text_addr = addrs->other[i].addr; @@ -410,7 +525,6 @@ som_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs) static const struct sym_fns som_sym_fns = { - bfd_target_som_flavour, som_new_init, /* init anything gbl to entire symtab */ som_symfile_init, /* read initial info, setup for sym_read() */ som_symfile_read, /* read a symbol file into symtab */ @@ -429,5 +543,5 @@ initialize_file_ftype _initialize_somread; void _initialize_somread (void) { - add_symtab_fns (&som_sym_fns); + add_symtab_fns (bfd_target_som_flavour, &som_sym_fns); }