/* Test program for dwarf_lowpc and dwarf_highpc Copyright (C) 2012 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 . */ #include #include #include #include ELFUTILS_HEADER(dwfl) #include #include #include #include #include #include #include #include #include struct args { Dwfl *dwfl; Dwarf_Die *cu; Dwarf_Addr dwbias; char **argv; const char *file; }; static struct args *args; static void fail(Dwarf_Off off, const char *name, const char *msg) { printf("%s: [%" PRIx64 "] '%s' %s\n", args->file, off, name, msg); exit(-1); } static int handle_die (Dwarf_Die *die, void *arg) { args = arg; Dwarf_Off off = dwarf_dieoffset (die); const char *name = dwarf_diename (die); if (name == NULL) fail (off, "", "die without a name"); Dwarf_Addr lowpc = 0; Dwarf_Addr highpc = 0; if (dwarf_lowpc (die, &lowpc) != 0 && dwarf_hasattr (die, DW_AT_low_pc)) fail (off, name, "has DW_AT_low_pc but dwarf_lowpc fails"); if (dwarf_highpc (die, &highpc) != 0 && dwarf_hasattr (die, DW_AT_high_pc)) fail (off, name, "has DW_AT_high_pc but dwarf_highpc fails"); /* GCC < 4.7 had a bug where no code CUs got a highpc == lowpc. Allow that, because it is not the main purpose of this test. */ if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_hasattr (die, DW_AT_high_pc) && highpc <= lowpc && ! (dwarf_tag (die) == DW_TAG_compile_unit && highpc == lowpc)) { printf("lowpc: %" PRIx64 ", highpc: %" PRIx64 "lx\n", lowpc, highpc); fail (off, name, "highpc <= lowpc"); } 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) { a.file = dwarf_diename (a.cu); handle_die (a.cu, &a); dwarf_getfuncs (a.cu, &handle_die, &a, 0); } dwfl_end (a.dwfl); return result; }