diff options
Diffstat (limited to 'src/tests/addrcfi.c')
-rw-r--r-- | src/tests/addrcfi.c | 226 |
1 files changed, 0 insertions, 226 deletions
diff --git a/src/tests/addrcfi.c b/src/tests/addrcfi.c deleted file mode 100644 index 8a2d126c..00000000 --- a/src/tests/addrcfi.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Test program for CFI handling. - Copyright (C) 2009-2010, 2013 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#include <config.h> -#include <assert.h> -#include <inttypes.h> -#include ELFUTILS_HEADER(dwfl) -#include <dwarf.h> -#include <argp.h> -#include <stdio.h> -#include <stdio_ext.h> -#include <locale.h> -#include <stdlib.h> -#include <string.h> - -#include "../libdw/known-dwarf.h" - -static const char * -op_name (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE) -#define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_OP -#undef ONE_KNOWN_DW_OP -#undef ONE_KNOWN_DW_OP_DESC - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - -static void -print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias) -{ - if (result < 0) - printf ("indeterminate (%s)\n", dwarf_errmsg (-1)); - else if (nops == 0) - printf ("%s\n", ops == NULL ? "same_value" : "undefined"); - else - { - printf ("%s expression:", result == 0 ? "location" : "value"); - for (size_t i = 0; i < nops; ++i) - { - printf (" %s", op_name(ops[i].atom)); - if (ops[i].number2 == 0) - { - if (ops[i].atom == DW_OP_addr) - printf ("(%#" PRIx64 ")", ops[i].number + bias); - else if (ops[i].number != 0) - printf ("(%" PRId64 ")", ops[i].number); - } - else - printf ("(%" PRId64 ",%" PRId64 ")", - ops[i].number, ops[i].number2); - } - puts (""); - } -} - -struct stuff -{ - Dwarf_Frame *frame; - Dwarf_Addr bias; -}; - -static int -print_register (void *arg, - int regno, - const char *setname, - const char *prefix, - const char *regname, - int bits __attribute__ ((unused)), - int type __attribute__ ((unused))) -{ - struct stuff *stuff = arg; - - printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname); - - Dwarf_Op ops_mem[2]; - Dwarf_Op *ops; - size_t nops; - int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops); - print_detail (result, ops, nops, stuff->bias); - - return DWARF_CB_OK; -} - -static int -handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi, - GElf_Addr pc, struct stuff *stuff) -{ - if (cfi == NULL) - { - printf ("handle_cfi no CFI (%s): %s\n", which, dwarf_errmsg (-1)); - return -1; - } - - int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame); - if (result != 0) - { - printf ("dwarf_cfi_addrframe (%s): %s\n", which, dwarf_errmsg (-1)); - return 1; - } - - Dwarf_Addr start = pc; - Dwarf_Addr end = pc; - bool signalp; - int ra_regno = dwarf_frame_info (stuff->frame, &start, &end, &signalp); - if (ra_regno >= 0) - { - start += stuff->bias; - end += stuff->bias; - } - - printf ("%s has %#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n", - which, pc, start, end); - - if (ra_regno < 0) - printf ("\treturn address register unavailable (%s)\n", - dwarf_errmsg (0)); - else - printf ("\treturn address in reg%u%s\n", - ra_regno, signalp ? " (signal frame)" : ""); - - // Point cfa_ops to dummy to match print_detail expectations. - // (nops == 0 && cfa_ops != NULL => "undefined") - Dwarf_Op dummy; - Dwarf_Op *cfa_ops = &dummy; - size_t cfa_nops; - result = dwarf_frame_cfa (stuff->frame, &cfa_ops, &cfa_nops); - - printf ("\tCFA "); - print_detail (result, cfa_ops, cfa_nops, stuff->bias); - - (void) dwfl_module_register_names (dwfl_addrmodule (dwfl, pc), - &print_register, stuff); - - return 0; -} - -static int -handle_address (GElf_Addr pc, Dwfl *dwfl) -{ - Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc); - - struct stuff stuff; - return (handle_cfi (dwfl, ".eh_frame", - dwfl_module_eh_cfi (mod, &stuff.bias), pc, &stuff) - & handle_cfi (dwfl, ".debug_frame", - dwfl_module_dwarf_cfi (mod, &stuff.bias), pc, &stuff)); -} - -int -main (int argc, char *argv[]) -{ - int remaining; - - /* Set locale. */ - (void) setlocale (LC_ALL, ""); - - Dwfl *dwfl = NULL; - (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl); - assert (dwfl != NULL); - - int result = 0; - - /* Now handle the addresses. In case none are given on the command - line, read from stdin. */ - if (remaining == argc) - { - /* We use no threads here which can interfere with handling a stream. */ - (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); - - char *buf = NULL; - size_t len = 0; - while (!feof_unlocked (stdin)) - { - if (getline (&buf, &len, stdin) < 0) - break; - - char *endp; - uintmax_t addr = strtoumax (buf, &endp, 0); - if (endp != buf) - result |= handle_address (addr, dwfl); - else - result = 1; - } - - free (buf); - } - else - { - do - { - char *endp; - uintmax_t addr = strtoumax (argv[remaining], &endp, 0); - if (endp != argv[remaining]) - result |= handle_address (addr, dwfl); - else - result = 1; - } - while (++remaining < argc); - } - - dwfl_end (dwfl); - - return result; -} |