linux-pid-attach.c revision 879850950bd56255cb5796c86b62bf3bdedd4fb9
10b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Get Dwarf Frame state for target live PID process.
2879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard   Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
30b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   This file is part of elfutils.
40b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
50b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   This file is free software; you can redistribute it and/or modify
60b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   it under the terms of either
70b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
80b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     * the GNU Lesser General Public License as published by the Free
90b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       Software Foundation; either version 3 of the License, or (at
100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       your option) any later version
110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   or
130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     * the GNU General Public License as published by the Free
150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       Software Foundation; either version 2 of the License, or (at
160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil       your option) any later version
170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   or both in parallel, as here.
190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   elfutils is distributed in the hope that it will be useful, but
210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   WITHOUT ANY WARRANTY; without even the implied warranty of
220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   General Public License for more details.
240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   You should have received copies of the GNU General Public License and
260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   the GNU Lesser General Public License along with this program.  If
270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil   not, see <http://www.gnu.org/licenses/>.  */
280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
29879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard#include "libelfP.h"
300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include "libdwflP.h"
31879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard#include <sys/types.h>
32879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard#include <sys/stat.h>
33879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard#include <fcntl.h>
340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/ptrace.h>
350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/wait.h>
360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <dirent.h>
370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/syscall.h>
380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <unistd.h>
390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#ifndef MAX
410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# define MAX(a, b) ((a) > (b) ? (a) : (b))
420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif
430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
4402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#ifdef __linux__
450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvillinux_proc_pid_is_stopped (pid_t pid)
480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  char buffer[64];
500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  FILE *procfile;
510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool retval, have_state;
520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  procfile = fopen (buffer, "r");
550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (procfile == NULL)
560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  have_state = false;
590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    if (strncmp (buffer, "State:", 6) == 0)
610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      {
620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	have_state = true;
630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	break;
640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      }
650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  fclose (procfile);
670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return retval;
680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
704b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardbool
714b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
724b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_ERRNO);
770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
7910d7a39aa2a509c16edd205c94b365ff1696f4fbJan Kratochvil  *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
8010d7a39aa2a509c16edd205c94b365ff1696f4fbJan Kratochvil  if (*tid_was_stoppedp)
810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      /* Make sure there is a SIGSTOP signal pending even when the process is
830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 already State: T (stopped).  Older kernels might fail to generate
840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 above.  Which would make the waitpid below wait forever.  So emulate
860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 it.  Since there can only be one SIGSTOP notification pending this is
870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 safe.  See also gdb/linux-nat.c linux_nat_post_attach_wait.  */
880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      syscall (__NR_tkill, tid, SIGSTOP);
890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      ptrace (PTRACE_CONT, tid, NULL, NULL);
900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  for (;;)
920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      int status;
940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  int saved_errno = errno;
970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  errno = saved_errno;
990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_ERRNO);
1000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
1010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (WSTOPSIG (status) == SIGSTOP)
1030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	break;
1040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (ptrace (PTRACE_CONT, tid, NULL,
1050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		  (void *) (uintptr_t) WSTOPSIG (status)) != 0)
1060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
1070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  int saved_errno = errno;
1080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
1090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  errno = saved_errno;
1100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_ERRNO);
1110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
1120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
1150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
1180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
1190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
1204b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = arg;
1210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = pid_arg->tid_attached;
1220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (tid > 0);
1230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = dwfl->process;
1240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
1250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      errno = 0;
1280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
1290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return errno == 0;
1300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#else /* SIZEOF_LONG != 8 */
1310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      /* This should not happen.  */
1320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
1330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG != 8 */
1340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  /* We do not care about reads unaliged to 4 bytes boundary.
1370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     But 0x...ffc read of 8 bytes could overrun a page.  */
1380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool lowered = (addr & 4) != 0;
1390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (lowered)
1400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    addr -= 4;
1410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG == 8 */
1420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  errno = 0;
1430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
1440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (errno != 0)
1450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
1460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# if BYTE_ORDER == BIG_ENDIAN
1480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (! lowered)
1490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    *result >>= 32;
1500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# else
1510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (lowered)
1520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    *result >>= 32;
1530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# endif
1540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG == 8 */
1550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *result &= 0xffffffff;
1560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
1570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic pid_t
1600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
1610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		 void **thread_argp)
1620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
1634b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
1640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  struct dirent *dirent;
165c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard  /* Start fresh on first traversal. */
166c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard  if (*thread_argp == NULL)
167c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard    rewinddir (pid_arg->dir);
1680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  do
1690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      errno = 0;
1710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      dirent = readdir (pid_arg->dir);
1720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (dirent == NULL)
1730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
1740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (errno != 0)
1750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
1760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_ERRNO);
1770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return -1;
1780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
1790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return 0;
1800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  while (strcmp (dirent->d_name, ".") == 0
1830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 || strcmp (dirent->d_name, "..") == 0);
1840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  char *end;
1850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  errno = 0;
1860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  long tidl = strtol (dirent->d_name, &end, 10);
1870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (errno != 0)
1880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_ERRNO);
1900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return -1;
1910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = tidl;
1930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (tidl <= 0 || (end && *end) || tid != tidl)
1940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_PARSE_PROC);
1960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return -1;
1970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *thread_argp = dwfl_arg;
1990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return tid;
2000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
202e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard/* Just checks that the thread id exists.  */
203e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaardstatic bool
204e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaardpid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
205e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard	       void *dwfl_arg, void **thread_argp)
206e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard{
207e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  *thread_argp = dwfl_arg;
208e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  if (kill (tid, 0) < 0)
209e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard    {
210e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard      __libdwfl_seterrno (DWFL_E_ERRNO);
211e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard      return false;
212e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard    }
213e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  return true;
214e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard}
215e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard
2160b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Implement the ebl_set_initial_registers_tid setfunc callback.  */
2170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
2191c1a53b657ef31b168928925884c01a7e4bcaf0cJan Kratochvilpid_thread_state_registers_cb (int firstreg, unsigned nregs,
2201c1a53b657ef31b168928925884c01a7e4bcaf0cJan Kratochvil			       const Dwarf_Word *regs, void *arg)
2210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Thread *thread = (Dwfl_Thread *) arg;
2235cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  if (firstreg < 0)
2245cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    {
2255cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      assert (firstreg == -1);
2265cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      assert (nregs == 1);
2275cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
2285cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      return true;
2295cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    }
2305cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  assert (nregs > 0);
2310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
2320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
2350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
2360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2374b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = thread_arg;
2380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (pid_arg->tid_attached == 0);
2390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
24019108019192ab273c53ae324be448d29dac806caMark Wielaard  if (! pid_arg->assume_ptrace_stopped
2414b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard      && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
2420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
2430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = tid;
2440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = thread->process;
2450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Ebl *ebl = process->ebl;
2460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return ebl_set_initial_registers_tid (ebl, tid,
2470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil					pid_thread_state_registers_cb, thread);
2480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic void
2510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
2520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2534b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
254879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  elf_end (pid_arg->elf);
255879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  close (pid_arg->elf_fd);
2560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  closedir (pid_arg->dir);
2570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  free (pid_arg);
2580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2604b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardvoid
2614b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
2624b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
2634b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard{
2644b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  /* This handling is needed only on older Linux kernels such as
2654b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     2.6.32-358.23.2.el6.ppc64.  Later kernels such as
2664b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     3.11.7-200.fc19.x86_64 remember the T (stopped) state
2674b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     themselves and no longer need to pass SIGSTOP during
2684b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     PTRACE_DETACH.  */
2694b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  ptrace (PTRACE_DETACH, tid, NULL,
2704b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard	  (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
2714b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard}
2724b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
2730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic void
2740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
2750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2764b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = thread_arg;
2770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
2780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (pid_arg->tid_attached == tid);
2790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = 0;
28019108019192ab273c53ae324be448d29dac806caMark Wielaard  if (! pid_arg->assume_ptrace_stopped)
2814b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard    __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
2820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic const Dwfl_Thread_Callbacks pid_thread_callbacks =
2850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_next_thread,
287e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  pid_getthread,
2880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_memory_read,
2890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_set_initial_registers,
2900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_detach,
2910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_thread_detach,
2920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil};
2930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
29419108019192ab273c53ae324be448d29dac806caMark Wielaardint
29519108019192ab273c53ae324be448d29dac806caMark Wielaarddwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
2960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
29797bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  char buffer[36];
29897bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  FILE *procfile;
29914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard  int err = 0; /* The errno to return and set for dwfl->attcherr.  */
30097bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
30197bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  /* Make sure to report the actual PID (thread group leader) to
30297bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard     dwfl_attach_state.  */
30397bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
30497bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  procfile = fopen (buffer, "r");
30597bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  if (procfile == NULL)
30614beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
30714beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = errno;
30814beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    fail:
30914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
31014beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	{
31114beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	  errno = err;
31214beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
31314beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	}
31414beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      return err;
31514beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
31697bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
31797bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  char *line = NULL;
31897bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  size_t linelen = 0;
31997bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  while (getline (&line, &linelen, procfile) >= 0)
32097bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard    if (strncmp (line, "Tgid:", 5) == 0)
32197bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard      {
32268de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	errno = 0;
32368de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	char *endptr;
32468de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	long val = strtol (&line[5], &endptr, 10);
32568de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	if ((errno == ERANGE && val == LONG_MAX)
32668de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	    || *endptr != '\n' || val < 0 || val != (pid_t) val)
32768de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	  pid = 0;
32868de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	else
32968de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	  pid = (pid_t) val;
33068de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	break;
33197bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard      }
33297bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  free (line);
33397bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  fclose (procfile);
33497bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
33597bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  if (pid == 0)
33614beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
33714beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = ESRCH;
33814beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
33914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
34097bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
341879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  char name[64];
342879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
343879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
344879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  DIR *dir = opendir (name);
3450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (dir == NULL)
34614beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
34714beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = errno;
34814beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
34914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
350879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard
351879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  Elf *elf;
352879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
353879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
354879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  int elf_fd = open (name, O_RDONLY);
355879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  if (elf_fd >= 0)
356879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard    {
357879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
358879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      if (elf == NULL)
359879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	{
360879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	  /* Just ignore, dwfl_attach_state will fall back to trying
361879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	     to associate the Dwfl with one of the existing DWfl_Module
362879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	     ELF images (to know the machine/class backend to use).  */
363879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	  close (elf_fd);
364879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	  elf_fd = -1;
365879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard	}
366879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard    }
367879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  else
368879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard    elf = NULL;
3694b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
3700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (pid_arg == NULL)
3710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
372879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      elf_end (elf);
373879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      close (elf_fd);
3740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      closedir (dir);
37514beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = ENOMEM;
37614beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
3770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
3780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->dir = dir;
379879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  pid_arg->elf = elf;
380879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  pid_arg->elf_fd = elf_fd;
3810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = 0;
38219108019192ab273c53ae324be448d29dac806caMark Wielaard  pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
383879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard  if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
3840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil				   pid_arg))
3850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
386879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      elf_end (elf);
387879850950bd56255cb5796c86b62bf3bdedd4fb9Mark Wielaard      close (elf_fd);
3880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      closedir (dir);
3890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      free (pid_arg);
39019108019192ab273c53ae324be448d29dac806caMark Wielaard      return -1;
3910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
39219108019192ab273c53ae324be448d29dac806caMark Wielaard  return 0;
3930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
39419108019192ab273c53ae324be448d29dac806caMark WielaardINTDEF (dwfl_linux_proc_attach)
3954b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
3964b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardstruct __libdwfl_pid_arg *
3974b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
3984b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_get_pid_arg (Dwfl *dwfl)
3994b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard{
4004b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  if (dwfl != NULL && dwfl->process != NULL
4014b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard      && dwfl->process->callbacks == &pid_thread_callbacks)
4024b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard    return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
4034b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
4044b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  return NULL;
4054b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard}
40602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
40702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#else	/* __linux__ */
40802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
40902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic pid_t
41002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
41102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         void *dwfl_arg __attribute__ ((unused)),
41202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx		 void **thread_argp __attribute__ ((unused)))
41302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
41402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
41502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
41602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return -1;
41702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
41802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
41902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
42002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_getthread (Dwfl *dwfl __attribute__ ((unused)),
42102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       pid_t tid __attribute__ ((unused)),
42202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       void *dwfl_arg __attribute__ ((unused)),
42302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       void **thread_argp __attribute__ ((unused)))
42402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
42502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
42602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
42702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
42802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
42902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
430a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckxbool
431a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckxinternal_function
432a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
433a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx			 bool *tid_was_stoppedp __attribute__ ((unused)))
434a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx{
435a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx  errno = ENOSYS;
436a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
437a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx  return false;
438a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx}
439a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx
44002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
44102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
44202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx                 Dwarf_Addr addr __attribute__ ((unused)),
44302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         Dwarf_Word *result __attribute__ ((unused)),
44402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         void *arg __attribute__ ((unused)))
44502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
44602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
44702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
44802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
44902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
45002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
45102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
45202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
45302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			   void *thread_arg __attribute__ ((unused)))
45402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
45502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
45602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
45702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
45802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
45902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
46002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic void
46102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_detach (Dwfl *dwfl __attribute__ ((unused)),
46202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	    void *dwfl_arg __attribute__ ((unused)))
46302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
46402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
46502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
466a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckxvoid
467a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckxinternal_function
468a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
469a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx			 bool tid_was_stopped __attribute__ ((unused)))
470a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx{
471a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx}
472a7a385547bbcc6e5fc15935b99ce0136126f1908Kurt Roeckx
47302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic void
47402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
47502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx		  void *thread_arg __attribute__ ((unused)))
47602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
47702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
47802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
47902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic const Dwfl_Thread_Callbacks pid_thread_callbacks =
48002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
48102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_next_thread,
48202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_getthread,
48302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_memory_read,
48402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_set_initial_registers,
48502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_detach,
48602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_thread_detach,
48702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx};
48802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
48902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxint
49002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxdwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
49102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			pid_t pid __attribute__ ((unused)),
49202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			bool assume_ptrace_stopped __attribute__ ((unused)))
49302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
49402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return ENOSYS;
49502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
49602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt RoeckxINTDEF (dwfl_linux_proc_attach)
49702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
49802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstruct __libdwfl_pid_arg *
49902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxinternal_function
50002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
50102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
50202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return NULL;
50302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
50402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
50502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#endif /* ! __linux __ */
50602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
507