1/* Test program for getting symbol table from vdso module. 2 Copyright (C) 2014 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18#include <config.h> 19#include <assert.h> 20#include <errno.h> 21#include <error.h> 22#include <inttypes.h> 23#include <stdio.h> 24#include <string.h> 25#include <sys/types.h> 26#include <unistd.h> 27#include ELFUTILS_HEADER(dwfl) 28 29#ifndef __linux__ 30int 31main (int argc __attribute__ ((unused)), char **argv) 32{ 33 printf ("Getting the vdso is unsupported.\n"); 34 return 77; 35} 36#else /* __linux__ */ 37static int vdso_syms = 0; 38 39static int 40module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)), 41 const char *name, Dwarf_Addr start __attribute__((unused)), 42 void *arg __attribute__((unused))) 43{ 44 /* We can only recognize the vdso by inspecting the "magic name". */ 45 printf ("module name: %s\n", name); 46 if (strncmp ("[vdso: ", name, 7) == 0) 47 { 48 vdso_syms = dwfl_module_getsymtab (mod); 49 printf ("vdso syms: %d\n", vdso_syms); 50 if (vdso_syms < 0) 51 error (2, 0, "dwfl_module_getsymtab: %s", dwfl_errmsg (-1)); 52 53 for (int i = 0; i < vdso_syms; i++) 54 { 55 GElf_Sym sym; 56 GElf_Addr addr; 57 const char *sname = dwfl_module_getsym_info (mod, i, &sym, &addr, 58 NULL, NULL, NULL); 59 assert (sname != NULL); 60 printf ("%d: '%s' %" PRIx64 " (%" PRIx64 ")\n", 61 i, sname, sym.st_value, addr); 62 } 63 } 64 65 return DWARF_CB_OK; 66} 67 68int 69main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) 70{ 71 static char *debuginfo_path; 72 static const Dwfl_Callbacks proc_callbacks = 73 { 74 .find_debuginfo = dwfl_standard_find_debuginfo, 75 .debuginfo_path = &debuginfo_path, 76 77 .find_elf = dwfl_linux_proc_find_elf, 78 }; 79 Dwfl *dwfl = dwfl_begin (&proc_callbacks); 80 if (dwfl == NULL) 81 error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); 82 83 /* Take our parent as "arbitrary" process to inspect. */ 84 pid_t pid = getppid(); 85 86 int result = dwfl_linux_proc_report (dwfl, pid); 87 if (result < 0) 88 error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1)); 89 else if (result > 0) 90 error (2, result, "dwfl_linux_proc_report"); 91 92 /* Also explicitly attach for older kernels (cannot read vdso otherwise). */ 93 result = dwfl_linux_proc_attach (dwfl, pid, false); 94 if (result < 0) 95 error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1)); 96 else if (result > 0) 97 error (2, result, "dwfl_linux_proc_attach"); 98 99 if (dwfl_report_end (dwfl, NULL, NULL) != 0) 100 error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1)); 101 102 if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0) 103 error (1, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1)); 104 105 /* No symbols is ok, then we haven't seen the vdso at all on this arch. */ 106 return vdso_syms >= 0 ? 0 : -1; 107} 108 109#endif /* ! __linux__ */ 110