diff options
| author | Roland McGrath <[email protected]> | 2005-08-27 10:33:26 +0000 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2005-08-27 10:33:26 +0000 |
| commit | 71e15a01742e5d5de9c6260d4526146be54e5a8a (patch) | |
| tree | 2796d8ea1fa5580b4e381881314fdad12904635f /tests/funcscopes.c | |
| parent | 995f92d7d696930e2cbf08427d028d948e8c5180 (diff) | |
libdw/
2005-08-27 Roland McGrath <[email protected]>
* dwarf_getscopes.c (dwarf_getscopes): Rewritten using
__libdw_visit_scopes.
* dwarf_getscopes_die.c: New file.
* Makefile.am (libdw_a_SOURCES): Add it.
* libdw.h: Declare dwarf_getscopes_die.
* libdw.map: Bump to 0.115 and add it.
* libdw_visit_scopes.c (__libdw_visit_scopes): Pass a struct
containing a DIE and its parent pointer, instead of just Dwarf_Die.
Take two functions for both preorder and postorder visitors.
* libdwP.h: Update decl.
(struct Dwarf_Die_Chain): New type.
* dwarf_func_inline.c: Update uses.
* dwarf_diename.c (dwarf_diename): Use dwarf_attr_integrate.
Add INTDEF.
* libdwP.h: Add INTDECL.
* dwarf_func_name.c (dwarf_func_name): Use dwarf_diename.
src/
2005-08-27 Roland McGrath <[email protected]>
* addr2line.c (dwarf_diename_integrate): Function removed.
(print_dwarf_function): Use plain dwarf_diename.
tests/
2005-08-27 Roland McGrath <[email protected]>
* run-funcscopes.sh: New file.
* testfile25.bz2: New data file.
* Makefile.am (TESTS, EXTRA_DIST): Add them.
2005-08-26 Roland McGrath <[email protected]>
* addrscopes.c (dwarf_diename_integrate): Removed.
(print_vars, handle_address): Use plain dwarf_diename.
2005-08-25 Roland McGrath <[email protected]>
* funcscopes.c: New file.
* Makefile.am (noinst_PROGRAMS): Add it.
(funcscopes_LDADD): New variable.
* run-addrscopes.sh: Add another case.
* testfile24.bz2: New data file.
* Makefile.am (EXTRA_DIST): Add it.
* addrscopes.c (handle_address): Take new argument IGNORE_INLINES,
pass it to dwarf_getscopes.
(main): Pass it, true when '=' follows an address.
Diffstat (limited to 'tests/funcscopes.c')
| -rw-r--r-- | tests/funcscopes.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/tests/funcscopes.c b/tests/funcscopes.c new file mode 100644 index 00000000..a74e8d87 --- /dev/null +++ b/tests/funcscopes.c @@ -0,0 +1,192 @@ +/* Test program for dwarf_getscopes. + Copyright (C) 2005 Red Hat, Inc. + + This program is Open Source software; you can redistribute it and/or + modify it under the terms of the Open Software License version 1.0 as + published by the Open Source Initiative. + + You should have received a copy of the Open Software License along + with this program; if not, you may obtain a copy of the Open Software + License version 1.0 from http://www.opensource.org/licenses/osl.php or + by writing the Open Source Initiative c/o Lawrence Rosen, Esq., + 3001 King Ranch Road, Ukiah, CA 95482. */ + +#include <config.h> +#include <assert.h> +#include <inttypes.h> +#include <libdwfl.h> +#include <dwarf.h> +#include <argp.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <locale.h> +#include <stdlib.h> +#include <error.h> +#include <string.h> +#include <fnmatch.h> + + +static void +paddr (const char *prefix, Dwarf_Addr addr, Dwfl_Line *line) +{ + const char *src; + int lineno, linecol; + if (line != NULL + && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, + NULL, NULL)) != NULL) + { + if (linecol != 0) + printf ("%s%#" PRIx64 " (%s:%d:%d)", + prefix, addr, src, lineno, linecol); + else + printf ("%s%#" PRIx64 " (%s:%d)", + prefix, addr, src, lineno); + } + else + printf ("%s%#" PRIx64, prefix, addr); +} + + +static void +print_vars (unsigned int indent, Dwarf_Die *die) +{ + Dwarf_Die child; + if (dwarf_child (die, &child) == 0) + do + switch (dwarf_tag (&child)) + { + case DW_TAG_variable: + case DW_TAG_formal_parameter: + printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "", + dwarf_diename (&child), + (uint64_t) dwarf_dieoffset (&child)); + break; + default: + break; + } + while (dwarf_siblingof (&child, &child) == 0); + + Dwarf_Attribute attr_mem; + Dwarf_Die origin; + if (dwarf_hasattr (die, DW_AT_abstract_origin) + && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem), + &origin) != NULL + && dwarf_child (&origin, &child) == 0) + do + switch (dwarf_tag (&child)) + { + case DW_TAG_variable: + case DW_TAG_formal_parameter: + printf ("%*s%s (abstract)\n", indent, "", + dwarf_diename (&child)); + break; + default: + break; + } + while (dwarf_siblingof (&child, &child) == 0); +} + + +#define INDENT 4 + +struct args +{ + Dwfl *dwfl; + Dwarf_Die *cu; + Dwarf_Addr dwbias; + char **argv; +}; + +static int +handle_function (Dwarf_Func *func, void *arg) +{ + struct args *a = arg; + + const char *name = dwarf_func_name (func); + char **argv = a->argv; + if (argv[0] != NULL) + { + bool match; + do + match = fnmatch (*argv, name, 0) == 0; + while (!match && *++argv); + if (!match) + return 0; + } + + Dwarf_Die funcdie_mem; + Dwarf_Die *funcdie = dwarf_func_die (func, &funcdie_mem); + assert (funcdie == &funcdie_mem); + + Dwarf_Die *scopes; + int n = dwarf_getscopes_die (funcdie, &scopes); + if (n <= 0) + error (EXIT_FAILURE, 0, "dwarf_getscopes_die: %s", dwarf_errmsg (-1)); + else + { + Dwarf_Addr start, end; + const char *fname; + const char *modname = dwfl_module_info (dwfl_cumodule (a->cu), NULL, + &start, &end, + NULL, NULL, + &fname, NULL); + if (modname == NULL) + error (EXIT_FAILURE, 0, "dwfl_module_info: %s", dwarf_errmsg (-1)); + if (modname[0] == '\0') + modname = fname; + printf ("%s: %#" PRIx64 " .. %#" PRIx64 "\n", modname, start, end); + + unsigned int indent = 0; + while (n-- > 0) + { + Dwarf_Die *const die = &scopes[n]; + + indent += INDENT; + printf ("%*s%s (%#x)", indent, "", + dwarf_diename (die) ?: "<unnamed>", + dwarf_tag (die)); + + Dwarf_Addr lowpc, highpc; + if (dwarf_lowpc (die, &lowpc) == 0 + && dwarf_highpc (die, &highpc) == 0) + { + lowpc += a->dwbias; + highpc += a->dwbias; + Dwfl_Line *loline = dwfl_getsrc (a->dwfl, lowpc); + Dwfl_Line *hiline = dwfl_getsrc (a->dwfl, highpc); + paddr (": ", lowpc, loline); + if (highpc != lowpc) + paddr (" .. ", lowpc, hiline == loline ? NULL : hiline); + } + puts (""); + + print_vars (indent + INDENT, die); + } + } + + return 0; +} + + +int +main (int argc, char *argv[]) +{ + int remaining; + + /* Set locale. */ + (void) setlocale (LC_ALL, ""); + + struct args a = { .dwfl = NULL, .cu = NULL }; + + (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, + &a.dwfl); + assert (a.dwfl != NULL); + a.argv = &argv[remaining]; + + int result = 0; + + while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL) + dwarf_getfuncs (a.cu, &handle_function, &a, 0); + + return result; +} |
