checks.hh checks_i.hh \
coverage.cc coverage.hh \
cu_coverage.cc cu_coverage.hh cu_coverage_i.hh \
+ die_locus.cc die_locus.hh \
dwarf_2.cc dwarf_2.hh \
dwarf_3.cc dwarf_3.hh \
dwarf_4.cc dwarf_4.hh \
locstats_SOURCES = \
locstats.cc \
+ die_locus.cc die_locus.hh \
files.cc files.hh \
option.cc option.hh option_i.hh \
section_id.cc section_id.hh \
std::string
abbrev_attrib_locus::name () const
{
- assert (_m_name != -1);
- return elfutils::dwarf::attributes::name (_m_name);
+ return pri::attr_name (_m_name);
}
void
wr_error (&where, ": can't read table length.\n");
return false;
}
- if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+ if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
return false;
struct read_ctx sub_ctx;
/* Address size. */
int address_size;
error_code err = read_address_size (&sub_ctx, file->addr_64,
- &address_size, &where);
+ &address_size, where);
if (err != err_ok)
retval = false;
if (err == err_fatal)
while (!read_ctx_eof (&ctx))
{
const unsigned char *cu_begin = ctx.ptr;
- struct where where = WHERE (sec_info, NULL);
uint64_t offset = read_ctx_get_offset (&ctx);
- where_reset_1 (&where, offset);
-
- cu_head head;
- head.offset = offset;
- head.where = where;
+ cu_head head (offset);
/* Reading CU head is a bit tricky, because we don't know if
we have run into (superfluous but allowed) zero padding
if (!read_ctx_need_data (&ctx, 4)
&& read_check_zero_padding (&ctx, &off_start, &off_end))
{
- wr_message_padding_0 (mc_info | mc_header, where,
+ wr_message_padding_0 (mc_info | mc_header, head.where,
off_start, off_end);
break;
}
uint32_t size32;
if (!read_ctx_read_4ubyte (&ctx, &size32))
{
- wr_error (where) << "can't read CU length." << std::endl;
+ wr_error (head.where) << "can't read CU length." << std::endl;
throw check_base::failed ();
}
if (size32 == 0
&& read_check_zero_padding (&ctx, &off_start, &off_end))
{
- wr_message_padding_0 (mc_info | mc_header, where,
+ wr_message_padding_0 (mc_info | mc_header, head.where,
off_start, off_end);
break;
}
Dwarf_Off cu_size;
if (!read_size_extra (&ctx, size32, &cu_size,
- &head.offset_size, &where))
+ &head.offset_size, head.where))
throw check_base::failed ();
if (!read_ctx_need_data (&ctx, cu_size))
{
- wr_error (where)
+ wr_error (head.where)
<< "section doesn't have enough data to read CU of size "
<< cu_size << '.' << std::endl;
throw check_base::failed ();
if (dwarf_version::get (version) == NULL)
{
wr_error (head.where) << "unsupported CU version "
- << version << '.' << std::endl;
+ << version << '.' << std::endl;
throw check_base::failed ();
}
if (version == 2 && head.offset_size == 8) // xxx?
/* Address size. */
error_code err = read_address_size (&ctx, file->addr_64,
- &head.address_size, &head.where);
+ &head.address_size, head.where);
if (err == err_fatal)
throw check_base::failed ();
else if (err == err_nohl)
if (!read_ctx_skip (&ctx, head.size))
{
- wr_error (where) << pri::not_enough ("next CU") << std::endl;
+ wr_error (head.where) << pri::not_enough ("next CU") << std::endl;
throw check_base::failed ();
}
struct value_check_cb_ctx
{
struct read_ctx *const ctx;
- struct where *const where;
+ locus const *where;
struct cu *const cu;
struct ref_record *local_die_refs;
Elf_Data *strings;
uint64_t sibling_addr = 0;
uint64_t die_off, prev_die_off = 0;
struct abbrev *abbrev = NULL;
- struct where where = WHERE (sec_info, NULL);
unsigned long die_count = 0;
int retval = 0;
struct value_check_cb_ctx cb_ctx = {
- ctx, &where, cu,
+ ctx, NULL, cu,
local_die_refs,
strings, strings_coverage,
pc_coverage,
while (!read_ctx_eof (ctx))
{
- where = cu->head->where;
die_off = read_ctx_get_offset (ctx);
/* Shift reported DIE offset by CU offset, to match the way
readelf reports DIEs. */
- where_reset_2 (&where, die_off + cu->head->offset);
+ die_locus where (cu->head->offset + die_off);
+ cb_ctx.where = &where;
uint64_t abbr_code;
if (!checked_read_uleb128 (ctx, &abbr_code, where, "abbrev code"))
return -1;
-#define DEF_PREV_WHERE \
- struct where prev_where = where; \
- where_reset_2 (&prev_where, prev_die_off + cu->head->offset)
+#define DEF_PREV_WHERE die_locus prev_where (cu->head->offset + prev_die_off)
/* Check sibling value advertised last time through the loop. */
if (sibling_addr != 0)
for (struct abbrev_attrib *it = abbrev->attribs;
it->name != 0 || it->form != 0; ++it)
{
- where.ref = &it->where;
+ where.set_attrib_name (it->name);
int form_name = it->form;
// In following, attribute may be NULL, but form never
// field? See check_debug_loc_range::op_read_form
if (!check_location_expression
(ver, file, &block, cu,
- expr_start, reloc, value, &where))
+ expr_start, reloc, value, where))
return -1;
}
else
if (valuep != NULL)
*valuep = value;
}
- where.ref = NULL;
+ where.set_attrib_name (-1);
if (high_pc != (uint64_t)-1 && low_pc != (uint64_t)-1
&& high_pc_relative)
else
{
if (!high_pc_relative)
- check_range_relocations (mc_die_other, &where,
+ check_range_relocations (where, mc_die_other,
&file,
low_pc_symbol, high_pc_symbol,
"DW_AT_low_pc and DW_AT_high_pc");
}
}
- where.ref = &abbrev->where;
-
if (abbrev->has_children)
{
int st = read_die_chain (ver, file, ctx, cu, abbrevs, strings,
}
if (sibling_addr != 0)
- wr_error (where)
+ wr_error (die_locus (cu->head->offset + prev_die_off))
<< "this DIE should have had its sibling at " << pri::hex (sibling_addr)
<< ", but the DIE chain ended." << std::endl;
it != cu_headers.end (); ++it)
{
cu_head const &head = *it;
- where const &where = head.where;
+ cu_locus where = head.where;
{
cu cur;
memset (&cur, 0, sizeof (cur));
if (success)
{
- where wh = WHERE (sec_info, NULL);
+ section_locus wh (sec_info);
if (ctx.ptr != ctx.end)
/* Did we read up everything? */
wr_message (mc_die_other | mc_impact_4, &wh,
#include "check_debug_line_i.hh"
#include "check_debug_aranges_i.hh"
#include "sections_i.hh"
+#include "die_locus.hh"
struct cu_head
{
- uint64_t offset;
+ Dwarf_Off offset;
Dwarf_Off size; // Size of this CU.
Dwarf_Off head_size; // Size from begin to 1st byte of CU.
Dwarf_Off total_size; // size + head_size
- int offset_size; // Offset size in this CU.
- ::where where; // Where this section was defined.
+ int offset_size; // Offset size in this CU.
Dwarf_Off abbrev_offset; // Abbreviation section that this CU uses.
int version; // CU version
int address_size; // Address size in bytes on the target machine.
- cu_head ()
- : offset (0)
+ cu_locus where;
+
+ explicit cu_head (Dwarf_Off a_offset)
+ : offset (a_offset)
, size (0)
, head_size (0)
, total_size (0)
, offset_size (0)
- , where ()
, abbrev_offset (0)
, version (0)
, address_size (0)
+ , where (a_offset)
{}
};
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "check_debug_line.hh"
#include "check_debug_info.hh"
#include "sections.hh"
wr_error (where) << "can't read table length." << std::endl;
throw check_base::failed ();
}
- if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+ if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
throw check_base::failed ();
struct read_ctx sub_ctx;
wr_message (cat | mc_impact_2 | mc_reloc, &where,
": end of address range is relocated, but the beginning wasn't.\n");
else
- check_range_relocations (cat, &where, file,
+ check_range_relocations (where, cat, file,
begin_symbol, end_symbol,
"begin and end address");
}
/* location expression itself */
uint64_t expr_start = read_ctx_get_offset (&ctx);
if (!check_location_expression
- (ver, *file, &ctx, cu, expr_start, &sec->rel, len, &where))
+ (ver, *file, &ctx, cu, expr_start, &sec->rel, len, where))
return false;
uint64_t expr_end = read_ctx_get_offset (&ctx);
if (!overlap
uint64_t init_off,
struct relocation_data *reloc,
size_t length,
- struct where *wh)
+ locus const &loc)
{
struct read_ctx ctx;
if (!read_ctx_init_sub (&ctx, parent_ctx, parent_ctx->ptr,
parent_ctx->ptr + length))
{
- wr_error (wh, PRI_NOT_ENOUGH, "location expression");
+ wr_error (&loc, PRI_NOT_ENOUGH, "location expression");
return false;
}
while (!read_ctx_eof (&ctx))
{
uint64_t opcode_off = read_ctx_get_offset (&ctx) + init_off;
- locexpr_locus where (opcode_off, wh);
+ locexpr_locus where (opcode_off, &loc);
opaddrs.add (opcode_off);
uint8_t opcode;
}
void
-check_range_relocations (enum message_category cat,
- struct where *where,
+check_range_relocations (locus const &loc,
+ enum message_category cat,
struct elf_file const *file,
GElf_Sym *begin_symbol,
GElf_Sym *end_symbol,
if (begin_symbol != NULL
&& end_symbol != NULL
&& begin_symbol->st_shndx != end_symbol->st_shndx)
- wr_message (cat | mc_impact_2 | mc_reloc, where,
+ wr_message (cat | mc_impact_2 | mc_reloc, &loc,
": %s relocated against different sections (%s and %s).\n",
description,
file->sec[begin_symbol->st_shndx].name,
uint64_t init_off,
struct relocation_data *reloc,
size_t length,
- struct where *wh);
+ locus const &loc);
-void check_range_relocations (enum message_category cat,
- struct where *where,
+void check_range_relocations (locus const &loc,
+ enum message_category cat,
struct elf_file const *file,
GElf_Sym *begin_symbol,
GElf_Sym *end_symbol,
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "check_debug_pub.hh"
#include "check_debug_info.hh"
#include "sections.hh"
wr_error (&where, ": can't read table length.\n");
return false;
}
- if (!read_size_extra (&ctx, size32, &size, &offset_size, &where))
+ if (!read_size_extra (&ctx, size32, &size, &offset_size, where))
return false;
{
decl_file = attrs.find (DW_AT_decl_file);
if (decl_column != attrs.end () && decl_line == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has decl_column, but NOT decl_line" << std::endl;
if (decl_line != attrs.end () && decl_file == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has decl_line, but NOT decl_file" << std::endl;
if (decl_file != attrs.end () && decl_line == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has decl_file, but NOT decl_line" << std::endl;
call_file = attrs.find (DW_AT_call_file);
if (call_column != attrs.end () && call_line == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has call_column, but NOT call_line" << std::endl;
if (call_line != attrs.end () && call_file == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has call_line, but NOT call_file" << std::endl;
if (call_file != attrs.end () && call_line == attrs.end ())
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " has call_file, but NOT call_line" << std::endl;
}
if (! found)
- wr_message (to_where (entry), mc_impact_3 | mc_acc_suboptimal)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
<< " " << dwarf::attributes::name (pc.first) << "=0x"
r += reason;
}
- wr_error (to_where (*a_d_it))
+ wr_error (die_locus (*a_d_it))
<< "A check failed: " << (_m_cd->name () ?: "(nil)")
<< r << std::endl;
}
varinfo &i = old->second;
if ((declaration && i.decl != children.end ())
|| (!declaration && i.def != children.end ()))
- wr_message (to_where (*jt), mc_impact_3 | mc_die_other)
+ wr_message (die_locus (*jt), mc_impact_3 | mc_die_other)
.id (descriptor ())
<< "Re" << (declaration ? "declaration" : "definition")
<< " of variable '" << name << "', originally seen at "
<< pri::ref (declaration ? *i.decl : *i.def)
<< '.' << std::endl;
else
- wr_message (to_where (*jt), mc_impact_3 | mc_die_other)
+ wr_message (die_locus (*jt), mc_impact_3 | mc_die_other)
.id (descriptor ())
<< "Found "
<< (declaration ? "declaration" : "definition")
if ((at2 = m.find ((*at).first)) != m.end ()
&& ! duplicate_ok (entry.tag (), at2->first, attr.first,
referree.tag (), at2->second == (*at).second))
- wr_message (to_where (entry), mc_impact_3 | mc_acc_bloat | mc_die_rel)
+ wr_message (die_locus (entry), mc_impact_3 | mc_acc_bloat | mc_die_rel)
.id (descriptor ())
<< dwarf::tags::name (entry.tag ())
<< " attribute " << dwarf::attributes::name (at2->first)
void operator () (dwarf::compile_unit const &cu,
dwarf::debug_info_entry const &parent)
{
- struct where where = WHERE (sec_info, NULL);
- where_reset_1 (&where, cu.offset ());
- where_reset_2 (&where, parent.offset ());
+ die_locus where (parent);
int parent_tag = parent.tag ();
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- wr_error (WHERE (sec_info, NULL))
+ wr_error (section_locus (sec_info))
<< "Exception while checking expected trees: " << exc.what ()
<< std::endl;
throw check_base::failed ();
&& entry.tag () != DW_TAG_union_type)
|| attrs.find (DW_AT_name) != attrs.end ()))
{
- wr_message (to_where (entry),
+ wr_message (die_locus (entry),
mc_impact_3 | mc_acc_suboptimal | mc_die_other)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
if (attrs.find (DW_AT_declaration) == attrs.end ()
&& is_external (it))
{
- wr_message (to_where (entry),
+ wr_message (die_locus (entry),
mc_impact_3 | mc_acc_suboptimal | mc_die_other)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
{
// Global symbol in symbol table, not marked external.
// Always bad.
- wr_message (to_where (entry),
+ wr_message (die_locus (entry),
mc_impact_3 | mc_acc_suboptimal | mc_die_other)
.id (descriptor ())
<< elfutils::dwarf::tags::name (entry.tag ())
try
{
- struct where where_ref = WHERE (sec_info, NULL);
struct where where_ar = WHERE (sec_aranges, NULL);
- where_ar.ref = &where_ref;
struct where where_r = WHERE (sec_ranges, NULL);
- where_r.ref = &where_ref;
char buf[128];
const dwarf::aranges_map &aranges = dw.aranges ();
i != aranges.end (); ++i)
{
const dwarf::compile_unit &cu = i->first;
- where_reset_1 (&where_ref, 0);
- where_reset_2 (&where_ref, cu.offset ());
+ die_locus where_ref (cu);
+ where_ar.ref = &where_ref;
+ where_r.ref = &where_ref;
std::set<dwarf::ranges::key_type>
cu_aranges = i->second,
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- wr_error (WHERE (sec_info, NULL))
+ wr_error (section_locus (sec_info))
<< "Exception while checking matching ranges: " << exc.what ()
<< std::endl;
throw check_base::failed ();
static void recursively_validate (dwarf::compile_unit const &cu,
dwarf::debug_info_entry const &die,
ranges_t const &ranges,
- where const &wh_parent);
+ locus const &wh_parent);
public:
static checkdescriptor const *descriptor () {
class dwarf::compile_units_type const &cus = dw.compile_units ();
ranges_t r;
r.push_back (std::make_pair (0, -1));
- where wh = WHERE (sec_info, NULL);
+ section_locus wh (sec_info);
for (dwarf::compile_units_type::const_iterator it = cus.begin ();
it != cus.end (); ++it)
recursively_validate (*it, *it, r, wh);
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- wr_error (WHERE (sec_info, NULL))
+ wr_error (section_locus (sec_info))
<< "Exception while checking ranges out of scope: " << exc.what ()
<< std::endl;
throw check_base::failed ();
(dwarf::compile_unit const &cu,
dwarf::debug_info_entry const &die,
ranges_t const &ranges,
- where const &wh_parent)
+ locus const &wh_parent)
{
- where wh = WHERE (sec_info, NULL);
- where_reset_1 (&wh, cu.offset ());
- where_reset_2 (&wh, die.offset ());
+ die_locus wh (die);
::Dwarf_Addr low_pc = 0;
::Dwarf_Addr high_pc = ::noaddr;
{
dwarf::debug_info_entry ref = *val.reference ();
if (ref.identity () == entry.identity ())
- wr_message (to_where (entry),
+ wr_message (die_locus (entry),
mc_impact_3 | mc_acc_suboptimal | mc_die_rel)
.id (descriptor ())
<< dwarf::tags::name (entry.tag ())
bool
read_size_extra (struct read_ctx *ctx, uint32_t size32, uint64_t *sizep,
- int *offset_sizep, struct where *where)
+ int *offset_sizep, locus const &loc)
{
if (size32 == DWARF3_LENGTH_64_BIT)
{
if (!read_ctx_read_8ubyte (ctx, sizep))
{
- wr_error (*where) << "can't read 64bit CU length.\n";
+ wr_error (loc) << "can't read 64bit CU length.\n";
return false;
}
}
else if (size32 >= DWARF3_LENGTH_MIN_ESCAPE_CODE)
{
- wr_error (*where)
+ wr_error (loc)
<< "unrecognized CU length escape value: " << size32 << ".\n";
return false;
}
}
error_code
-read_address_size (struct read_ctx *ctx,
- bool addr_64,
- int *address_sizep,
- struct where const *where)
+read_address_size (struct read_ctx *ctx, bool addr_64,
+ int *address_sizep, locus const &loc)
{
uint8_t address_size;
if (!read_ctx_read_ubyte (ctx, &address_size))
{
- wr_error (*where) << "can't read address size.\n";
+ wr_error (loc) << "can't read address size.\n";
return err_fatal;
}
{
/* Keep going. Deduce the address size from ELF header, and try
to parse it anyway. */
- wr_error (*where) << "invalid address size: " << (int)address_size
- << " (only 4 or 8 allowed).\n";
+ wr_error (loc) << "invalid address size: " << (int)address_size
+ << " (only 4 or 8 allowed).\n";
address_size = addr_64 ? 8 : 4;
ret = err_nohl;
}
else if ((address_size == 8) != addr_64)
{
/* Keep going, we may still be able to parse it. */
- wr_error (*where) << "CU reports address size of " << address_size
- << " in " << (addr_64 ? 64 : 32) << "-bit ELF.\n";
+ wr_error (loc) << "CU reports address size of " << address_size
+ << " in " << (addr_64 ? 64 : 32) << "-bit ELF.\n";
ret = err_nohl;
}
};
bool read_size_extra (read_ctx *ctx, uint32_t size32, uint64_t *sizep,
- int *offset_sizep, where *where);
+ int *offset_sizep, locus const &loc);
/// Read address size and return it via address_sizep and return 0.
/// Address size may be 4 or 8; for other values it's set depending or
/// addr_64, and err_nohl is returned.
-error_code read_address_size (read_ctx *ctx,
- bool addr_64,
- int *address_sizep,
- where const *where);
+error_code read_address_size (read_ctx *ctx, bool addr_64,
+ int *address_sizep, locus const &loc);
bool checked_read_uleb128 (read_ctx *ctx, uint64_t *ret,
locus const &loc, const char *what);
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "cu_coverage.hh"
#include "check_debug_info.hh"
#include "check_debug_loc_range.hh"
--- /dev/null
+/*
+ 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>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "die_locus.hh"
+#include "pri.hh"
+
+std::string
+cu_locus::format (bool brief) const
+{
+ std::stringstream ss;
+ if (!brief)
+ ss << section_name[sec_info] << ": ";
+ ss << "CU " << _m_offset;
+ return ss.str ();
+}
+
+std::string
+die_locus::format (bool brief) const
+{
+ std::stringstream ss;
+ if (!brief)
+ ss << section_name[sec_info] << ": ";
+
+ ss << "DIE 0x" << std::hex << _m_offset;
+
+ if (_m_attrib_name != -1)
+ ss << ", attr. " << pri::attr_name (_m_attrib_name);
+
+ return ss.str ();
+}
+
--- /dev/null
+/*
+ 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>. */
+
+#ifndef _DWARFLINT_DIE_LOCUS_H_
+#define _DWARFLINT_DIE_LOCUS_H_
+
+#include "where.h"
+#include "../libdw/c++/dwarf"
+
+class cu_locus
+ : public clonable_locus<cu_locus>
+{
+ Dwarf_Off _m_offset;
+public:
+ explicit cu_locus (Dwarf_Off offset)
+ : _m_offset (offset)
+ {}
+
+ std::string format (bool brief = false) const;
+};
+
+class die_locus
+ : public clonable_locus<die_locus>
+{
+ Dwarf_Off _m_offset;
+ int _m_attrib_name;
+
+public:
+ explicit die_locus (Dwarf_Off offset, int attrib_name = -1)
+ : _m_offset (offset)
+ , _m_attrib_name (attrib_name)
+ {}
+
+ template <class T>
+ explicit die_locus (T const &die, int attrib_name = -1)
+ : _m_offset (die.offset ())
+ , _m_attrib_name (attrib_name)
+ {}
+
+ void
+ set_attrib_name (int attrib_name)
+ {
+ _m_attrib_name = attrib_name;
+ }
+
+ std::string format (bool brief = false) const;
+};
+
+#endif /* _DWARFLINT_DIE_LOCUS_H_ */
#endif
#include "checks.hh"
+#include "check_debug_info.hh"
+
#include "../libdw/c++/dwarf"
#include "../libdwfl/libdwfl.h"
{}
};
-template <class T>
-inline where
-to_where (T const &die)
-{
- where ret = WHERE (sec_info, NULL);
- where_reset_1 (&ret, 0);
- where_reset_2 (&ret, die.offset ());
- return ret;
-}
-
#endif//DWARFLINT_CHECKS_HIGH_HH
}
catch (::error const &e)
{
- struct where where = WHERE (sec_info, NULL);
- where_reset_1 (&where, it.cu ().offset ());
- where_reset_2 (&where, die.offset ());
- std::cerr << "error: " << where << ": "
+ std::cerr << "error: " << die_locus (die) << ": "
<< e.what () << '.' << std::endl;
continue;
}
Network licensing program, please visit www.openinventionnetwork.com
<http://www.openinventionnetwork.com>. */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "lowlevel_checks.hh"
#include "sections.hh"
#include "check_debug_info.hh"
return os << "[" << pri::addr (obj.start)
<< ", " << pri::addr (obj.end) << ")";
}
+
+std::string
+pri::attr_name (int name)
+{
+ assert (name != -1);
+ return elfutils::dwarf::attributes::name (name);
+}
friend std::ostream &operator << (std::ostream &os, range const &obj);
};
std::ostream &operator << (std::ostream &os, range const &obj);
+
+ std::string attr_name (int name);
}
#endif//DWARFLINT_PRI_H
: (is_rela ? sizeof (Elf32_Rela) : sizeof (Elf32_Rel));
size_t count = reldata->d_size / entrysize;
- struct where parent = WHERE (sec->id, NULL);
+ section_locus parent (sec->id);
for (unsigned i = 0; i < count; ++i)
{
testrun_compare ./dwarflint empty-1 <<EOF
warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
warning: .debug_line: table 0: no CU uses this line table.
-error: .debug_info: DIE 0x29 (abbr. 0x11, attr. decl_file): references .debug_line table, but CU DIE lacks DW_AT_stmt_list.
+error: .debug_info: DIE 0x29, attr. decl_file: references .debug_line table, but CU DIE lacks DW_AT_stmt_list.
EOF
testrun_compare ./dwarflint garbage-1 <<EOF
testrun_compare ./dwarflint garbage-2 <<EOF
error: .debug_info: CU 0: toplevel DIE must be either compile_unit or partial_unit.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
EOF
testrun_compare ./dwarflint --check=@low garbage-3 <<EOF
testrun_compare ./dwarflint garbage-4 <<EOF
error: .debug_info: DIE 0x6c: this DIE claims that its sibling is 0x80000085 but it's actually 0x85.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
EOF
testrun_compare ./dwarflint garbage-5 <<EOF
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
error: .debug_line: offset 0x3e: not enough data to read an opcode of length 5.
-error: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): unresolved reference to .debug_line table 0x0.
+error: .debug_info: DIE 0xb, attr. stmt_list: unresolved reference to .debug_line table 0x0.
EOF
testrun_compare ./dwarflint garbage-6 <<EOF
EOF
testrun_compare ./dwarflint garbage-8 <<EOF
-error: .debug_info: DIE 0x6c (abbr. 0x3b, attr. sibling): has a value of 0.
+error: .debug_info: DIE 0x6c, attr. sibling: has a value of 0.
error: .debug_info: DIE 0x6c: This DIE had children, but no DW_AT_sibling attribute.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
EOF
testrun_compare ./dwarflint garbage-9 <<EOF
-error: .debug_info: DIE 0x84 (abbr. 0x59, attr. type): invalid reference outside the CU: 0xef00ab.
+error: .debug_info: DIE 0x84, attr. type: invalid reference outside the CU: 0xef00ab.
error: .debug_info: DIE 0x6c: is the last sibling in chain, but has a DW_AT_sibling attribute.
-error: .debug_info: DIE 0xab (abbr. offset 113): DIE chain not terminated with null entry.
+error: .debug_info: DIE 0xab: DIE chain not terminated with null entry.
EOF
testrun_compare ./dwarflint garbage-10 <<EOF
-warning: .rela 0xc of .debug_info: DIE 0xb (abbr. 0x0, attr. producer): relocation formed using STT_SECTION symbol with non-zero value.
-error: .rela 0x11 of .debug_info: DIE 0xb (abbr. 0x0, attr. comp_dir): couldn't obtain symbol #7208969: invalid section index.
+warning: .rela 0xc of .debug_info: DIE 0xb, attr. producer: relocation formed using STT_SECTION symbol with non-zero value.
+error: .rela 0x11 of .debug_info: DIE 0xb, attr. comp_dir: couldn't obtain symbol #7208969: invalid section index.
warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
EOF
error: .rela 0x2500 of .debug_info: invalid relocation 2560 (<INVALID RELOC>).
error: .rela 0x3600 of .debug_info: invalid relocation 256 (<INVALID RELOC>).
warning: .debug_info: CU 0: abbrev table offset seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. producer): strp seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. comp_dir): strp seems to lack a relocation
-warning: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): data4 seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. producer: strp seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. comp_dir: strp seems to lack a relocation
+warning: .debug_info: DIE 0xb, attr. stmt_list: data4 seems to lack a relocation
warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
error: .debug_line: table 0: header claims that it has a size of 542, but in fact it has a size of 30.
-error: .debug_info: DIE 0xb (abbr. 0x0, attr. stmt_list): unresolved reference to .debug_line table 0x0.
+error: .debug_info: DIE 0xb, attr. stmt_list: unresolved reference to .debug_line table 0x0.
EOF
testrun_compare ./dwarflint garbage-12 <<EOF
public:
section_formatters ()
{
- add (sec_info, ".debug_info", "CU %"PRId64, "DIE %#"PRIx64);
-
add (sec_aranges, ".debug_aranges",
"table %"PRId64, "arange %#"PRIx64);
{
assert (sec != sec_abbrev);
assert (sec != sec_str);
+ assert (sec != sec_info);
where::formatter const *fmt = wf_for_section (sec);
return where (fmt, next);
}