* breakpoint.c (do_enable_breakpoint): Use update_watchpoint for
[binutils-gdb.git] / gdb / solib-frv.c
index 5d2c9a12fc057c4b1abd7e93e78b0121512668f2..c770b3e75bf3d9eb22a3df5ef2e1e12ea948d774 100644 (file)
@@ -1,11 +1,11 @@
 /* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
-   Copyright (C) 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -14,9 +14,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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
 #include "defs.h"
@@ -32,6 +30,7 @@
 #include "command.h"
 #include "gdbcmd.h"
 #include "elf/frv.h"
+#include "exceptions.h"
 
 /* Flag which indicates whether internal debug messages should be printed.  */
 static int solib_frv_debug;
@@ -125,6 +124,9 @@ fetch_loadmap (CORE_ADDR ldmaddr)
   nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
                                     sizeof ext_ldmbuf_partial.nsegs);
 
+  if (nsegs <= 0)
+    return NULL;
+
   /* Allocate space for the complete (external) loadmap.  */
   ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
                + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
@@ -361,6 +363,14 @@ lm_base (void)
   CORE_ADDR addr;
   gdb_byte buf[FRV_PTR_SIZE];
 
+  /* One of our assumptions is that the main executable has been relocated.
+     Bail out if this has not happened.  (Note that post_create_inferior()
+     in infcmd.c will call solib_add prior to solib_create_inferior_hook().
+     If we allow this to happen, lm_base_cache will be initialized with
+     a bogus value.  */
+  if (main_executable_lm_info == 0)
+    return 0;
+
   /* If we already have a cached value, return it.  */
   if (lm_base_cache)
     return lm_base_cache;
@@ -639,12 +649,11 @@ enable_break2 (void)
       unsigned int interp_sect_size;
       gdb_byte *buf;
       bfd *tmp_bfd = NULL;
-      int tmp_fd = -1;
-      char *tmp_pathname = NULL;
       int status;
       CORE_ADDR addr, interp_loadmap_addr;
       gdb_byte addr_buf[FRV_PTR_SIZE];
       struct int_elf32_fdpic_loadmap *ldm;
+      volatile struct gdb_exception ex;
 
       /* Read the contents of the .interp section into a local buffer;
          the contents specify the dynamic linker this program uses.  */
@@ -662,26 +671,17 @@ enable_break2 (void)
          be trivial on GNU/Linux).  Therefore, we have to try an alternate
          mechanism to find the dynamic linker's base address.  */
 
-      tmp_fd  = solib_open (buf, &tmp_pathname);
-      if (tmp_fd >= 0)
-       tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
-
+      TRY_CATCH (ex, RETURN_MASK_ALL)
+        {
+          tmp_bfd = solib_bfd_open (buf);
+        }
       if (tmp_bfd == NULL)
        {
          enable_break_failure_warning ();
          return 0;
        }
 
-      /* Make sure the dynamic linker is really a useful object.  */
-      if (!bfd_check_format (tmp_bfd, bfd_object))
-       {
-         warning (_("Unable to grok dynamic linker %s as an object file"), buf);
-         enable_break_failure_warning ();
-         bfd_close (tmp_bfd);
-         return 0;
-       }
-
-      status = frv_fdpic_loadmap_addresses (current_gdbarch,
+      status = frv_fdpic_loadmap_addresses (target_gdbarch,
                                             &interp_loadmap_addr, 0);
       if (status < 0)
        {
@@ -863,16 +863,17 @@ static void
 frv_relocate_main_executable (void)
 {
   int status;
-  CORE_ADDR exec_addr;
+  CORE_ADDR exec_addr, interp_addr;
   struct int_elf32_fdpic_loadmap *ldm;
   struct cleanup *old_chain;
   struct section_offsets *new_offsets;
   int changed;
   struct obj_section *osect;
 
-  status = frv_fdpic_loadmap_addresses (current_gdbarch, 0, &exec_addr);
+  status = frv_fdpic_loadmap_addresses (target_gdbarch,
+                                        &interp_addr, &exec_addr);
 
-  if (status < 0)
+  if (status < 0 || (exec_addr == 0 && interp_addr == 0))
     {
       /* Not using FDPIC ABI, so do nothing.  */
       return;
@@ -902,7 +903,7 @@ frv_relocate_main_executable (void)
       osect_idx = osect->the_bfd_section->index;
 
       /* Current address of section.  */
-      addr = osect->addr;
+      addr = obj_section_addr (osect);
       /* Offset from where this section started.  */
       offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
       /* Original address prior to any past relocations.  */
@@ -1266,7 +1267,7 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
   return 0;
 }
 
-static struct target_so_ops frv_so_ops;
+struct target_so_ops frv_so_ops;
 
 void
 _initialize_frv_solib (void)
@@ -1280,9 +1281,6 @@ _initialize_frv_solib (void)
   frv_so_ops.open_symbol_file_object = open_symbol_file_object;
   frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
 
-  /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
-  current_target_so_ops = &frv_so_ops;
-
   /* Debug this file's internals.  */
   add_setshow_zinteger_cmd ("solib-frv", class_maintenance,
                            &solib_frv_debug, _("\