summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2011-03-17 23:28:44 +0100
committerPetr Machata <pmachata@redhat.com>2011-03-17 23:28:44 +0100
commit7a1dae978f9c77dca7f3a618226c440b2d6aeefc (patch)
tree2f3c7028f0cadd636c439246dad24bd03f3590b4
parent46bed7782877d07b10801dc4a02ee325f3ccb8ac (diff)
dwarflint: Support DW_AT_high_pc that is constant, check low_pc <= high_pc
-rw-r--r--dwarflint/Makefile.am6
-rw-r--r--dwarflint/check_debug_info.cc35
-rw-r--r--dwarflint/tests/DW_AT_high_pc-relative.bz2bin0 -> 615 bytes
-rwxr-xr-xdwarflint/tests/run-DW_AT_high_pc-relative.sh36
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
new file mode 100644
index 00000000..d5196652
--- /dev/null
+++ b/dwarflint/tests/DW_AT_high_pc-relative.bz2
Binary files differ
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