blob: ea80091cdc2d173e345e91ad44e4cf5c149224b7 [file] [log] [blame]
/* -*- C++ -*- interfaces for libdw.
Copyright (C) 2009-2011 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 either
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at
your option) any later version
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at
your option) any later version
or both in parallel, as here.
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 copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "dwarf"
using namespace std;
using namespace elfutils;
#define VS(what) (1U << dwarf::VS_##what)
/* Return a bitmask of value spaces expected for this attribute of this tag.
Primarily culled from the DWARF 3 spec: 7.5.4, Figure 20. Updated to
DWARF 4, plus some GNU additions. */
static unsigned int
expected_value_space (int attr, int tag)
{
switch (attr)
{
case DW_AT_sibling:
case DW_AT_common_reference:
case DW_AT_containing_type:
case DW_AT_default_value:
case DW_AT_abstract_origin:
case DW_AT_base_types:
case DW_AT_friend:
case DW_AT_priority:
case DW_AT_specification:
case DW_AT_type:
case DW_AT_use_location:
case DW_AT_data_location:
case DW_AT_extension:
case DW_AT_small:
case DW_AT_object_pointer:
case DW_AT_namelist_item:
return VS(reference);
case DW_AT_location:
case DW_AT_string_length:
case DW_AT_return_addr:
case DW_AT_frame_base:
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_vtable_elem_location:
case DW_AT_GNU_call_site_value:
case DW_AT_GNU_call_site_data_value:
case DW_AT_GNU_call_site_target:
case DW_AT_GNU_call_site_target_clobbered:
return VS(location);
case DW_AT_data_member_location:
return VS(location) | VS(constant);
case DW_AT_name:
switch (tag)
{
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
return VS(source_file);
default:
return VS(identifier);
}
case DW_AT_ordering:
case DW_AT_language:
case DW_AT_visibility:
case DW_AT_inline:
case DW_AT_accessibility:
case DW_AT_address_class:
case DW_AT_calling_convention:
case DW_AT_encoding:
case DW_AT_identifier_case:
case DW_AT_virtuality:
case DW_AT_endianity:
return VS(dwarf_constant);
case DW_AT_byte_size:
case DW_AT_byte_stride:
case DW_AT_bit_size:
case DW_AT_bit_offset:
case DW_AT_bit_stride:
case DW_AT_lower_bound:
case DW_AT_upper_bound:
case DW_AT_count:
case DW_AT_allocated:
case DW_AT_associated:
return VS(reference) | VS(constant) | VS(location); // XXX non-loc expr
case DW_AT_stmt_list:
return VS(lineptr);
case DW_AT_macro_info:
return VS(macptr);
case DW_AT_ranges:
return VS(rangelistptr);
case DW_AT_low_pc:
case DW_AT_high_pc:
case DW_AT_entry_pc:
return VS(address);
case DW_AT_discr:
return VS(reference);
case DW_AT_discr_value:
return VS(constant);
case DW_AT_discr_list:
return VS(discr_list);
case DW_AT_import:
return VS(reference);
case DW_AT_comp_dir:
return VS(source_file);
case DW_AT_const_value:
return VS(constant) | VS(string) | VS(address);
case DW_AT_is_optional:
case DW_AT_prototyped:
case DW_AT_artificial:
case DW_AT_declaration:
case DW_AT_external:
case DW_AT_variable_parameter:
case DW_AT_use_UTF8:
case DW_AT_mutable:
case DW_AT_main_subprogram:
case DW_AT_threads_scaled:
case DW_AT_explicit:
case DW_AT_elemental:
case DW_AT_pure:
case DW_AT_recursive:
case DW_AT_const_expr:
case DW_AT_enum_class:
case DW_AT_GNU_tail_call:
case DW_AT_GNU_all_tail_call_sites:
case DW_AT_GNU_all_call_sites:
case DW_AT_GNU_all_source_call_sites:
case DW_AT_GNU_vector:
return VS(flag);
case DW_AT_producer:
return VS(string);
case DW_AT_start_scope:
case DW_AT_data_bit_offset:
return VS(constant);
case DW_AT_binary_scale:
case DW_AT_decimal_scale:
case DW_AT_decimal_sign:
case DW_AT_digit_count:
return VS(constant);
case DW_AT_decl_file:
case DW_AT_call_file:
return VS(source_file);
case DW_AT_decl_line:
case DW_AT_call_line:
return VS(source_line);
case DW_AT_decl_column:
case DW_AT_call_column:
return VS(source_column);
case DW_AT_trampoline:
return VS(address) | VS(flag) | VS(reference) | VS(string);
case DW_AT_description:
case DW_AT_picture_string:
return VS(string);
case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name:
case DW_AT_GNU_template_name:
return VS(identifier);
/* XXX Note these are not the same, the first is related to C++
ODR (one-definition-rule checking), the later to .debug_type
references. Should be its own class really. */
case DW_AT_GNU_odr_signature:
return VS(constant);
case DW_AT_signature:
return VS(reference);
}
return 0;
}