From 31bf2445a311a748188d2760263e191da515a320 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 17:12:58 +0100 Subject: Don't emit two error messages for invalid attribute form - and add space to "complain" error message --- dwarflint/check_debug_abbrev.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dwarflint/check_debug_abbrev.cc b/dwarflint/check_debug_abbrev.cc index d727328c..8d413fc6 100644 --- a/dwarflint/check_debug_abbrev.cc +++ b/dwarflint/check_debug_abbrev.cc @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2009, 2010 Red Hat, Inc. + Copyright (C) 2009, 2010, 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 @@ -117,7 +117,7 @@ namespace { wr_error (*where) << "attribute " << *attribute << " with " << qualifier - << (indirect ? " indirect" : "") << " form" + << (indirect ? " indirect" : "") << " form " << *form << '.' << std::endl; } @@ -405,9 +405,7 @@ namespace (ver, attrib_form, attribute, &where, false); if (form == NULL) { - wr_error (where) - << "invalid or unknown form " << pri::hex (attrib_form) - << '.' << std::endl; + // Error message is emitted in check_form. failed = true; continue; } -- cgit v1.2.3 From 89d49fd98e52938636e23dbfc4b709d40e83a0d2 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 17:20:01 +0100 Subject: Add license boilerplate to src/dwarfstrings.* - took the boilerplate from readelf.c, since that's where the code originated --- src/dwarfstrings.c | 25 +++++++++++++++++++++++++ src/dwarfstrings.h | 25 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/dwarfstrings.c b/src/dwarfstrings.c index 7ef2a35c..6feba59f 100644 --- a/src/dwarfstrings.c +++ b/src/dwarfstrings.c @@ -1,3 +1,28 @@ +/* Copyright (C) 1999-2011 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper , 1999. + + 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 + . */ + #ifdef HAVE_CONFIG_H # include #endif diff --git a/src/dwarfstrings.h b/src/dwarfstrings.h index a38c2748..c77a1907 100644 --- a/src/dwarfstrings.h +++ b/src/dwarfstrings.h @@ -1,3 +1,28 @@ +/* Copyright (C) 1999-2011 Red Hat, Inc. + This file is part of Red Hat elfutils. + Written by Ulrich Drepper , 1999. + + 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 + . */ + #ifndef DWARFSTRINGS_H #define DWARFSTRINGS_H 1 -- cgit v1.2.3 From c9ce330e45f7ff68658f67abd57103ead8bb2f55 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 20:44:34 +0100 Subject: dwarflint: form::width takes cu_head, not cu argument - also the argument may be NULL, in which case the width may end up being fw_unknown --- dwarflint/check_debug_info.cc | 11 ++++++----- dwarflint/check_debug_loc_range.cc | 4 ++-- dwarflint/dwarf_version.cc | 28 ++++++++++++++++++++-------- dwarflint/dwarf_version.hh | 6 +++--- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index 63ea4c43..a89d90d2 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -1,6 +1,6 @@ /* Routines related to .debug_info. - Copyright (C) 2009, 2010 Red Hat, Inc. + Copyright (C) 2009, 2010, 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 @@ -629,7 +629,8 @@ namespace && ver->form_class (form, attribute) == cl_indirect) { uint64_t value; - if (!read_sc_value (&value, form->width (cu), ctx, &where)) + if (!read_sc_value (&value, form->width (cu->head), + ctx, &where)) return -1; form_name = value; form = check_debug_abbrev::check_form @@ -684,7 +685,7 @@ namespace cl_rangelistptr); if (cls != max_dw_class && ref_classes.test (cls)) - if (form->width (cu) == fw_8 + if (form->width (cu->head) == fw_8 && cu->head->offset_size == 4) wr_error (where) << "reference attribute with form \"" @@ -773,7 +774,7 @@ namespace read_ctx block; storage_class_t storclass = form->storage_class (); - if (!read_generic_value (ctx, form->width (cu), storclass, + if (!read_generic_value (ctx, form->width (cu->head), storclass, &where, &value, &block)) { // Note that for fw_uleb and fw_sleb we report the @@ -814,7 +815,7 @@ namespace if (attribute != NULL) { - form_width_t width = form->width (cu); + form_width_t width = form->width (cu->head); relocate_one (&file, reloc, rel, width, &value, &where, reloc_target (form, attribute), symbolp); } diff --git a/dwarflint/check_debug_loc_range.cc b/dwarflint/check_debug_loc_range.cc index f3b5f5a4..e64b07c9 100644 --- a/dwarflint/check_debug_loc_range.cc +++ b/dwarflint/check_debug_loc_range.cc @@ -1,6 +1,6 @@ /* Routines related to .debug_loc and .debug_range. - Copyright (C) 2009, 2010 Red Hat, Inc. + Copyright (C) 2009, 2010, 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 @@ -791,7 +791,7 @@ namespace storage_class_t storclass = form->storage_class (); assert (storclass != sc_string); - if (!read_generic_value (ctx, form->width (cu), storclass, + if (!read_generic_value (ctx, form->width (cu->head), storclass, where, valuep, NULL)) { wr_error (*where) diff --git a/dwarflint/dwarf_version.cc b/dwarflint/dwarf_version.cc index 9b4ebaaf..e611a833 100644 --- a/dwarflint/dwarf_version.cc +++ b/dwarflint/dwarf_version.cc @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2009,2010 Red Hat, Inc. + Copyright (C) 2009,2010,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 @@ -27,6 +27,10 @@ // version. Apart from standardized DWARF formats, e.g. DWARF3+GNU is // a version of its own. +#ifdef HAVE_CONFIG_H +# include +#endif + #include "dwarf_version.hh" #include "dwarf_2.hh" #include "dwarf_3.hh" @@ -89,14 +93,22 @@ dwarf_version::form_class (form const *form, attribute const *attribute) const } form_width_t -form::width (cu const *cu) const +form::width (cu_head const *cu_head) const { - if (_m_width == fw_offset) - return static_cast (cu->head->offset_size); - else if (_m_width == fw_address) - return static_cast (cu->head->address_size); - else - return static_cast (_m_width); + switch (_m_width) + { + case fw_offset: + case fw_address: + if (unlikely (cu_head == NULL)) + return fw_unknown; + if (_m_width == fw_offset) + return static_cast (cu_head->offset_size); + else + return static_cast (cu_head->address_size); + + default: + return static_cast (_m_width); + } } std::ostream & diff --git a/dwarflint/dwarf_version.hh b/dwarflint/dwarf_version.hh index f3bee10b..1d397817 100644 --- a/dwarflint/dwarf_version.hh +++ b/dwarflint/dwarf_version.hh @@ -1,6 +1,6 @@ /* Dwarf version tables. - Copyright (C) 2009, 2010 Red Hat, Inc. + Copyright (C) 2009, 2010, 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 @@ -122,8 +122,8 @@ public: /// /// Return value is never fw_offset or fw_address. These get /// resolved to fw_4 or fw_8 depending on corresponding value in - /// CU->head. - form_width_t width (cu const *cu) const; + /// CU_HEAD. + form_width_t width (cu_head const *cu_head) const; /// Return storage class of given form. Closely related to width. storage_class_t -- cgit v1.2.3 From 92cf230319c6f079498b2912484ef074a5d84c07 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 21:31:14 +0100 Subject: dwarflint: DW_AT_GNU_odr_signature is 8-byte constant - make dwarf_version::form_allowed virtual. Override in dwarf_gnu to force the right exact --- dwarflint/dwarf_4.cc | 5 ++--- dwarflint/dwarf_gnu.cc | 22 ++++++++++++++++------ dwarflint/dwarf_version.hh | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/dwarflint/dwarf_4.cc b/dwarflint/dwarf_4.cc index 812eef62..3beb9b65 100644 --- a/dwarflint/dwarf_4.cc +++ b/dwarflint/dwarf_4.cc @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2010 Red Hat, Inc. + Copyright (C) 2010, 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 @@ -67,8 +67,7 @@ namespace add (exprloc_form (DW_FORM_exprloc)); add (flag_form (DW_FORM_flag_present, fw_0)); - // xxx This actually needs to be something like ref8_form. This - // and DW_AT_GNU_odr_signature. + // http://wiki.dwarfstd.org/index.php?title=COMDAT_Type_Sections add (ref_form (DW_FORM_ref_sig8, fw_8)); // In DWARF 2 we claim that blocks are exprloc forms (see diff --git a/dwarflint/dwarf_gnu.cc b/dwarflint/dwarf_gnu.cc index 36c826c2..df3e85b1 100644 --- a/dwarflint/dwarf_gnu.cc +++ b/dwarflint/dwarf_gnu.cc @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2010 Red Hat, Inc. + Copyright (C) 2010, 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 @@ -63,12 +63,10 @@ namespace add (const_attribute (DW_AT_GNU_shared_locks_required)); // Contains a shallower 8-byte signature of the type described - // in the type unit. We encode it the same way as - // DW_AT_signature, which AFAICT is just a standardized name of - // DW_AT_GNU_odr_signature. + // in the type unit. This is nominally a const_attribute, but + // we do the checking ourselves in form_allowed. // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo - // http://wiki.dwarfstd.org/index.php?title=COMDAT_Type_Sections - add (ref_attribute (DW_AT_GNU_odr_signature)); + add (const_attribute (DW_AT_GNU_odr_signature)); add (string_attribute (DW_AT_GNU_template_name)); // xxx ??? } @@ -80,6 +78,18 @@ namespace dwarf_gnu_ext_t () : std_dwarf (dwarf_gnu_attributes (), form_table ()) {} + + virtual bool + form_allowed (int attribute_name, int form_name) const + { + if (attribute_name == DW_AT_GNU_odr_signature) + { + form const *f = get_form (form_name); + return f->classes ()[cl_constant] && f->width (NULL) == fw_8; + } + else + return std_dwarf::form_allowed (attribute_name, form_name); + } }; } diff --git a/dwarflint/dwarf_version.hh b/dwarflint/dwarf_version.hh index 1d397817..c8a0e6a3 100644 --- a/dwarflint/dwarf_version.hh +++ b/dwarflint/dwarf_version.hh @@ -186,7 +186,7 @@ public: /// Figure out whether, in given DWARF version, given attribute is /// allowed to have given form. - bool form_allowed (int attribute_name, int form_name) const; + virtual bool form_allowed (int attribute_name, int form_name) const; /// Answer a class of FORM given ATTRIBUTE as a context. If there's /// exactly one candidate class, that's the one answered. If -- cgit v1.2.3 From 5982e1cc64499959e2e55458387fe1d4add24e15 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 21:52:44 +0100 Subject: dwarflint: Allow per-form configuration of CU bitness where form may appear --- dwarflint/check_debug_info.cc | 16 ++++++++++------ dwarflint/dwarf_2.cc | 4 ++-- dwarflint/dwarf_version-imp.hh | 7 ++++--- dwarflint/dwarf_version.cc | 8 ++++++-- dwarflint/dwarf_version.hh | 24 ++++++++++++++++++++---- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index a89d90d2..69d8fdd3 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -685,12 +685,16 @@ namespace cl_rangelistptr); if (cls != max_dw_class && ref_classes.test (cls)) - if (form->width (cu->head) == fw_8 - && cu->head->offset_size == 4) - wr_error (where) - << "reference attribute with form \"" - << pri::form (form_name) << "\" in 32-bit CU." - << std::endl; + { + form_bitness_t bitness = form->bitness (); + if ((bitness == fb_32 && cu->head->offset_size == 8) + || (bitness == fb_64 && cu->head->offset_size == 4)) + wr_error (where) + << "reference attribute with form \"" + << pri::form (form_name) << "\" in " + << (8 * cu->head->offset_size) << "-bit CU." + << std::endl; + } /* Setup pointer checking. */ switch (cls) diff --git a/dwarflint/dwarf_2.cc b/dwarflint/dwarf_2.cc index c39eca6f..f3c23a24 100644 --- a/dwarflint/dwarf_2.cc +++ b/dwarflint/dwarf_2.cc @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2010 Red Hat, Inc. + Copyright (C) 2010, 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 @@ -148,7 +148,7 @@ namespace add (ref_form (DW_FORM_ref1, fw_1)); add (ref_form (DW_FORM_ref2, fw_2)); add (ref_form (DW_FORM_ref4, fw_4)); - add (ref_form (DW_FORM_ref8, fw_8)); + add (ref_form (DW_FORM_ref8, fw_8, fb_64)); add (ref_form (DW_FORM_ref_udata, fw_uleb)); add (string_form (DW_FORM_string)); diff --git a/dwarflint/dwarf_version-imp.hh b/dwarflint/dwarf_version-imp.hh index 4f00c7c8..10cbc616 100644 --- a/dwarflint/dwarf_version-imp.hh +++ b/dwarflint/dwarf_version-imp.hh @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2010 Red Hat, Inc. + Copyright (C) 2010, 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 @@ -49,8 +49,9 @@ template struct preset_form : public form { - preset_form (int a_name, form_width_t a_width) - : form (a_name, dw_class_set (Classes...), a_width, StorClass) + preset_form (int a_name, form_width_t a_width, + form_bitness_t a_bitness = fb_any) + : form (a_name, dw_class_set (Classes...), a_width, StorClass, a_bitness) {} }; diff --git a/dwarflint/dwarf_version.cc b/dwarflint/dwarf_version.cc index e611a833..819f8106 100644 --- a/dwarflint/dwarf_version.cc +++ b/dwarflint/dwarf_version.cc @@ -58,19 +58,23 @@ dw_class_set::dw_class_set (dw_class a, dw_class b, dw_class c, } form::form (int a_name, dw_class_set a_classes, - form_width_t a_width, storage_class_t a_storclass) + form_width_t a_width, storage_class_t a_storclass, + form_bitness_t a_bitness) : _m_name (a_name) , _m_classes (a_classes) , _m_width (a_width) , _m_storclass (a_storclass) + , _m_bitness (a_bitness) {} form::form (int a_name, dw_class_set a_classes, - form_width_special_t a_width, storage_class_t a_storclass) + form_width_special_t a_width, storage_class_t a_storclass, + form_bitness_t a_bitness) : _m_name (a_name) , _m_classes (a_classes) , _m_width (a_width) , _m_storclass (a_storclass) + , _m_bitness (a_bitness) {} dw_class diff --git a/dwarflint/dwarf_version.hh b/dwarflint/dwarf_version.hh index c8a0e6a3..f7a1df5d 100644 --- a/dwarflint/dwarf_version.hh +++ b/dwarflint/dwarf_version.hh @@ -85,19 +85,29 @@ enum storage_class_t sc_string, }; +enum form_bitness_t + { + fb_any, ///< Form is allowed in all CUs + fb_32, ///< Form is allowed only in 32-bit CUs + fb_64, ///< Form is allowed only in 64-bit CUs + }; + class form { int const _m_name; dw_class_set const _m_classes; int const _m_width; storage_class_t const _m_storclass; + form_bitness_t _m_bitness; public: - form (int a_name, dw_class_set a_classes, - form_width_t a_width, storage_class_t a_storclass); + form (int name, dw_class_set classes, + form_width_t width, storage_class_t storclass, + form_bitness_t bitness = fb_any); - form (int a_name, dw_class_set a_classes, - form_width_special_t a_width, storage_class_t a_storclass); + form (int name, dw_class_set classes, + form_width_special_t width, storage_class_t storclass, + form_bitness_t bitness = fb_any); int name () const @@ -131,6 +141,12 @@ public: { return _m_storclass; } + + form_bitness_t + bitness () const + { + return _m_bitness; + } }; std::ostream &operator << (std::ostream &os, form const &obj); -- cgit v1.2.3 From aa23bd349dd79ff5bba7e1d313e206cf73ecb0cc Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Wed, 23 Feb 2011 22:56:45 +0100 Subject: Handle DW_AT_linkage_name in dwarf_attr_string and dwarf-knowledge --- libdw/c++/dwarf-knowledge.cc | 1 + src/dwarfstrings.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libdw/c++/dwarf-knowledge.cc b/libdw/c++/dwarf-knowledge.cc index 5fdf123e..53cf1a17 100644 --- a/libdw/c++/dwarf-knowledge.cc +++ b/libdw/c++/dwarf-knowledge.cc @@ -151,6 +151,7 @@ expected_value_space (int attr, int tag) case DW_AT_picture_string: return VS(string); + case DW_AT_linkage_name: case DW_AT_MIPS_linkage_name: return VS(identifier); diff --git a/src/dwarfstrings.c b/src/dwarfstrings.c index 6feba59f..b340f026 100644 --- a/src/dwarfstrings.c +++ b/src/dwarfstrings.c @@ -233,6 +233,7 @@ dwarf_attr_string (unsigned int attrnum) [DW_AT_elemental] = "elemental", [DW_AT_pure] = "pure", [DW_AT_recursive] = "recursive", + [DW_AT_linkage_name] = "linkage_name", }; const unsigned int nknown_attrs = (sizeof (known_attrs) / sizeof (known_attrs[0])); -- cgit v1.2.3