linux-pid-attach.c revision 14beac3b6f22b8d7a054980f74c4f8d33b969fc4
10b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Get Dwarf Frame state for target live PID process.
24b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard   Copyright (C) 2013, 2014 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
290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include "libdwflP.h"
300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/ptrace.h>
310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/wait.h>
320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <dirent.h>
330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <sys/syscall.h>
340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#include <unistd.h>
350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#ifndef MAX
370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# define MAX(a, b) ((a) > (b) ? (a) : (b))
380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif
390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
4002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#ifdef __linux__
410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvillinux_proc_pid_is_stopped (pid_t pid)
440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  char buffer[64];
460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  FILE *procfile;
470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool retval, have_state;
480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  procfile = fopen (buffer, "r");
510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (procfile == NULL)
520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  have_state = false;
550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    if (strncmp (buffer, "State:", 6) == 0)
570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      {
580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	have_state = true;
590b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	break;
600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      }
610b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  fclose (procfile);
630b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return retval;
640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
664b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardbool
674b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
684b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_ERRNO);
730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
7510d7a39aa2a509c16edd205c94b365ff1696f4fbJan Kratochvil  *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
7610d7a39aa2a509c16edd205c94b365ff1696f4fbJan Kratochvil  if (*tid_was_stoppedp)
770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      /* Make sure there is a SIGSTOP signal pending even when the process is
790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 already State: T (stopped).  Older kernels might fail to generate
800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 above.  Which would make the waitpid below wait forever.  So emulate
820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 it.  Since there can only be one SIGSTOP notification pending this is
830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 safe.  See also gdb/linux-nat.c linux_nat_post_attach_wait.  */
840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      syscall (__NR_tkill, tid, SIGSTOP);
850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      ptrace (PTRACE_CONT, tid, NULL, NULL);
860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  for (;;)
880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      int status;
900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  int saved_errno = errno;
930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  errno = saved_errno;
950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_ERRNO);
960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
980b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (WSTOPSIG (status) == SIGSTOP)
990b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	break;
1000b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (ptrace (PTRACE_CONT, tid, NULL,
1010b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		  (void *) (uintptr_t) WSTOPSIG (status)) != 0)
1020b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
1030b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  int saved_errno = errno;
1040b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
1050b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  errno = saved_errno;
1060b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  __libdwfl_seterrno (DWFL_E_ERRNO);
1070b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return false;
1080b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1090b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1100b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
1110b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
1140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
1150b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
1164b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = arg;
1170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = pid_arg->tid_attached;
1180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (tid > 0);
1190b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = dwfl->process;
1200b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
1210b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1220b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1230b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      errno = 0;
1240b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
1250b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return errno == 0;
1260b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#else /* SIZEOF_LONG != 8 */
1270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      /* This should not happen.  */
1280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return false;
1290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG != 8 */
1300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  /* We do not care about reads unaliged to 4 bytes boundary.
1330b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil     But 0x...ffc read of 8 bytes could overrun a page.  */
1340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  bool lowered = (addr & 4) != 0;
1350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (lowered)
1360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    addr -= 4;
1370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG == 8 */
1380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  errno = 0;
1390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
1400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (errno != 0)
1410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
1420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#if SIZEOF_LONG == 8
1430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# if BYTE_ORDER == BIG_ENDIAN
1440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (! lowered)
1450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    *result >>= 32;
1460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# else
1470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (lowered)
1480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    *result >>= 32;
1490b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil# endif
1500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil#endif /* SIZEOF_LONG == 8 */
1510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *result &= 0xffffffff;
1520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return true;
1530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1540b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
1550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic pid_t
1560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
1570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil		 void **thread_argp)
1580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
1594b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
1600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  struct dirent *dirent;
161c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard  /* Start fresh on first traversal. */
162c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard  if (*thread_argp == NULL)
163c76b2ff3eebc04c628ea7475c7ea0abb6cf0ff0dMark Wielaard    rewinddir (pid_arg->dir);
1640b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  do
1650b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1660b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      errno = 0;
1670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      dirent = readdir (pid_arg->dir);
1680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      if (dirent == NULL)
1690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	{
1700b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  if (errno != 0)
1710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    {
1720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      __libdwfl_seterrno (DWFL_E_ERRNO);
1730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	      return -1;
1740b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	    }
1750b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	  return 0;
1760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	}
1770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  while (strcmp (dirent->d_name, ".") == 0
1790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil	 || strcmp (dirent->d_name, "..") == 0);
1800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  char *end;
1810b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  errno = 0;
1820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  long tidl = strtol (dirent->d_name, &end, 10);
1830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (errno != 0)
1840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_ERRNO);
1860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return -1;
1870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1880b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = tidl;
1890b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (tidl <= 0 || (end && *end) || tid != tidl)
1900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
1910b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      __libdwfl_seterrno (DWFL_E_PARSE_PROC);
1920b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      return -1;
1930b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
1940b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  *thread_argp = dwfl_arg;
1950b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return tid;
1960b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
1970b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
198e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard/* Just checks that the thread id exists.  */
199e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaardstatic bool
200e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaardpid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
201e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard	       void *dwfl_arg, void **thread_argp)
202e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard{
203e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  *thread_argp = dwfl_arg;
204e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  if (kill (tid, 0) < 0)
205e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard    {
206e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard      __libdwfl_seterrno (DWFL_E_ERRNO);
207e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard      return false;
208e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard    }
209e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  return true;
210e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard}
211e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard
2120b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil/* Implement the ebl_set_initial_registers_tid setfunc callback.  */
2130b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2140b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
2151c1a53b657ef31b168928925884c01a7e4bcaf0cJan Kratochvilpid_thread_state_registers_cb (int firstreg, unsigned nregs,
2161c1a53b657ef31b168928925884c01a7e4bcaf0cJan Kratochvil			       const Dwarf_Word *regs, void *arg)
2170b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2180b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Thread *thread = (Dwfl_Thread *) arg;
2195cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  if (firstreg < 0)
2205cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    {
2215cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      assert (firstreg == -1);
2225cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      assert (nregs == 1);
2235cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
2245cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil      return true;
2255cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil    }
2265cbf42aaf47195e2c41171786371d55b253a7667Jan Kratochvil  assert (nregs > 0);
2270b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
2280b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2290b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2300b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic bool
2310b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
2320b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2334b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = thread_arg;
2340b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (pid_arg->tid_attached == 0);
2350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
23619108019192ab273c53ae324be448d29dac806caMark Wielaard  if (! pid_arg->assume_ptrace_stopped
2374b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard      && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
2380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    return false;
2390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = tid;
2400b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Dwfl_Process *process = thread->process;
2410b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  Ebl *ebl = process->ebl;
2420b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  return ebl_set_initial_registers_tid (ebl, tid,
2430b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil					pid_thread_state_registers_cb, thread);
2440b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic void
2470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
2480b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2494b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
2500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  closedir (pid_arg->dir);
2510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  free (pid_arg);
2520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2530b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2544b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardvoid
2554b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
2564b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
2574b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard{
2584b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  /* This handling is needed only on older Linux kernels such as
2594b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     2.6.32-358.23.2.el6.ppc64.  Later kernels such as
2604b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     3.11.7-200.fc19.x86_64 remember the T (stopped) state
2614b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     themselves and no longer need to pass SIGSTOP during
2624b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard     PTRACE_DETACH.  */
2634b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  ptrace (PTRACE_DETACH, tid, NULL,
2644b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard	  (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
2654b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard}
2664b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
2670b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic void
2680b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilpid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
2690b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2704b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = thread_arg;
2710b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
2720b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (pid_arg->tid_attached == tid);
2730b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = 0;
27419108019192ab273c53ae324be448d29dac806caMark Wielaard  if (! pid_arg->assume_ptrace_stopped)
2754b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard    __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
2760b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
2770b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
2780b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvilstatic const Dwfl_Thread_Callbacks pid_thread_callbacks =
2790b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
2800b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_next_thread,
281e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard  pid_getthread,
2820b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_memory_read,
2830b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_set_initial_registers,
2840b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_detach,
2850b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_thread_detach,
2860b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil};
2870b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil
28819108019192ab273c53ae324be448d29dac806caMark Wielaardint
28919108019192ab273c53ae324be448d29dac806caMark Wielaarddwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
2900b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil{
29197bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  char buffer[36];
29297bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  FILE *procfile;
29314beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard  int err = 0; /* The errno to return and set for dwfl->attcherr.  */
29497bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
29597bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  /* Make sure to report the actual PID (thread group leader) to
29697bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard     dwfl_attach_state.  */
29797bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
29897bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  procfile = fopen (buffer, "r");
29997bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  if (procfile == NULL)
30014beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
30114beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = errno;
30214beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    fail:
30314beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
30414beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	{
30514beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	  errno = err;
30614beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
30714beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard	}
30814beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      return err;
30914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
31097bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
31197bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  char *line = NULL;
31297bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  size_t linelen = 0;
31397bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  while (getline (&line, &linelen, procfile) >= 0)
31497bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard    if (strncmp (line, "Tgid:", 5) == 0)
31597bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard      {
31668de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	errno = 0;
31768de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	char *endptr;
31868de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	long val = strtol (&line[5], &endptr, 10);
31968de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	if ((errno == ERANGE && val == LONG_MAX)
32068de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	    || *endptr != '\n' || val < 0 || val != (pid_t) val)
32168de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	  pid = 0;
32268de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	else
32368de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	  pid = (pid_t) val;
32468de442d13f7b3192d0b81634c0f2136002c4552Mark Wielaard	break;
32597bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard      }
32697bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  free (line);
32797bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  fclose (procfile);
32897bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
32997bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard  if (pid == 0)
33014beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
33114beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = ESRCH;
33214beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
33314beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
33497bbf9b7ca002aab236bf750aba699d81f7985f7Mark Wielaard
3350b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  char dirname[64];
3360b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
3370b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
3380b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  DIR *dir = opendir (dirname);
3390b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (dir == NULL)
34014beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    {
34114beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = errno;
34214beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
34314beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard    }
3444b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
3450b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  if (pid_arg == NULL)
3460b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
3470b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      closedir (dir);
34814beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      err = ENOMEM;
34914beac3b6f22b8d7a054980f74c4f8d33b969fc4Mark Wielaard      goto fail;
3500b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
3510b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->dir = dir;
3520b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil  pid_arg->tid_attached = 0;
35319108019192ab273c53ae324be448d29dac806caMark Wielaard  pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
354ed78237ef7c31fb1d7dc80e2c2e07484e1216727Jan Kratochvil  if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
3550b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil				   pid_arg))
3560b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    {
3570b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      closedir (dir);
3580b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil      free (pid_arg);
35919108019192ab273c53ae324be448d29dac806caMark Wielaard      return -1;
3600b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil    }
36119108019192ab273c53ae324be448d29dac806caMark Wielaard  return 0;
3620b867460075c9f02cb305abc91a0e12b90017583Jan Kratochvil}
36319108019192ab273c53ae324be448d29dac806caMark WielaardINTDEF (dwfl_linux_proc_attach)
3644b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
3654b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardstruct __libdwfl_pid_arg *
3664b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaardinternal_function
3674b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard__libdwfl_get_pid_arg (Dwfl *dwfl)
3684b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard{
3694b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  if (dwfl != NULL && dwfl->process != NULL
3704b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard      && dwfl->process->callbacks == &pid_thread_callbacks)
3714b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard    return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
3724b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard
3734b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard  return NULL;
3744b9e1433d2272f5f68b3227abdd9cf6817a0afd3Mark Wielaard}
37502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
37602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#else	/* __linux__ */
37702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
37802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic pid_t
37902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
38002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         void *dwfl_arg __attribute__ ((unused)),
38102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx		 void **thread_argp __attribute__ ((unused)))
38202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
38302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
38402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
38502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return -1;
38602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
38702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
38802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
38902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_getthread (Dwfl *dwfl __attribute__ ((unused)),
39002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       pid_t tid __attribute__ ((unused)),
39102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       void *dwfl_arg __attribute__ ((unused)),
39202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	       void **thread_argp __attribute__ ((unused)))
39302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
39402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
39502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
39602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
39702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
39802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
39902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
40002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
40102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx                 Dwarf_Addr addr __attribute__ ((unused)),
40202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         Dwarf_Word *result __attribute__ ((unused)),
40302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	         void *arg __attribute__ ((unused)))
40402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
40502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
40602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
40702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
40802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
40902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
41002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic bool
41102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
41202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			   void *thread_arg __attribute__ ((unused)))
41302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
41402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  errno = ENOSYS;
41502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  __libdwfl_seterrno (DWFL_E_ERRNO);
41602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return false;
41702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
41802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
41902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic void
42002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_detach (Dwfl *dwfl __attribute__ ((unused)),
42102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx	    void *dwfl_arg __attribute__ ((unused)))
42202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
42302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
42402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
42502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic void
42602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxpid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
42702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx		  void *thread_arg __attribute__ ((unused)))
42802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
42902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
43002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
43102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstatic const Dwfl_Thread_Callbacks pid_thread_callbacks =
43202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
43302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_next_thread,
43402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_getthread,
43502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_memory_read,
43602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_set_initial_registers,
43702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_detach,
43802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  pid_thread_detach,
43902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx};
44002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
44102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxint
44202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxdwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
44302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			pid_t pid __attribute__ ((unused)),
44402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx			bool assume_ptrace_stopped __attribute__ ((unused)))
44502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
44602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return ENOSYS;
44702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
44802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt RoeckxINTDEF (dwfl_linux_proc_attach)
44902cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
45002cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxstruct __libdwfl_pid_arg *
45102cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckxinternal_function
45202cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
45302cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx{
45402cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx  return NULL;
45502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx}
45602cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
45702cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#endif /* ! __linux __ */
45802cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx
459