libdwfl: Make dwfl_linux_proc_attach work even without any Dwfl_Modules.

dwfl_linux_proc_attach depended on a Dwfl_Module with the correct
ELF header already being available. That isn't really necessary since
when we attach we have the main exe ELF file available. Just use that
to make dwfl_linux_proc_attach always work.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index ae71702..4c0f42d 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -1,5 +1,5 @@
 /* Get Dwarf Frame state for target live PID process.
-   Copyright (C) 2013, 2014 Red Hat, Inc.
+   Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -26,7 +26,11 @@
    the GNU Lesser General Public License along with this program.  If
    not, see <http://www.gnu.org/licenses/>.  */
 
+#include "libelfP.h"
 #include "libdwflP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <sys/ptrace.h>
 #include <sys/wait.h>
 #include <dirent.h>
@@ -247,6 +251,8 @@
 pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
 {
   struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
+  elf_end (pid_arg->elf);
+  close (pid_arg->elf_fd);
   closedir (pid_arg->dir);
   free (pid_arg);
 }
@@ -332,28 +338,53 @@
       goto fail;
     }
 
-  char dirname[64];
-  int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
-  assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
-  DIR *dir = opendir (dirname);
+  char name[64];
+  int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
+  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+  DIR *dir = opendir (name);
   if (dir == NULL)
     {
       err = errno;
       goto fail;
     }
+
+  Elf *elf;
+  i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
+  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+  int elf_fd = open (name, O_RDONLY);
+  if (elf_fd >= 0)
+    {
+      elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
+      if (elf == NULL)
+	{
+	  /* Just ignore, dwfl_attach_state will fall back to trying
+	     to associate the Dwfl with one of the existing DWfl_Module
+	     ELF images (to know the machine/class backend to use).  */
+	  close (elf_fd);
+	  elf_fd = -1;
+	}
+    }
+  else
+    elf = NULL;
   struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
   if (pid_arg == NULL)
     {
+      elf_end (elf);
+      close (elf_fd);
       closedir (dir);
       err = ENOMEM;
       goto fail;
     }
   pid_arg->dir = dir;
+  pid_arg->elf = elf;
+  pid_arg->elf_fd = elf_fd;
   pid_arg->tid_attached = 0;
   pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
-  if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
+  if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
 				   pid_arg))
     {
+      elf_end (elf);
+      close (elf_fd);
       closedir (dir);
       free (pid_arg);
       return -1;