summaryrefslogtreecommitdiff
path: root/dwarflint/dwarf_3.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dwarflint/dwarf_3.cc')
-rw-r--r--dwarflint/dwarf_3.cc141
1 files changed, 141 insertions, 0 deletions
diff --git a/dwarflint/dwarf_3.cc b/dwarflint/dwarf_3.cc
new file mode 100644
index 00000000..913029c3
--- /dev/null
+++ b/dwarflint/dwarf_3.cc
@@ -0,0 +1,141 @@
+/* Pedantic checking of DWARF files
+ Copyright (C) 2010 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file 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; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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 this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "dwarf_version-imp.hh"
+#include "dwarf_2.hh"
+#include "dwarf_3.hh"
+#include "../libdw/dwarf.h"
+#include <cassert>
+
+namespace
+{
+ struct dwarf_3_attributes
+ : public attribute_table
+ {
+ dwarf_3_attributes ()
+ {
+ add (location_attribute (DW_AT_location));
+ add (dynval_attribute (DW_AT_byte_size));
+ add (dynval_attribute (DW_AT_bit_offset));
+ add (dynval_attribute (DW_AT_bit_size));
+ add (location_attribute (DW_AT_string_length));
+ add (dynval_attribute (DW_AT_lower_bound));
+ add (location_attribute (DW_AT_return_addr));
+
+ // Note, DWARF 3 claims only a const class for DW_AT_bit_stride,
+ // but from 2.19 it's clear that this is an omission.
+ add (dynval_attribute (DW_AT_bit_stride));
+
+ add (dynval_attribute (DW_AT_upper_bound));
+ add (dynval_attribute (DW_AT_count));
+ add (attribute (DW_AT_data_member_location,
+ dw_class_set (cl_exprloc, cl_constant, cl_loclistptr)));
+ add (location_attribute (DW_AT_frame_base));
+ add (location_attribute (DW_AT_segment));
+ add (location_attribute (DW_AT_static_link));
+ add (location_attribute (DW_AT_use_location));
+ add (location_attribute (DW_AT_vtable_elem_location));
+ add (dynval_attribute (DW_AT_allocated));
+ add (dynval_attribute (DW_AT_associated));
+ add (attribute (DW_AT_data_location, cl_exprloc));
+ add (dynval_attribute (DW_AT_byte_stride));
+ add (addr_attribute (DW_AT_entry_pc));
+ add (flag_attribute (DW_AT_use_UTF8));
+ add (ref_attribute (DW_AT_extension));
+ add (attribute (DW_AT_ranges, cl_rangelistptr));
+ add (attribute (DW_AT_trampoline,
+ dw_class_set (cl_address, cl_flag,
+ cl_reference, cl_string)));
+ add (const_attribute (DW_AT_call_column));
+ add (const_attribute (DW_AT_call_file));
+ add (const_attribute (DW_AT_call_line));
+ add (string_attribute (DW_AT_description));
+ add (const_attribute (DW_AT_binary_scale));
+ add (const_attribute (DW_AT_decimal_scale));
+ add (ref_attribute (DW_AT_small));
+ add (const_attribute (DW_AT_decimal_sign));
+ add (const_attribute (DW_AT_digit_count));
+ add (string_attribute (DW_AT_picture_string));
+ add (flag_attribute (DW_AT_mutable));
+ add (flag_attribute (DW_AT_threads_scaled));
+ add (flag_attribute (DW_AT_explicit));
+ add (ref_attribute (DW_AT_object_pointer));
+ add (const_attribute (DW_AT_endianity));
+ add (flag_attribute (DW_AT_elemental));
+ add (flag_attribute (DW_AT_pure));
+ add (flag_attribute (DW_AT_recursive));
+ }
+ };
+
+ struct dwarf_3_forms
+ : public form_table
+ {
+ dwarf_3_forms ()
+ {
+ add (offset_form (DW_FORM_ref_addr, cl_reference));
+
+ // In DWARF 2 we made all the const forms into various cl_*ptr,
+ // since that's how the standard was worded: it allowed
+ // DW_AT_location to have any constant form. In DWARF 3, only
+ // data4 and data8 are like this. In addition, these two can
+ // also be cl_rangelistptr.
+ typedef preset_form<sc_value,
+ cl_constant, cl_lineptr, cl_loclistptr,
+ cl_macptr, cl_rangelistptr> dw3_data_form;
+
+ add (const_form (DW_FORM_data1, fw_1));
+ add (const_form (DW_FORM_data2, fw_2));
+ add (dw3_data_form (DW_FORM_data4, fw_4));
+ add (dw3_data_form (DW_FORM_data8, fw_8));
+ add (const_form (DW_FORM_sdata, fw_sleb));
+ add (const_form (DW_FORM_udata, fw_uleb));
+ }
+ };
+
+ struct dwarf_3_ext_t
+ : public std_dwarf
+ {
+ dwarf_3_ext_t ()
+ : std_dwarf (dwarf_3_attributes (), dwarf_3_forms ())
+ {}
+
+ dw_class
+ ambiguous_class (__attribute__ ((unused)) form const *form,
+ attribute const *attribute,
+ dw_class_set const &candidates) const
+ {
+ assert (attribute->name () == DW_AT_data_member_location);
+ assert (candidates == dw_class_set (cl_constant, cl_loclistptr));
+ return cl_loclistptr;
+ }
+ };
+}
+
+dwarf_version const *
+dwarf_3_ext ()
+{
+ static dwarf_3_ext_t dw;
+ return &dw;
+}
+
+dwarf_version const *
+dwarf_3 ()
+{
+ static dwarf_version const *dw =
+ dwarf_version::extend (dwarf_2 (), dwarf_3_ext ());
+ return dw;
+}