Don't reset CXXFLAGS_FOR_TARGET
[deliverable/binutils-gdb.git] / gdb / solib-svr4.c
index 4c94f9f1b85a30ef6d97c859d652fb73a6ec2997..0cecc2aec7ec8bdd486f1e4dfe0b93ad57360724 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle SVR4 shared libraries for GDB, the GNU Debugger.
 
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbcore.h"
 #include "target.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "regcache.h"
 #include "gdbthread.h"
 #include "observer.h"
 
-#include "gdb_assert.h"
-
 #include "solist.h"
 #include "solib.h"
 #include "solib-svr4.h"
@@ -44,7 +43,6 @@
 #include "elf-bfd.h"
 #include "exec.h"
 #include "auxv.h"
-#include "exceptions.h"
 #include "gdb_bfd.h"
 #include "probe.h"
 
@@ -613,14 +611,14 @@ find_program_interpreter (void)
 }
 
 
-/* Scan for DYNTAG in .dynamic section of ABFD.  If DYNTAG is found 1 is
-   returned and the corresponding PTR is set.  */
+/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD.  If DESIRED_DYNTAG is
+   found, 1 is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
+scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr)
 {
   int arch_size, step, sect_size;
-  long dyn_tag;
+  long current_dyntag;
   CORE_ADDR dyn_ptr, dyn_addr;
   gdb_byte *bufend, *bufstart, *buf;
   Elf32_External_Dyn *x_dynp_32;
@@ -678,18 +676,18 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
     if (arch_size == 32)
       {
        x_dynp_32 = (Elf32_External_Dyn *) buf;
-       dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+       current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
        dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
       }
     else
       {
        x_dynp_64 = (Elf64_External_Dyn *) buf;
-       dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+       current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
        dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
       }
-     if (dyn_tag == DT_NULL)
+     if (current_dyntag == DT_NULL)
        return 0;
-     if (dyn_tag == dyntag)
+     if (current_dyntag == desired_dyntag)
        {
         /* If requested, try to read the runtime value of this .dynamic
            entry.  */
@@ -712,16 +710,16 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
   return 0;
 }
 
-/* Scan for DYNTAG in .dynamic section of the target's main executable,
-   found by consulting the OS auxillary vector.  If DYNTAG is found 1 is
-   returned and the corresponding PTR is set.  */
+/* Scan for DESIRED_DYNTAG in .dynamic section of the target's main executable,
+   found by consulting the OS auxillary vector.  If DESIRED_DYNTAG is found, 1
+   is returned and the corresponding PTR is set.  */
 
 static int
-scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
+scan_dyntag_auxv (const int desired_dyntag, CORE_ADDR *ptr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   int sect_size, arch_size, step;
-  long dyn_tag;
+  long current_dyntag;
   CORE_ADDR dyn_ptr;
   gdb_byte *bufend, *bufstart, *buf;
 
@@ -741,7 +739,7 @@ scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
       {
        Elf32_External_Dyn *dynp = (Elf32_External_Dyn *) buf;
 
-       dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
+       current_dyntag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
                                            4, byte_order);
        dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
                                            4, byte_order);
@@ -750,15 +748,15 @@ scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
       {
        Elf64_External_Dyn *dynp = (Elf64_External_Dyn *) buf;
 
-       dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
+       current_dyntag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
                                            8, byte_order);
        dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
                                            8, byte_order);
       }
-    if (dyn_tag == DT_NULL)
+    if (current_dyntag == DT_NULL)
       break;
 
-    if (dyn_tag == dyntag)
+    if (current_dyntag == desired_dyntag)
       {
        if (ptr)
          *ptr = dyn_ptr;
@@ -876,14 +874,18 @@ solib_svr4_r_map (struct svr4_info *info)
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   CORE_ADDR addr = 0;
-  volatile struct gdb_exception ex;
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
                                         ptr_type);
     }
-  exception_print (gdb_stderr, ex);
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      exception_print (gdb_stderr, ex);
+    }
+  END_CATCH
+
   return addr;
 }
 
@@ -934,7 +936,7 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
 {
   struct svr4_info *info;
   CORE_ADDR ldsomap;
-  struct so_list *new;
+  struct so_list *newobj;
   struct cleanup *old_chain;
   CORE_ADDR name_lm;
 
@@ -949,11 +951,11 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   if (!ldsomap)
     return 0;
 
-  new = XCNEW (struct so_list);
-  old_chain = make_cleanup (xfree, new);
-  new->lm_info = lm_info_read (ldsomap);
-  make_cleanup (xfree, new->lm_info);
-  name_lm = new->lm_info ? new->lm_info->l_name : 0;
+  newobj = XCNEW (struct so_list);
+  old_chain = make_cleanup (xfree, newobj);
+  newobj->lm_info = lm_info_read (ldsomap);
+  make_cleanup (xfree, newobj->lm_info);
+  name_lm = newobj->lm_info ? newobj->lm_info->l_name : 0;
   do_cleanups (old_chain);
 
   return (name_lm >= vaddr && name_lm < vaddr + size);
@@ -1089,17 +1091,17 @@ svr4_copy_library_list (struct so_list *src)
 
   while (src != NULL)
     {
-      struct so_list *new;
+      struct so_list *newobj;
 
-      new = xmalloc (sizeof (struct so_list));
-      memcpy (new, src, sizeof (struct so_list));
+      newobj = xmalloc (sizeof (struct so_list));
+      memcpy (newobj, src, sizeof (struct so_list));
 
-      new->lm_info = xmalloc (sizeof (struct lm_info));
-      memcpy (new->lm_info, src->lm_info, sizeof (struct lm_info));
+      newobj->lm_info = xmalloc (sizeof (struct lm_info));
+      memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info));
 
-      new->next = NULL;
-      *link = new;
-      link = &new->next;
+      newobj->next = NULL;
+      *link = newobj;
+      link = &newobj->next;
 
       src = src->next;
     }
@@ -1210,7 +1212,7 @@ svr4_parse_libraries (const char *document, struct svr4_library_list *list)
 
   memset (list, 0, sizeof (*list));
   list->tailp = &list->head;
-  if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
+  if (gdb_xml_parse_quick (_("target library list"), "library-list-svr4.dtd",
                           svr4_library_list_elements, document, list) == 0)
     {
       /* Parsed successfully, keep the result.  */
@@ -1274,24 +1276,24 @@ static struct so_list *
 svr4_default_sos (void)
 {
   struct svr4_info *info = get_svr4_info ();
-  struct so_list *new;
+  struct so_list *newobj;
 
   if (!info->debug_loader_offset_p)
     return NULL;
 
-  new = XCNEW (struct so_list);
+  newobj = XCNEW (struct so_list);
 
-  new->lm_info = xzalloc (sizeof (struct lm_info));
+  newobj->lm_info = xzalloc (sizeof (struct lm_info));
 
   /* Nothing will ever check the other fields if we set l_addr_p.  */
-  new->lm_info->l_addr = info->debug_loader_offset;
-  new->lm_info->l_addr_p = 1;
+  newobj->lm_info->l_addr = info->debug_loader_offset;
+  newobj->lm_info->l_addr_p = 1;
 
-  strncpy (new->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
-  new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-  strcpy (new->so_original_name, new->so_name);
+  strncpy (newobj->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
+  newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+  strcpy (newobj->so_original_name, newobj->so_name);
 
-  return new;
+  return newobj;
 }
 
 /* Read the whole inferior libraries chain starting at address LM.
@@ -1311,28 +1313,28 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm,
 
   for (; lm != 0; prev_lm = lm, lm = next_lm)
     {
-      struct so_list *new;
+      struct so_list *newobj;
       struct cleanup *old_chain;
       int errcode;
       char *buffer;
 
-      new = XCNEW (struct so_list);
-      old_chain = make_cleanup_free_so (new);
+      newobj = XCNEW (struct so_list);
+      old_chain = make_cleanup_free_so (newobj);
 
-      new->lm_info = lm_info_read (lm);
-      if (new->lm_info == NULL)
+      newobj->lm_info = lm_info_read (lm);
+      if (newobj->lm_info == NULL)
        {
          do_cleanups (old_chain);
          return 0;
        }
 
-      next_lm = new->lm_info->l_next;
+      next_lm = newobj->lm_info->l_next;
 
-      if (new->lm_info->l_prev != prev_lm)
+      if (newobj->lm_info->l_prev != prev_lm)
        {
          warning (_("Corrupted shared library list: %s != %s"),
                   paddress (target_gdbarch (), prev_lm),
-                  paddress (target_gdbarch (), new->lm_info->l_prev));
+                  paddress (target_gdbarch (), newobj->lm_info->l_prev));
          do_cleanups (old_chain);
          return 0;
        }
@@ -1342,18 +1344,18 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm,
          SVR4, it has no name.  For others (Solaris 2.3 for example), it
          does have a name, so we can no longer use a missing name to
          decide when to ignore it.  */
-      if (ignore_first && new->lm_info->l_prev == 0)
+      if (ignore_first && newobj->lm_info->l_prev == 0)
        {
          struct svr4_info *info = get_svr4_info ();
 
-         first_l_name = new->lm_info->l_name;
-         info->main_lm_addr = new->lm_info->lm_addr;
+         first_l_name = newobj->lm_info->l_name;
+         info->main_lm_addr = newobj->lm_info->lm_addr;
          do_cleanups (old_chain);
          continue;
        }
 
       /* Extract this shared object's name.  */
-      target_read_string (new->lm_info->l_name, &buffer,
+      target_read_string (newobj->lm_info->l_name, &buffer,
                          SO_NAME_MAX_PATH_SIZE - 1, &errcode);
       if (errcode != 0)
        {
@@ -1361,30 +1363,30 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm,
             inferior executable, then this is not a normal shared
             object, but (most likely) a vDSO.  In this case, silently
             skip it; otherwise emit a warning. */
-         if (first_l_name == 0 || new->lm_info->l_name != first_l_name)
+         if (first_l_name == 0 || newobj->lm_info->l_name != first_l_name)
            warning (_("Can't read pathname for load map: %s."),
                     safe_strerror (errcode));
          do_cleanups (old_chain);
          continue;
        }
 
-      strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
-      new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-      strcpy (new->so_original_name, new->so_name);
+      strncpy (newobj->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+      newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+      strcpy (newobj->so_original_name, newobj->so_name);
       xfree (buffer);
 
       /* If this entry has no name, or its name matches the name
         for the main executable, don't include it in the list.  */
-      if (! new->so_name[0] || match_main (new->so_name))
+      if (! newobj->so_name[0] || match_main (newobj->so_name))
        {
          do_cleanups (old_chain);
          continue;
        }
 
       discard_cleanups (old_chain);
-      new->next = 0;
-      **link_ptr_ptr = new;
-      *link_ptr_ptr = &new->next;
+      newobj->next = 0;
+      **link_ptr_ptr = newobj;
+      *link_ptr_ptr = &newobj->next;
     }
 
   return 1;
@@ -1463,10 +1465,11 @@ svr4_current_sos_direct (struct svr4_info *info)
   return head;
 }
 
-/* Implement the "current_sos" target_so_ops method.  */
+/* Implement the main part of the "current_sos" target_so_ops
+   method.  */
 
 static struct so_list *
-svr4_current_sos (void)
+svr4_current_sos_1 (void)
 {
   struct svr4_info *info = get_svr4_info ();
 
@@ -1479,6 +1482,82 @@ svr4_current_sos (void)
   return svr4_current_sos_direct (info);
 }
 
+/* Implement the "current_sos" target_so_ops method.  */
+
+static struct so_list *
+svr4_current_sos (void)
+{
+  struct so_list *so_head = svr4_current_sos_1 ();
+  struct mem_range vsyscall_range;
+
+  /* Filter out the vDSO module, if present.  Its symbol file would
+     not be found on disk.  The vDSO/vsyscall's OBJFILE is instead
+     managed by symfile-mem.c:add_vsyscall_page.  */
+  if (gdbarch_vsyscall_range (target_gdbarch (), &vsyscall_range)
+      && vsyscall_range.length != 0)
+    {
+      struct so_list **sop;
+
+      sop = &so_head;
+      while (*sop != NULL)
+       {
+         struct so_list *so = *sop;
+
+         /* We can't simply match the vDSO by starting address alone,
+            because lm_info->l_addr_inferior (and also l_addr) do not
+            necessarily represent the real starting address of the
+            ELF if the vDSO's ELF itself is "prelinked".  The l_ld
+            field (the ".dynamic" section of the shared object)
+            always points at the absolute/resolved address though.
+            So check whether that address is inside the vDSO's
+            mapping instead.
+
+            E.g., on Linux 3.16 (x86_64) the vDSO is a regular
+            0-based ELF, and we see:
+
+             (gdb) info auxv
+             33  AT_SYSINFO_EHDR  System-supplied DSO's ELF header 0x7ffff7ffb000
+             (gdb)  p/x *_r_debug.r_map.l_next
+             $1 = {l_addr = 0x7ffff7ffb000, ..., l_ld = 0x7ffff7ffb318, ...}
+
+            And on Linux 2.6.32 (x86_64) we see:
+
+             (gdb) info auxv
+             33  AT_SYSINFO_EHDR  System-supplied DSO's ELF header 0x7ffff7ffe000
+             (gdb) p/x *_r_debug.r_map.l_next
+             $5 = {l_addr = 0x7ffff88fe000, ..., l_ld = 0x7ffff7ffe580, ... }
+
+            Dumping that vDSO shows:
+
+             (gdb) info proc mappings
+             0x7ffff7ffe000  0x7ffff7fff000  0x1000  0  [vdso]
+             (gdb) dump memory vdso.bin 0x7ffff7ffe000 0x7ffff7fff000
+             # readelf -Wa vdso.bin
+             [...]
+               Entry point address: 0xffffffffff700700
+             [...]
+             Section Headers:
+               [Nr] Name     Type    Address          Off    Size
+               [ 0]          NULL    0000000000000000 000000 000000
+               [ 1] .hash    HASH    ffffffffff700120 000120 000038
+               [ 2] .dynsym  DYNSYM  ffffffffff700158 000158 0000d8
+             [...]
+               [ 9] .dynamic DYNAMIC ffffffffff700580 000580 0000f0
+         */
+         if (address_in_mem_range (so->lm_info->l_ld, &vsyscall_range))
+           {
+             *sop = so->next;
+             free_so (so);
+             break;
+           }
+
+         sop = &so->next;
+       }
+    }
+
+  return so_head;
+}
+
 /* Get the address of the link_map for a given OBJFILE.  */
 
 CORE_ADDR
@@ -1568,6 +1647,9 @@ struct probe_and_action
   /* The probe.  */
   struct probe *probe;
 
+  /* The relocated address of the probe.  */
+  CORE_ADDR address;
+
   /* The action.  */
   enum probe_action action;
 };
@@ -1579,7 +1661,7 @@ hash_probe_and_action (const void *p)
 {
   const struct probe_and_action *pa = p;
 
-  return (hashval_t) pa->probe->address;
+  return (hashval_t) pa->address;
 }
 
 /* Returns non-zero if the probe_and_actions referenced by p1 and p2
@@ -1591,14 +1673,15 @@ equal_probe_and_action (const void *p1, const void *p2)
   const struct probe_and_action *pa1 = p1;
   const struct probe_and_action *pa2 = p2;
 
-  return pa1->probe->address == pa2->probe->address;
+  return pa1->address == pa2->address;
 }
 
 /* Register a solib event probe and its associated action in the
    probes table.  */
 
 static void
-register_solib_event_probe (struct probe *probe, enum probe_action action)
+register_solib_event_probe (struct probe *probe, CORE_ADDR address,
+                           enum probe_action action)
 {
   struct svr4_info *info = get_svr4_info ();
   struct probe_and_action lookup, *pa;
@@ -1611,11 +1694,13 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
                                            xfree, xcalloc, xfree);
 
   lookup.probe = probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, INSERT);
   gdb_assert (*slot == HTAB_EMPTY_ENTRY);
 
   pa = XCNEW (struct probe_and_action);
   pa->probe = probe;
+  pa->address = address;
   pa->action = action;
 
   *slot = pa;
@@ -1628,12 +1713,10 @@ register_solib_event_probe (struct probe *probe, enum probe_action action)
 static struct probe_and_action *
 solib_event_probe_at (struct svr4_info *info, CORE_ADDR address)
 {
-  struct probe lookup_probe;
   struct probe_and_action lookup;
   void **slot;
 
-  lookup_probe.address = address;
-  lookup.probe = &lookup_probe;
+  lookup.address = address;
   slot = htab_find_slot (info->probes_table, &lookup, NO_INSERT);
 
   if (slot == NULL)
@@ -1934,7 +2017,8 @@ svr4_update_solib_event_breakpoints (void)
 
 static void
 svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
-                              VEC (probe_p) **probes)
+                              VEC (probe_p) **probes,
+                              struct objfile *objfile)
 {
   int i;
 
@@ -1948,8 +2032,10 @@ svr4_create_probe_breakpoints (struct gdbarch *gdbarch,
           VEC_iterate (probe_p, probes[i], ix, probe);
           ++ix)
        {
-         create_solib_event_breakpoint (gdbarch, probe->address);
-         register_solib_event_probe (probe, action);
+         CORE_ADDR address = get_probe_address (probe, objfile);
+
+         create_solib_event_breakpoint (gdbarch, address);
+         register_solib_event_probe (probe, address, action);
        }
     }
 
@@ -2034,7 +2120,7 @@ svr4_create_solib_event_breakpoints (struct gdbarch *gdbarch,
            }
 
          if (all_probes_found)
-           svr4_create_probe_breakpoints (gdbarch, probes);
+           svr4_create_probe_breakpoints (gdbarch, probes, os->objfile);
 
          for (i = 0; i < NUM_PROBES; i++)
            VEC_free (probe_p, probes[i]);
@@ -2184,7 +2270,6 @@ enable_break (struct svr4_info *info, int from_tty)
       struct so_list *so;
       bfd *tmp_bfd = NULL;
       struct target_ops *tmp_bfd_target;
-      volatile struct gdb_exception ex;
 
       sym_addr = 0;
 
@@ -2197,10 +2282,15 @@ enable_break (struct svr4_info *info, int from_tty)
          be trivial on GNU/Linux).  Therefore, we have to try an alternate
          mechanism to find the dynamic linker's base address.  */
 
-      TRY_CATCH (ex, RETURN_MASK_ALL)
+      TRY
         {
          tmp_bfd = solib_bfd_open (interp_name);
        }
+      CATCH (ex, RETURN_MASK_ALL)
+       {
+       }
+      END_CATCH
+
       if (tmp_bfd == NULL)
        goto bkpt_at_symbol;
 
@@ -3113,7 +3203,7 @@ struct target_so_ops svr4_so_ops;
    the main executable.  */
 
 static struct symbol *
-elf_lookup_lib_symbol (const struct objfile *objfile,
+elf_lookup_lib_symbol (struct objfile *objfile,
                       const char *name,
                       const domain_enum domain)
 {
This page took 0.041353 seconds and 4 git commands to generate.