* inftarg.c (child_thread_alive): New function to see if a
[deliverable/binutils-gdb.git] / gdb / somsolib.c
index fc3d2ad15fe118190dc27b9a2db593bbbe738ed5..8b5fc52b232d8b9258205da6fea44359ebd55da9 100644 (file)
@@ -33,11 +33,10 @@ and by Cygnus Support.  */
 #include "symfile.h"
 #include "objfiles.h"
 #include "inferior.h"
+#include "gdb-stabs.h"
 
 /* TODO:
 
-   * Relocate data addresses in the shared library.
-
    * Most of this code should work for hp300 shared libraries.  Does
    anyone care enough to weed out any SOM-isms.
 
@@ -114,7 +113,13 @@ som_solib_add (arg_string, from_tty, target)
   asection *shlib_info;
   int status;
   unsigned int dld_flags;
-  char buf[4];
+  char buf[4], *re_err;
+
+  /* First validate our arguments.  */
+  if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+    {
+      error ("Invalid regexp: %s", re_err);
+    }
 
   /* If we're debugging a core file, or have attached to a running
      process, then som_solib_create_inferior_hook will not have been
@@ -126,6 +131,9 @@ som_solib_add (arg_string, from_tty, target)
      We also need to examine __dld_flags to determine if the shared library
      list is valid and to determine if the libraries have been privately
      mapped.  */
+  if (symfile_objfile == NULL)
+    return;
+
   /* First see if the objfile was dynamically linked.  */
   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
   if (!shlib_info)
@@ -135,7 +143,7 @@ som_solib_add (arg_string, from_tty, target)
   if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
     return;
 
-  msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *) NULL);
+  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
   if (msymbol == NULL)
     {
       error ("Unable to find __dld_flags symbol in object file.\n");
@@ -163,12 +171,12 @@ som_solib_add (arg_string, from_tty, target)
   if ((dld_flags & 1) == 0)
     warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n");
 
-  msymbol = lookup_minimal_symbol ("__dld_list", (struct objfile *) NULL);
+  msymbol = lookup_minimal_symbol ("__dld_list", NULL, NULL);
   if (!msymbol)
     {
       /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
         but the data is still available if you know where to look.  */
-      msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *)NULL);
+      msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
       if (!msymbol)
        {
          error ("Unable to find dynamic library list.\n");
@@ -210,14 +218,7 @@ som_solib_add (arg_string, from_tty, target)
   addr = extract_unsigned_integer (buf, 4);
 
   /* Now that we have a pointer to the dynamic library list, walk
-     through it and add the symbols for each library.
-
-     Skip the first entry since it's our executable.  */
-  status = target_read_memory (addr + 36, buf, 4);
-  if (status != 0)
-    goto err;
-
-  addr = extract_unsigned_integer (buf, 4);
+     through it and add the symbols for each library.  */
 
   so_list_tail = so_list_head;
   /* Find the end of the list of shared objects.  */
@@ -230,6 +231,7 @@ som_solib_add (arg_string, from_tty, target)
       unsigned int name_len;
       char *name;
       struct so_list *new_so;
+      struct so_list *so_list = so_list_head;
       struct section_table *p;
 
       if (addr == 0)
@@ -257,6 +259,25 @@ som_solib_add (arg_string, from_tty, target)
       if (status != 0)
        goto err;
 
+      /* See if we've already loaded something with this name.  */
+      while (so_list)
+       {
+         if (!strcmp (so_list->som_solib.name, name))
+           break;
+         so_list = so_list->next;
+       }
+
+      /* We've already loaded this one or it's the main program, skip it.  */
+      if (so_list || !strcmp (name, symfile_objfile->name))
+       {
+         status = target_read_memory (addr + 36, buf, 4);
+         if (status != 0)
+           goto err;
+
+         addr = (CORE_ADDR) extract_unsigned_integer (buf, 4);
+         continue;
+       }
+
       name = obsavestring (name, name_len - 1,
                           &symfile_objfile->symbol_obstack);
 
@@ -335,8 +356,7 @@ som_solib_add (arg_string, from_tty, target)
       addr = (CORE_ADDR)new_so->som_solib.next;
 
       new_so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0);
-      new_so->abfd = bfd_openr (name, gnutarget);
-      new_so->abfd->cacheable = true;
+      new_so->abfd = new_so->objfile->obfd;
 
       if (!bfd_check_format (new_so->abfd, bfd_object))
        {
@@ -383,30 +403,27 @@ som_solib_add (arg_string, from_tty, target)
       status = target_read_memory (text_addr, buf, 4);
       if (status != 0)
        {
-         int old;
+         int old, new;
 
+         new = new_so->sections_end - new_so->sections;
          /* Add sections from the shared library to the core target.  */
          if (target->to_sections)
            {
              old = target->to_sections_end - target->to_sections;
              target->to_sections = (struct section_table *)
                xrealloc ((char *)target->to_sections,
-                         ((sizeof (struct section_table))
-                           * (old + bfd_count_sections (new_so->abfd))));
+                         ((sizeof (struct section_table)) * (old + new)));
            }
          else
            {
              old = 0;
              target->to_sections = (struct section_table *)
-               xmalloc ((sizeof (struct section_table))
-                        * bfd_count_sections (new_so->abfd));
+               xmalloc ((sizeof (struct section_table)) * new);
            }
-         target->to_sections_end = (target->to_sections
-                               + old + bfd_count_sections (new_so->abfd));
+         target->to_sections_end = (target->to_sections + old + new);
          memcpy ((char *)(target->to_sections + old),
                  new_so->sections,
-                 ((sizeof (struct section_table))
-                  * bfd_count_sections (new_so->abfd)));
+                 ((sizeof (struct section_table)) * new));
        }
     }
 
@@ -454,6 +471,9 @@ som_solib_create_inferior_hook()
   char shadow_contents[BREAKPOINT_MAX], buf[4];
   CORE_ADDR anaddr;
 
+  if (symfile_objfile == NULL)
+    return; 
+
   /* First see if the objfile was dynamically linked.  */
   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
   if (!shlib_info)
@@ -465,7 +485,7 @@ som_solib_create_inferior_hook()
 
   /* Get the address of __dld_flags, if no such symbol exists, then we can
      not debug the shared code.  */
-  msymbol = lookup_minimal_symbol ("__dld_flags", (struct objfile *) NULL);
+  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
   if (msymbol == NULL)
     {
       error ("Unable to find __dld_flags symbol in object file.\n");
@@ -493,7 +513,7 @@ som_solib_create_inferior_hook()
     }
 
   /* Now find the address of _start and set a breakpoint there.  */
-  msymbol = lookup_minimal_symbol ("_start", symfile_objfile);
+  msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
   if (msymbol == NULL)
     {
       error ("Unable to find _start symbol in object file.\n");
@@ -565,6 +585,50 @@ som_solib_get_got_by_pc (addr)
   return got_value;
 }
 
+int
+som_solib_section_offsets (objfile, offsets)
+     struct objfile *objfile;
+     struct section_offsets *offsets;
+{
+  struct so_list *so_list = so_list_head;
+
+  while (so_list)
+    {
+      /* Oh what a pain!  We need the offsets before so_list->objfile
+        is valid.  The BFDs will never match.  Make a best guess.  */
+      if (strstr (objfile->name, so_list->som_solib.name))
+       {
+         asection *private_section;
+
+         /* The text offset is easy.  */
+         ANOFFSET (offsets, SECT_OFF_TEXT)
+           = (so_list->som_solib.text_addr
+              - so_list->som_solib.text_link_addr);
+         ANOFFSET (offsets, SECT_OFF_RODATA)
+           = ANOFFSET (offsets, SECT_OFF_TEXT);
+
+         /* We should look at presumed_dp in the SOM header, but
+            that's not easily available.  This should be OK though.  */
+         private_section = bfd_get_section_by_name (objfile->obfd,
+                                                    "$PRIVATE$");
+         if (!private_section)
+           {
+             warning ("Unable to find $PRIVATE$ in shared library!");
+             ANOFFSET (offsets, SECT_OFF_DATA) = 0;
+             ANOFFSET (offsets, SECT_OFF_BSS) = 0;
+             return 1;
+           }
+         ANOFFSET (offsets, SECT_OFF_DATA)
+           = (so_list->som_solib.data_start - private_section->vma);
+         ANOFFSET (offsets, SECT_OFF_BSS)
+           = ANOFFSET (offsets, SECT_OFF_DATA);
+         return 1;
+       }
+      so_list = so_list->next;
+    }
+  return 0;
+}
+
 /* Dump information about all the currently loaded shared libraries.  */
 
 static void
@@ -612,9 +676,20 @@ som_sharedlibrary_info_command (ignore, from_tty)
     }
 }
 
+static void
+som_solib_sharedlibrary_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  dont_repeat ();
+  som_solib_add (args, from_tty, (struct target_ops *) 0);
+}
+
 void
 _initialize_som_solib ()
 {
+  add_com ("sharedlibrary", class_files, som_solib_sharedlibrary_command,
+           "Load shared object library symbols for files matching REGEXP.");
   add_info ("sharedlibrary", som_sharedlibrary_info_command,
            "Status of loaded shared object libraries.");
 }
This page took 0.027132 seconds and 4 git commands to generate.