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