+ abfd = bfd_fdopenr (filename, gnutarget, desc);
+ if (!abfd)
+ {
+ close (desc);
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't open to read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (!bfd_check_format (abfd, bfd_object)) /* Reads in section info */
+ {
+ bfd_close (abfd); /* This also closes desc */
+ make_cleanup (xfree, filename);
+ error ("\"%s\": can't read symbols: %s.", filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Sum the sizes of the various sections that compose debug info. */
+
+ /* This contains non-DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$DEBUG$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ /* This contains DOC information. */
+ sect = bfd_get_section_by_name (abfd, "$PINFO$");
+ if (sect)
+ st_size += (LONGEST) bfd_section_size (abfd, sect);
+
+ bfd_close (abfd); /* This also closes desc */
+ xfree (filename);
+
+ /* Unfortunately, just summing the sizes of various debug info
+ sections isn't a very accurate measurement of how much heap
+ space the debugger will need to hold them. It also doesn't
+ account for space needed by linker (aka "minimal") symbols.
+
+ Anecdotal evidence suggests that just summing the sizes of
+ debug-info-related sections understates the heap space needed
+ to represent it internally by about an order of magnitude.
+
+ Since it's not exactly brain surgery we're doing here, rather
+ than attempt to more accurately measure the size of a shlib's
+ symbol table in GDB's heap, we'll just apply a 10x fudge-
+ factor to the debug info sections' size-sum. No, this doesn't
+ account for minimal symbols in non-debuggable shlibs. But it
+ all roughly washes out in the end.
+ */
+ return st_size * (LONGEST) 10;
+}
+
+
+static void
+som_solib_add_solib_objfile (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr)
+{
+ obj_private_data_t *obj_private;
+ struct obj_section *s;
+
+ so->objfile = symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
+ so->abfd = so->objfile->obfd;
+
+ /* syms_from_objfile has bizarre section offset code,
+ so I do my own right here. */
+ for (s = so->objfile->sections; s < so->objfile->sections_end; s++)
+ {
+ flagword aflag = bfd_get_section_flags(so->abfd, s->the_bfd_section);
+ if (aflag & SEC_CODE)
+ {
+ s->addr += so->som_solib.text_addr - so->som_solib.text_link_addr;
+ s->endaddr += so->som_solib.text_addr - so->som_solib.text_link_addr;
+ }
+ else if (aflag & SEC_DATA)
+ {
+ s->addr += so->som_solib.data_start;
+ s->endaddr += so->som_solib.data_start;
+ }
+ else
+ ;
+ }
+
+ /* Mark this as a shared library and save private data.
+ */
+ so->objfile->flags |= OBJF_SHARED;
+
+ if (so->objfile->obj_private == NULL)
+ {
+ obj_private = (obj_private_data_t *)
+ obstack_alloc (&so->objfile->objfile_obstack,
+ sizeof (obj_private_data_t));
+ obj_private->unwind_info = NULL;
+ obj_private->so_info = NULL;
+ so->objfile->obj_private = obj_private;
+ }
+
+ obj_private = (obj_private_data_t *) so->objfile->obj_private;
+ obj_private->so_info = so;
+
+ if (!bfd_check_format (so->abfd, bfd_object))
+ {
+ error ("\"%s\": not in executable format: %s.",
+ name, bfd_errmsg (bfd_get_error ()));
+ }
+}
+
+
+static void
+som_solib_load_symbols (struct so_list *so, char *name, int from_tty,
+ CORE_ADDR text_addr, struct target_ops *target)
+{
+ struct section_table *p;
+ int status;
+ char buf[4];
+ CORE_ADDR presumed_data_start;
+
+#ifdef SOLIB_DEBUG
+ printf ("--Adding symbols for shared library \"%s\"\n", name);
+#endif
+
+ som_solib_add_solib_objfile (so, name, from_tty, text_addr);
+
+ /* Now we need to build a section table for this library since
+ we might be debugging a core file from a dynamically linked
+ executable in which the libraries were not privately mapped. */
+ if (build_section_table (so->abfd,
+ &so->sections,
+ &so->sections_end))
+ {
+ error ("Unable to build section table for shared library\n.");
+ return;
+ }
+
+ /* Relocate all the sections based on where they got loaded. */
+ for (p = so->sections; p < so->sections_end; p++)
+ {
+ if (p->the_bfd_section->flags & SEC_CODE)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT (so->objfile));
+ }
+ else if (p->the_bfd_section->flags & SEC_DATA)
+ {
+ p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA (so->objfile));
+ }
+ }