dwarflint/messages.cc dwarflint/messages.h \
dwarflint/where.c dwarflint/where.h \
dwarflint/config.cc dwarflint/config.h \
- dwarflint/checks.cc dwarflint/checks.hh \
+ dwarflint/checks.hh \
dwarflint/checks-low.cc dwarflint/checks-low.hh \
dwarflint/addr-record.cc dwarflint/addr-record.h \
dwarflint/reloc.cc dwarflint/reloc.h \
/* Abbreviation code. */
if (!checked_read_uleb128 (&ctx, &abbr_code, &where, "abbrev code"))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
/* Note: we generally can't tell the difference between
empty table and (excessive) padding. But NUL byte(s)
/* Abbreviation tag. */
uint64_t abbr_tag;
if (!checked_read_uleb128 (&ctx, &abbr_tag, &where, "abbrev tag"))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
if (abbr_tag > DW_TAG_hi_user)
{
std::stringstream ss;
ss << ": invalid abbrev tag 0x" << std::hex << abbr_tag << '.';
wr_error (&where, "%s\n", ss.str ().c_str ());
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
cur->tag = (typeof (cur->tag))abbr_tag;
if (!read_ctx_read_ubyte (&ctx, &has_children))
{
wr_error (&where, ": can't read abbrev has_children.\n");
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
if (has_children != DW_CHILDREN_no
{
wr_error (&where,
": invalid has_children value 0x%x.\n", cur->has_children);
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
cur->has_children = has_children == DW_CHILDREN_yes;
/* Load attribute name and form. */
if (!checked_read_uleb128 (&ctx, &attrib_name, &where,
"attribute name"))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
if (!checked_read_uleb128 (&ctx, &attrib_form, &where,
"attribute form"))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
null_attrib = attrib_name == 0 && attrib_form == 0;
std::stringstream ss;
ss << ": invalid name 0x" << std::hex << attrib_name << '.';
wr_error (&where, "%s\n", ss.str ().c_str ());
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
if (!attrib_form_valid (attrib_form))
std::stringstream ss;
ss << ": invalid form 0x" << std::hex << attrib_form << '.';
wr_error (&where, "%s\n", ss.str ().c_str ());
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
}
if (!check_line_structural (&_m_sec->file,
&_m_sec->sect,
&line_tables))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
check_debug_info *info = NULL;
info = lint.toplev_check (info);
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- throw check_base::failed
- (std::string ("Error while checking expected trees: ")
- + exc.what () + ".\n");
+ wr_error (WHERE (sec_info, NULL))
+ << "Exception while checking expected trees: " << exc.what ()
+ << std::endl;
+ throw check_base::failed ();
}
}
: highlevel_check<check_matching_ranges> (lint)
{
if (be_tolerant || be_gnu)
- throw check_base::unscheduled;
+ throw check_base::unscheduled ();
lint.check<check_debug_ranges> ();
lint.check<check_debug_aranges> ();
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- throw check_base::failed
- (std::string ("Error while checking matching ranges:")
- + exc.what () + ".\n");
+ wr_error (WHERE (sec_info, NULL))
+ << "Exception while checking matching ranges: " << exc.what ()
+ << std::endl;
+ throw check_base::failed ();
}
}
// XXX more specific class when <dwarf> has it
catch (std::runtime_error &exc)
{
- throw check_base::failed
- (std::string ("Error while checking range out of scope: ")
- + exc.what () + ".\n");
+ wr_error (WHERE (sec_info, NULL))
+ << "Exception while checking ranges out of scope: " << exc.what ()
+ << std::endl;
+ throw check_base::failed ();
}
}
, dw (_m_handle)
{
if (!do_high_level)
- throw check_base::unscheduled;
+ throw check_base::unscheduled ();
}
~highlevel_check ()
#include "checks-low.hh"
#include "low.h"
+#include "config.h"
#include <map>
#include <sstream>
#include <cstring>
free (file.sec);
}
+namespace
+{
+ message_category
+ secid_to_cat (section_id secid)
+ {
+ switch (secid)
+ {
+ case sec_info: return mc_info;
+ case sec_abbrev: return mc_abbrevs;
+ case sec_aranges: return mc_aranges;
+ case sec_str: return mc_strings;
+ case sec_line: return mc_line;
+ case sec_loc: return mc_loc;
+ case sec_ranges: return mc_ranges;
+
+ case sec_pubnames:
+ case sec_pubtypes:
+ return mc_pubtables;
+
+ case sec_rel:
+ case sec_rela:
+ return mc_reloc;
+
+ // xxx don't have one
+ case sec_mac:
+ case sec_invalid:
+ case sec_locexpr:
+ case rel_value:
+ case rel_address:
+ case rel_exec:
+ break;
+ };
+ std::stringstream ss;
+ ss << "Couldn't convert secid " << secid << " to mc.";
+ throw std::runtime_error (ss.str ());
+ }
+}
sec &
section_base::get_sec_or_throw (section_id secid)
{
if (sec *s = sections->file.debugsec[secid])
return *s;
- where wh = WHERE (secid, NULL);
- std::stringstream ss;
- ss << where_fmt (&wh) << ": data not found.";
- throw check_base::failed (ss.str ());
+ if (!tolerate_nodebug)
+ wr_message (WHERE (secid, NULL),
+ cat (mc_impact_4, mc_acc_suboptimal, mc_elf,
+ secid_to_cat (secid)))
+ << ": data not found." << std::endl;
+
+ throw check_base::failed ();
}
section_base::section_base (dwarflint &lint, section_id secid)
_m_sec_str->sect.data, &cu_cov);
if (chain == NULL)
- throw check_base::failed (""); // xxx
+ throw check_base::failed ();
for (cu *cu = chain; cu != NULL; cu = cu->next)
cus.push_back (*cu);
&_m_sec_ranges->sect,
&_m_cus->cus.front (),
&_m_cus->cu_cov))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
check_debug_aranges::check_debug_aranges (dwarflint &lint)
&_m_sec_aranges->sect,
info != NULL ? &info->cus.front () : NULL,
cov))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
check_debug_loc::check_debug_loc (dwarflint &lint)
&_m_sec_loc->sect,
&_m_cus->cus.front (),
NULL))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
namespace
if (!check_pub_structural (&_m_sec->file,
&_m_sec->sect,
&_m_cus->cus.front ()))
- throw check_base::failed (""); //xxx
+ throw check_base::failed ();
}
};
+++ /dev/null
-#include "checks.hh"
-check_base::failed check_base::unscheduled ("the check is not scheduled");
#ifndef DWARFLINT_CHECKS_HH
#define DWARFLINT_CHECKS_HH
-#include <stdexcept>
#include <string>
-#include <iostream>
#include "where.h"
#include "dwarflint.hh"
struct check_base
{
- struct failed
- : public std::runtime_error
- {
- failed (std::string const &msg)
- : std::runtime_error (msg)
- {}
- };
-
- static failed unscheduled;
+ struct failed {};
+ struct unscheduled: public failed {};
};
template<class T>
}
};
+template <class T>
+T *
+dwarflint::check ()
+{
+ void const *key = T::key ();
+ check_map::iterator it = _m_checks.find (key);
+
+ T *c;
+ if (it != _m_checks.end ())
+ {
+ c = static_cast <T *> (it->second);
+
+ // We already tried to do the check, but failed.
+ if (c == NULL)
+ throw check_base::failed ();
+ }
+ else
+ {
+ // Put a marker there saying that we tried to do the check, but
+ // it failed.
+ if (!_m_checks.insert (std::make_pair (key, (T *)0)).second)
+ throw std::runtime_error ("duplicate key");
+
+ // Now do the check.
+ c = new T (*this);
+
+ // On success, put the actual check object there instead of the
+ // marker.
+ _m_checks[key] = c;
+ }
+ return c;
+}
+
template <class T>
inline T *
dwarflint::toplev_check (__attribute__ ((unused)) T *tag)
}
catch (check_base::failed const &f)
{
- std::cout << f.what () << std::endl;
return NULL;
}
}
dwarflint (Elf *elf);
Elf *elf () { return _m_elf; }
- template <class T>
- T *
- check ()
- {
- void const *key = T::key ();
- check_map::iterator it = _m_checks.find (key);
- T *c;
- if (it != _m_checks.end ())
- c = static_cast <T *> (it->second);
- else
- {
- c = new T (*this);
- if (!_m_checks.insert (std::make_pair (key, c)).second)
- throw std::runtime_error ("duplicate key");
- }
- return c;
- }
+ template <class T> T *check ();
template <class T>
T *