Enable Gold linker for cross-*-binutils build
[platform/upstream/binutils.git] / gdb / solib-svr4.c
index 978564c..5313bf0 100644 (file)
@@ -43,7 +43,6 @@
 #include "elf-bfd.h"
 #include "exec.h"
 #include "auxv.h"
-#include "exceptions.h"
 #include "gdb_bfd.h"
 #include "probe.h"
 
@@ -1462,10 +1461,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 ();
 
@@ -1478,6 +1478,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