diff options
author | Petr Machata <pmachata@redhat.com> | 2011-03-17 23:28:44 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2011-03-17 23:28:44 +0100 |
commit | 7a1dae978f9c77dca7f3a618226c440b2d6aeefc (patch) | |
tree | 2f3c7028f0cadd636c439246dad24bd03f3590b4 | |
parent | 46bed7782877d07b10801dc4a02ee325f3ccb8ac (diff) |
dwarflint: Support DW_AT_high_pc that is constant, check low_pc <= high_pc
-rw-r--r-- | dwarflint/Makefile.am | 6 | ||||
-rw-r--r-- | dwarflint/check_debug_info.cc | 35 | ||||
-rw-r--r-- | dwarflint/tests/DW_AT_high_pc-relative.bz2 | bin | 0 -> 615 bytes | |||
-rwxr-xr-x | dwarflint/tests/run-DW_AT_high_pc-relative.sh | 36 |
4 files changed, 69 insertions, 8 deletions
diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am index a8560426..ba6d6a8a 100644 --- a/dwarflint/Makefile.am +++ b/dwarflint/Makefile.am @@ -104,7 +104,8 @@ EXTRA_TESTS = tests/run-debug_abbrev-duplicate-attribute.sh \ tests/run-libdl-2.12.so.debug.sh \ tests/run-test-all-dies-it.sh \ tests/run-bad.sh \ - tests/run-check_self_referential_die.sh + tests/run-check_self_referential_die.sh \ + tests/run-DW_AT_high_pc-relative.sh TESTS = $(EXTRA_TESTS) \ tests/test-coverage \ @@ -134,7 +135,8 @@ EXTRA_DIST = $(EXTRA_TESTS) \ tests/garbage-10.bz2 \ tests/garbage-11.bz2 \ tests/garbage-12.bz2 \ - tests/check_self_referential_die.bz2 + tests/check_self_referential_die.bz2 \ + tests/DW_AT_high_pc-relative.bz2 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \ bindir=$(DESTDIR)$(bindir) \ diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index b7e801d6..057dbeae 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -342,6 +342,7 @@ namespace case DW_FORM_data4: case DW_FORM_data8: + case DW_FORM_sec_offset: switch (attribute->name ()) { @@ -666,6 +667,7 @@ namespace uint64_t low_pc = (uint64_t)-1, high_pc = (uint64_t)-1; bool low_pc_relocated = false, high_pc_relocated = false; + bool high_pc_relative = false; GElf_Sym low_pc_symbol_mem, *low_pc_symbol = &low_pc_symbol_mem; GElf_Sym high_pc_symbol_mem, *high_pc_symbol = &high_pc_symbol_mem; @@ -793,6 +795,10 @@ namespace relocatedp = &high_pc_relocated; symbolp = &high_pc_symbol; valuep = &high_pc; + if (cls == cl_constant) + high_pc_relative = true; + else + assert (cls == cl_address); break; case DW_AT_decl_file: @@ -925,6 +931,16 @@ namespace } where.ref = NULL; + if (high_pc != (uint64_t)-1 && low_pc != (uint64_t)-1 + && high_pc_relative) + { + if (high_pc_relocated) + wr_message (where, mc_die_other | mc_impact_2 | mc_reloc) + << "DW_AT_high_pc is a constant (=relative), but is relocated." + << std::endl; + high_pc += low_pc; + } + /* Check PC coverage. */ if (is_cudie && low_pc != (uint64_t)-1) { @@ -936,15 +952,22 @@ namespace if (high_pc != (uint64_t)-1 && low_pc != (uint64_t)-1) { - if (high_pc_relocated != low_pc_relocated) - wr_message (where, cat (mc_die_other, mc_impact_2, mc_reloc)) + if (!high_pc_relative && high_pc_relocated != low_pc_relocated) + wr_message (where, mc_die_other | mc_impact_2 | mc_reloc) << "only one of DW_AT_low_pc and DW_AT_high_pc is relocated." << std::endl; else - check_range_relocations (mc_die_other, &where, - &file, - low_pc_symbol, high_pc_symbol, - "DW_AT_low_pc and DW_AT_high_pc"); + { + if (!high_pc_relative) + check_range_relocations (mc_die_other, &where, + &file, + low_pc_symbol, high_pc_symbol, + "DW_AT_low_pc and DW_AT_high_pc"); + if (low_pc > high_pc) + wr_message (where, mc_die_other | mc_impact_3) + << "DW_AT_low_pc value not below DW_AT_high_pc." + << std::endl; + } } where.ref = &abbrev->where; diff --git a/dwarflint/tests/DW_AT_high_pc-relative.bz2 b/dwarflint/tests/DW_AT_high_pc-relative.bz2 Binary files differnew file mode 100644 index 00000000..d5196652 --- /dev/null +++ b/dwarflint/tests/DW_AT_high_pc-relative.bz2 diff --git a/dwarflint/tests/run-DW_AT_high_pc-relative.sh b/dwarflint/tests/run-DW_AT_high_pc-relative.sh new file mode 100755 index 00000000..e1cffaba --- /dev/null +++ b/dwarflint/tests/run-DW_AT_high_pc-relative.sh @@ -0,0 +1,36 @@ +#! /bin/sh +# Copyright (C) 2011 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils 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; version 2 of the License. +# +# Red Hat 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 Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# <http://www.openinventionnetwork.com>. + +. $srcdir/../tests/test-subr.sh + +srcdir=$srcdir/tests + +# Hand-crafted file that has 0,0 pair in aranges presented before the +# actual end of the table. +testfiles DW_AT_high_pc-relative + +testrun_compare ./dwarflint --check=@low DW_AT_high_pc-relative <<EOF +No errors +EOF |