18ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil/* Test custom provided Dwfl_Thread_Callbacks vector. 28ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Copyright (C) 2013 Red Hat, Inc. 38ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil This file is part of elfutils. 48ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 58ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil This file is free software; you can redistribute it and/or modify 68ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil it under the terms of the GNU General Public License as published by 78ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil the Free Software Foundation; either version 3 of the License, or 88ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil (at your option) any later version. 98ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 108ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil elfutils is distributed in the hope that it will be useful, but 118ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil WITHOUT ANY WARRANTY; without even the implied warranty of 128ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 138ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil GNU General Public License for more details. 148ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 158ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil You should have received a copy of the GNU General Public License 168ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil along with this program. If not, see <http://www.gnu.org/licenses/>. */ 178ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 188ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil/* Test custom provided Dwfl_Thread_Callbacks vector. Test mimics what 198ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil a ptrace based vector would do. */ 208ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 218ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <config.h> 228ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <assert.h> 238ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <inttypes.h> 248ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <stdio.h> 258ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <stdio_ext.h> 268ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <locale.h> 278ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <dirent.h> 288ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <stdlib.h> 298ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <errno.h> 308ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <error.h> 318ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <unistd.h> 328ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <dwarf.h> 3365251494ae6eae66bfdf9134189fd11b1ee8e9b5Pino Toscano#if defined(__x86_64__) && defined(__linux__) 348ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <sys/resource.h> 358ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <sys/ptrace.h> 368ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <signal.h> 378ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <sys/types.h> 388ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <sys/wait.h> 398ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <sys/user.h> 408ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <fcntl.h> 418ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include <string.h> 428ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#include ELFUTILS_HEADER(dwfl) 4365251494ae6eae66bfdf9134189fd11b1ee8e9b5Pino Toscano#endif 448ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 4502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#if !defined(__x86_64__) || !defined(__linux__) 468ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 478ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilint 48813aae0e94c2e694e1cad25d4e268dfe60397196Mark Wielaardmain (int argc __attribute__ ((unused)), char **argv) 498ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 50813aae0e94c2e694e1cad25d4e268dfe60397196Mark Wielaard fprintf (stderr, "%s: Unwinding not supported for this architecture\n", 51813aae0e94c2e694e1cad25d4e268dfe60397196Mark Wielaard argv[0]); 528ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return 77; 538ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 548ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 5502cefdaa6429e620d6457fdb3ad9934f194c5a93Kurt Roeckx#else /* __x86_64__ && __linux__ */ 568ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 578ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil/* The only arch specific code is set_initial_registers. */ 588ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 598ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic int 608ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilfind_elf (Dwfl_Module *mod __attribute__ ((unused)), 618ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil void **userdata __attribute__ ((unused)), 628ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil const char *modname __attribute__ ((unused)), 638ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwarf_Addr base __attribute__ ((unused)), 648ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil char **file_name __attribute__ ((unused)), 658ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Elf **elfp __attribute__ ((unused))) 668ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 678ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* Not used as modules are reported explicitly. */ 688ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (0); 698ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 708ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 718ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic bool 728ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilmemory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, 738ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil void *dwfl_arg __attribute__ ((unused))) 748ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 758ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil pid_t child = dwfl_pid (dwfl); 768ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 778ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil errno = 0; 788ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil long l = ptrace (PTRACE_PEEKDATA, child, (void *) (uintptr_t) addr, NULL); 79c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 808ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil *result = l; 818ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 828ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* We could also return false for failed ptrace. */ 838ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return true; 848ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 858ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 868ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil/* Return filename and VMA address *BASEP where its mapping starts which 878ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil contains ADDR. */ 888ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 898ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic char * 908ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilmaps_lookup (pid_t pid, Dwarf_Addr addr, GElf_Addr *basep) 918ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 928ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil char *fname; 938ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil int i = asprintf (&fname, "/proc/%ld/maps", (long) pid); 94c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 958ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (i > 0); 968ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil FILE *f = fopen (fname, "r"); 97c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 988ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (f); 998ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil free (fname); 1008ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil for (;;) 1018ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 1028ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil // 37e3c22000-37e3c23000 rw-p 00022000 00:11 49532 /lib64/ld-2.14.90.so */ 1038ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil unsigned long start, end, offset; 1048ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil i = fscanf (f, "%lx-%lx %*s %lx %*x:%*x %*x", &start, &end, &offset); 105c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 1068ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (i == 3); 1078ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil char *filename = strdup (""); 1088ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (filename); 1098ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil size_t filename_len = 0; 1108ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil for (;;) 1118ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 1128ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil int c = fgetc (f); 1138ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (c != EOF); 1148ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (c == '\n') 1158ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil break; 1168ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (c == ' ' && *filename == '\0') 1178ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil continue; 1188ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil filename = realloc (filename, filename_len + 2); 1198ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (filename); 1208ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil filename[filename_len++] = c; 1218ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil filename[filename_len] = '\0'; 1228ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 1238ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (start <= addr && addr < end) 1248ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 1258ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil i = fclose (f); 126c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 1278ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (i == 0); 1288ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1298ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil *basep = start - offset; 1308ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return filename; 1318ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 1328ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil free (filename); 1338ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 1348ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 1358ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1368ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil/* Add module containing ADDR to the DWFL address space. 1378ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1388ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwfl_report_elf call here violates Dwfl manipulation as one should call 1398ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwfl_report only between dwfl_report_begin_add and dwfl_report_end. 1408ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Current elfutils implementation does not mind as dwfl_report_begin_add is 1418ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil empty. */ 1428ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1438ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic Dwfl_Module * 1448ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilreport_module (Dwfl *dwfl, pid_t child, Dwarf_Addr addr) 1458ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 1468ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil GElf_Addr base; 1478ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil char *long_name = maps_lookup (child, addr, &base); 1488ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwfl_Module *mod = dwfl_report_elf (dwfl, long_name, long_name, -1, 1498ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil base, false /* add_p_vaddr */); 1508ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (mod); 1518ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil free (long_name); 1528ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (dwfl_addrmodule (dwfl, addr) == mod); 1538ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return mod; 1548ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 1558ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1568ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic pid_t 1578ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilnext_thread (Dwfl *dwfl, void *dwfl_arg __attribute__ ((unused)), 1588ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil void **thread_argp) 1598ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 1608ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (*thread_argp != NULL) 1618ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return 0; 1628ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* Put arbitrary non-NULL value into *THREAD_ARGP as a marker so that this 1638ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil function returns non-zero PID only once. */ 1648ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil *thread_argp = thread_argp; 1658ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return dwfl_pid (dwfl); 1668ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 1678ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1688ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic bool 1698ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilset_initial_registers (Dwfl_Thread *thread, 1708ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil void *thread_arg __attribute__ ((unused))) 1718ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 1728ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil pid_t child = dwfl_pid (dwfl_thread_dwfl (thread)); 1738ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1748ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil struct user_regs_struct user_regs; 1758ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs); 176c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 1778ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (l == 0); 1788ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 1798ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwarf_Word dwarf_regs[17]; 1808ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[0] = user_regs.rax; 1818ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[1] = user_regs.rdx; 1828ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[2] = user_regs.rcx; 1838ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[3] = user_regs.rbx; 1848ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[4] = user_regs.rsi; 1858ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[5] = user_regs.rdi; 1868ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[6] = user_regs.rbp; 1878ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[7] = user_regs.rsp; 1888ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[8] = user_regs.r8; 1898ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[9] = user_regs.r9; 1908ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[10] = user_regs.r10; 1918ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[11] = user_regs.r11; 1928ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[12] = user_regs.r12; 1938ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[13] = user_regs.r13; 1948ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[14] = user_regs.r14; 1958ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[15] = user_regs.r15; 1968ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwarf_regs[16] = user_regs.rip; 1978ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil bool ok = dwfl_thread_state_registers (thread, 0, 17, dwarf_regs); 1988ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (ok); 1998ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2008ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* x86_64 has PC contained in its CFI subset of DWARF register set so 2018ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil elfutils will figure out the real PC value from REGS. 2028ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil So no need to explicitly call dwfl_thread_state_register_pc. */ 2038ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2048ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return true; 2058ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 2068ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2078ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic const Dwfl_Thread_Callbacks callbacks = 2088ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 2098ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil next_thread, 210e962ec3bcbe8eccdcded36aaafee7bec41fa1bc4Mark Wielaard NULL, /* get_thread */ 2118ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil memory_read, 2128ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil set_initial_registers, 2138ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil NULL, /* detach */ 2148ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil NULL, /* thread_detach */ 2158ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil}; 2168ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2178ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic int 2188ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilframe_callback (Dwfl_Frame *state, void *arg) 2198ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 2208ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil unsigned *framenop = arg; 2218ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwarf_Addr pc; 2228ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil bool isactivation; 2238ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (! dwfl_frame_pc (state, &pc, &isactivation)) 2248ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 2258ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil error (1, 0, "%s", dwfl_errmsg (-1)); 2268ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return 1; 2278ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 2288ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); 2298ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2308ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* Get PC->SYMNAME. */ 2318ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwfl *dwfl = dwfl_thread_dwfl (dwfl_frame_thread (state)); 2328ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); 2338ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil if (mod == NULL) 2348ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil mod = report_module (dwfl, dwfl_pid (dwfl), pc_adjusted); 2358ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil const char *symname = NULL; 2368ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil symname = dwfl_module_addrname (mod, pc_adjusted); 2378ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2388ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil printf ("#%2u %#" PRIx64 "%4s\t%s\n", (*framenop)++, (uint64_t) pc, 2398ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil ! isactivation ? "- 1" : "", symname); 2408ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return DWARF_CB_OK; 2418ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 2428ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2438ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilstatic int 2448ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilthread_callback (Dwfl_Thread *thread, void *thread_arg __attribute__ ((unused))) 2458ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 2468ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil unsigned frameno = 0; 2478ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil switch (dwfl_thread_getframes (thread, frame_callback, &frameno)) 2488ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 2498ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil case 0: 2508ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil break; 2518ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil case -1: 2528ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1)); 2538ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil default: 2548ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil abort (); 2558ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 2568ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return DWARF_CB_OK; 2578ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 2588ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2598ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilint 2608ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvilmain (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) 2618ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil{ 2628ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* We use no threads here which can interfere with handling a stream. */ 2638ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil __fsetlocking (stdin, FSETLOCKING_BYCALLER); 2648ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil __fsetlocking (stdout, FSETLOCKING_BYCALLER); 2658ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil __fsetlocking (stderr, FSETLOCKING_BYCALLER); 2668ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2678ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* Set locale. */ 2688ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil (void) setlocale (LC_ALL, ""); 2698ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2708ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil elf_version (EV_CURRENT); 2718ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2728ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil pid_t child = fork (); 2738ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil switch (child) 2748ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 2758ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil case -1: 276c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 2778ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (0); 2788ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil case 0:; 2798ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); 280c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 2818ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (l == 0); 2828ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil raise (SIGUSR1); 28370c3a53baa06b6cdee6e92bd673c1cf977066bc1Mark Wielaard return 0; 2848ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil default: 2858ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil break; 2868ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil } 2878ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2888ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil int status; 2898ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil pid_t pid = waitpid (child, &status, 0); 290c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 2918ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (pid == child); 2928ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (WIFSTOPPED (status)); 2938ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (WSTOPSIG (status) == SIGUSR1); 2948ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 2958ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil static char *debuginfo_path; 2968ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil static const Dwfl_Callbacks offline_callbacks = 2978ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil { 2988ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil .find_debuginfo = dwfl_standard_find_debuginfo, 2998ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil .debuginfo_path = &debuginfo_path, 3008ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil .section_address = dwfl_offline_section_address, 3018ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil .find_elf = find_elf, 3028ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil }; 3038ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil Dwfl *dwfl = dwfl_begin (&offline_callbacks); 3048ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (dwfl); 3058ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3068ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil struct user_regs_struct user_regs; 3078ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs); 308c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 3098ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (l == 0); 3108ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil report_module (dwfl, child, user_regs.rip); 3118ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3128ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil bool ok = dwfl_attach_state (dwfl, EM_NONE, child, &callbacks, NULL); 3138ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (ok); 3148ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3158ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil /* Multiple threads are not handled here. */ 3168ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil int err = dwfl_getthreads (dwfl, thread_callback, NULL); 3178ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (! err); 3188ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3198ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil dwfl_end (dwfl); 3208ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil kill (child, SIGKILL); 3218ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil pid = waitpid (child, &status, 0); 322c801acf1cb6ee95044d11ad8ed8ebf879db0444cMax Filippov assert (errno == 0); 3238ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (pid == child); 3248ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (WIFSIGNALED (status)); 3258ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil assert (WTERMSIG (status) == SIGKILL); 3268ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3278ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil return EXIT_SUCCESS; 3288ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil} 3298ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil 3308ae9bc9d315be6ecbb97dd9754b9d8424b5a70f0Jan Kratochvil#endif /* x86_64 */ 331