readelf and tests were using hard coded string tables to produce DWARF string constants. Use the known-dwarf macros to redefine these and reduce code. Technique comes from dwarf branch dwarfstrings.c.
Signed-off-by: Mark Wielaard mjw@redhat.com --- libdw/ChangeLog | 6 + libdw/Makefile.am | 4 +- libdw/dwarf.h | 4 +- src/ChangeLog | 35 ++ src/readelf.c | 1108 +++++++++++----------------------------- tests/ChangeLog | 11 + tests/allregs.c | 34 +- tests/run-readelf-dwz-multi.sh | 4 +- tests/show-die-info.c | 221 ++------- 9 files changed, 394 insertions(+), 1033 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 572252d..89009f0 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,9 @@ +2012-08-16 Mark Wielaard mjw@redhat.com + + * Makefile.am (EXTRA_DIST): Add known-dwarf.h. + * dwarf.h (DW_LANG_Go): Update comment. + (DW_LANG_Mips_Assembler): Likewise. + 2012-06-27 Mark Wielaard mjw@redhat.com
* dwarf.h: Add DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index e1fcef0..c6ac264 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 2002-2010 Red Hat, Inc. +## Copyright (C) 2002-2010, 2012 Red Hat, Inc. ## This file is part of elfutils. ## ## This file is free software; you can redistribute it and/or modify @@ -133,6 +133,6 @@ libdw_a_LIBADD = $(addprefix ../libdwfl/,$(shell $(AR) t ../libdwfl/libdwfl.a)) noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \ dwarf_sig8_hash.h cfi.h encoded-value.h
-EXTRA_DIST = libdw.map +EXTRA_DIST = libdw.map known-dwarf.h
MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so.$(VERSION) diff --git a/libdw/dwarf.h b/libdw/dwarf.h index 81bc7fe..41cae5b 100644 --- a/libdw/dwarf.h +++ b/libdw/dwarf.h @@ -581,10 +581,10 @@ enum DW_LANG_UPC = 0x0012, /* Unified Parallel C */ DW_LANG_D = 0x0013, /* D */ DW_LANG_Python = 0x0014, /* Python */ - DW_LANG_Go = 0x0016, /* Google's Go (provisionally in DWARF5) */ + DW_LANG_Go = 0x0016, /* Go */
DW_LANG_lo_user = 0x8000, - DW_LANG_Mips_Assembler = 0x8001, + DW_LANG_Mips_Assembler = 0x8001, /* Assembler */ DW_LANG_hi_user = 0xffff };
diff --git a/src/ChangeLog b/src/ChangeLog index 294e31b..725554d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,38 @@ +2012-08-16 Mark Wielaard mjw@redhat.com + + * readelf.c (dwarf_tag_name): Renamed from dwarf_tag_string. + Uses new dwarf_tag_string or adds ??? or lo_user+%#x when + appropriate. + (dwarf_attr_name): Likewise. + (dwarf_form_name): Likewise. + (dwarf_lang_name): Likewise. + (dwarf_inline_name): Likewise. + (dwarf_encoding_name): Likewise. + (dwarf_access_name): Likewise. + (dwarf_visibility_name): Likewise. + (dwarf_virtuality_name): Likewise. + (dwarf_identifier_case_name): Likewise. + (dwarf_calling_convention_name): Likewise. + (dwarf_ordering_name): Likewise. + (dwarf_discr_list_name): Likewise. + (print_ops): Remove KNOWN. Use dwarf_locexpr_opcode_string. + (attr_callback): Call new dwarf_foobar_name instead of old + dwarf_foobar_string functions. + (dwarf_tag_string): New function using known-dwarf.h macros. + (dwarf_attr_string): Likewise. + (dwarf_form_string): Likewise. + (dwarf_lang_string): Likewise. + (dwarf_inline_string): Likewise. + (dwarf_encoding_string): Likewise. + (dwarf_access_string): Likewise. + (dwarf_visibility_string): Likewise. + (dwarf_virtuality_string): Likewise. + (dwarf_identifier_case_string): Likewise. + (dwarf_calling_convention_string): Likewise. + (dwarf_ordering_string): Likewise. + (dwarf_discr_list_string): Likewise. + (dwarf_locexpr_opcode_string): Likewise. + 2012-06-27 Mark Wielaard mjw@redhat.com
* readelf.c (dwarf_form_string): Handle DW_FORM_GNU_ref_alt and diff --git a/src/readelf.c b/src/readelf.c index 36724a7..dc49669 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -51,6 +51,8 @@ #include "../libdwfl/libdwflP.h" #include "../libdw/memory-access.h"
+#include "../libdw/known-dwarf.h" +
/* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); @@ -3184,539 +3186,58 @@ format_dwarf_addr (Dwfl_Module *dwflmod, static const char * dwarf_tag_string (unsigned int tag) { - static const char *const known_tags[] = - { - [DW_TAG_array_type] = "array_type", - [DW_TAG_class_type] = "class_type", - [DW_TAG_entry_point] = "entry_point", - [DW_TAG_enumeration_type] = "enumeration_type", - [DW_TAG_formal_parameter] = "formal_parameter", - [DW_TAG_imported_declaration] = "imported_declaration", - [DW_TAG_label] = "label", - [DW_TAG_lexical_block] = "lexical_block", - [DW_TAG_member] = "member", - [DW_TAG_pointer_type] = "pointer_type", - [DW_TAG_reference_type] = "reference_type", - [DW_TAG_compile_unit] = "compile_unit", - [DW_TAG_string_type] = "string_type", - [DW_TAG_structure_type] = "structure_type", - [DW_TAG_subroutine_type] = "subroutine_type", - [DW_TAG_typedef] = "typedef", - [DW_TAG_union_type] = "union_type", - [DW_TAG_unspecified_parameters] = "unspecified_parameters", - [DW_TAG_variant] = "variant", - [DW_TAG_common_block] = "common_block", - [DW_TAG_common_inclusion] = "common_inclusion", - [DW_TAG_inheritance] = "inheritance", - [DW_TAG_inlined_subroutine] = "inlined_subroutine", - [DW_TAG_module] = "module", - [DW_TAG_ptr_to_member_type] = "ptr_to_member_type", - [DW_TAG_set_type] = "set_type", - [DW_TAG_subrange_type] = "subrange_type", - [DW_TAG_with_stmt] = "with_stmt", - [DW_TAG_access_declaration] = "access_declaration", - [DW_TAG_base_type] = "base_type", - [DW_TAG_catch_block] = "catch_block", - [DW_TAG_const_type] = "const_type", - [DW_TAG_constant] = "constant", - [DW_TAG_enumerator] = "enumerator", - [DW_TAG_file_type] = "file_type", - [DW_TAG_friend] = "friend", - [DW_TAG_namelist] = "namelist", - [DW_TAG_namelist_item] = "namelist_item", - [DW_TAG_packed_type] = "packed_type", - [DW_TAG_subprogram] = "subprogram", - [DW_TAG_template_type_parameter] = "template_type_parameter", - [DW_TAG_template_value_parameter] = "template_value_parameter", - [DW_TAG_thrown_type] = "thrown_type", - [DW_TAG_try_block] = "try_block", - [DW_TAG_variant_part] = "variant_part", - [DW_TAG_variable] = "variable", - [DW_TAG_volatile_type] = "volatile_type", - [DW_TAG_dwarf_procedure] = "dwarf_procedure", - [DW_TAG_restrict_type] = "restrict_type", - [DW_TAG_interface_type] = "interface_type", - [DW_TAG_namespace] = "namespace", - [DW_TAG_imported_module] = "imported_module", - [DW_TAG_unspecified_type] = "unspecified_type", - [DW_TAG_partial_unit] = "partial_unit", - [DW_TAG_imported_unit] = "imported_unit", - [DW_TAG_mutable_type] = "mutable_type", - [DW_TAG_condition] = "condition", - [DW_TAG_shared_type] = "shared_type", - [DW_TAG_type_unit] = "type_unit", - [DW_TAG_rvalue_reference_type] = "rvalue_reference_type", - [DW_TAG_template_alias] = "template_alias", - }; - const unsigned int nknown_tags = (sizeof (known_tags) - / sizeof (known_tags[0])); - static char buf[40]; - const char *result = NULL; - - if (likely (tag < nknown_tags)) - result = known_tags[tag]; - - if (unlikely (result == NULL)) - /* There are a few known extensions. */ - switch (tag) - { - case DW_TAG_MIPS_loop: - result = "MIPS_loop"; - break; - - case DW_TAG_format_label: - result = "format_label"; - break; - - case DW_TAG_function_template: - result = "function_template"; - break; - - case DW_TAG_class_template: - result = "class_template"; - break; - - case DW_TAG_GNU_BINCL: - result = "GNU_BINCL"; - break; - - case DW_TAG_GNU_EINCL: - result = "GNU_EINCL"; - break; - - case DW_TAG_GNU_template_template_param: - result = "GNU_template_template_param"; - break; - - case DW_TAG_GNU_template_parameter_pack: - result = "GNU_template_parameter_pack"; - break; - - case DW_TAG_GNU_formal_parameter_pack: - result = "GNU_formal_parameter_pack"; - break; - - case DW_TAG_GNU_call_site: - result = "GNU_call_site"; - break; - - case DW_TAG_GNU_call_site_parameter: - result = "GNU_call_site_parameter"; - break; - - default: - if (tag < DW_TAG_lo_user) - snprintf (buf, sizeof buf, gettext ("unknown tag %hx"), tag); - else - snprintf (buf, sizeof buf, gettext ("unknown user tag %hx"), tag); - result = buf; - break; - } - - return result; + switch (tag) + { +#define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_TAG +#undef ONE_KNOWN_DW_TAG + default: + return NULL; + } }
static const char * dwarf_attr_string (unsigned int attrnum) { - static const char *const known_attrs[] = - { - [DW_AT_sibling] = "sibling", - [DW_AT_location] = "location", - [DW_AT_name] = "name", - [DW_AT_ordering] = "ordering", - [DW_AT_subscr_data] = "subscr_data", - [DW_AT_byte_size] = "byte_size", - [DW_AT_bit_offset] = "bit_offset", - [DW_AT_bit_size] = "bit_size", - [DW_AT_element_list] = "element_list", - [DW_AT_stmt_list] = "stmt_list", - [DW_AT_low_pc] = "low_pc", - [DW_AT_high_pc] = "high_pc", - [DW_AT_language] = "language", - [DW_AT_member] = "member", - [DW_AT_discr] = "discr", - [DW_AT_discr_value] = "discr_value", - [DW_AT_visibility] = "visibility", - [DW_AT_import] = "import", - [DW_AT_string_length] = "string_length", - [DW_AT_common_reference] = "common_reference", - [DW_AT_comp_dir] = "comp_dir", - [DW_AT_const_value] = "const_value", - [DW_AT_containing_type] = "containing_type", - [DW_AT_default_value] = "default_value", - [DW_AT_inline] = "inline", - [DW_AT_is_optional] = "is_optional", - [DW_AT_lower_bound] = "lower_bound", - [DW_AT_producer] = "producer", - [DW_AT_prototyped] = "prototyped", - [DW_AT_return_addr] = "return_addr", - [DW_AT_start_scope] = "start_scope", - [DW_AT_bit_stride] = "bit_stride", - [DW_AT_upper_bound] = "upper_bound", - [DW_AT_abstract_origin] = "abstract_origin", - [DW_AT_accessibility] = "accessibility", - [DW_AT_address_class] = "address_class", - [DW_AT_artificial] = "artificial", - [DW_AT_base_types] = "base_types", - [DW_AT_calling_convention] = "calling_convention", - [DW_AT_count] = "count", - [DW_AT_data_member_location] = "data_member_location", - [DW_AT_decl_column] = "decl_column", - [DW_AT_decl_file] = "decl_file", - [DW_AT_decl_line] = "decl_line", - [DW_AT_declaration] = "declaration", - [DW_AT_discr_list] = "discr_list", - [DW_AT_encoding] = "encoding", - [DW_AT_external] = "external", - [DW_AT_frame_base] = "frame_base", - [DW_AT_friend] = "friend", - [DW_AT_identifier_case] = "identifier_case", - [DW_AT_macro_info] = "macro_info", - [DW_AT_namelist_item] = "namelist_item", - [DW_AT_priority] = "priority", - [DW_AT_segment] = "segment", - [DW_AT_specification] = "specification", - [DW_AT_static_link] = "static_link", - [DW_AT_type] = "type", - [DW_AT_use_location] = "use_location", - [DW_AT_variable_parameter] = "variable_parameter", - [DW_AT_virtuality] = "virtuality", - [DW_AT_vtable_elem_location] = "vtable_elem_location", - [DW_AT_allocated] = "allocated", - [DW_AT_associated] = "associated", - [DW_AT_data_location] = "data_location", - [DW_AT_byte_stride] = "byte_stride", - [DW_AT_entry_pc] = "entry_pc", - [DW_AT_use_UTF8] = "use_UTF8", - [DW_AT_extension] = "extension", - [DW_AT_ranges] = "ranges", - [DW_AT_trampoline] = "trampoline", - [DW_AT_call_column] = "call_column", - [DW_AT_call_file] = "call_file", - [DW_AT_call_line] = "call_line", - [DW_AT_description] = "description", - [DW_AT_binary_scale] = "binary_scale", - [DW_AT_decimal_scale] = "decimal_scale", - [DW_AT_small] = "small", - [DW_AT_decimal_sign] = "decimal_sign", - [DW_AT_digit_count] = "digit_count", - [DW_AT_picture_string] = "picture_string", - [DW_AT_mutable] = "mutable", - [DW_AT_threads_scaled] = "threads_scaled", - [DW_AT_explicit] = "explicit", - [DW_AT_object_pointer] = "object_pointer", - [DW_AT_endianity] = "endianity", - [DW_AT_elemental] = "elemental", - [DW_AT_pure] = "pure", - [DW_AT_recursive] = "recursive", - [DW_AT_signature] = "signature", - [DW_AT_main_subprogram] = "main_subprogram", - [DW_AT_data_bit_offset] = "data_bit_offset", - [DW_AT_const_expr] = "const_expr", - [DW_AT_enum_class] = "enum_class", - [DW_AT_linkage_name] = "linkage_name", - }; - const unsigned int nknown_attrs = (sizeof (known_attrs) - / sizeof (known_attrs[0])); - static char buf[40]; - const char *result = NULL; - - if (likely (attrnum < nknown_attrs)) - result = known_attrs[attrnum]; - - if (unlikely (result == NULL)) - /* There are a few known extensions. */ - switch (attrnum) - { - case DW_AT_MIPS_fde: - result = "MIPS_fde"; - break; - - case DW_AT_MIPS_loop_begin: - result = "MIPS_loop_begin"; - break; - - case DW_AT_MIPS_tail_loop_begin: - result = "MIPS_tail_loop_begin"; - break; - - case DW_AT_MIPS_epilog_begin: - result = "MIPS_epilog_begin"; - break; - - case DW_AT_MIPS_loop_unroll_factor: - result = "MIPS_loop_unroll_factor"; - break; - - case DW_AT_MIPS_software_pipeline_depth: - result = "MIPS_software_pipeline_depth"; - break; - - case DW_AT_MIPS_linkage_name: - result = "MIPS_linkage_name"; - break; - - case DW_AT_MIPS_stride: - result = "MIPS_stride"; - break; - - case DW_AT_MIPS_abstract_name: - result = "MIPS_abstract_name"; - break; - - case DW_AT_MIPS_clone_origin: - result = "MIPS_clone_origin"; - break; - - case DW_AT_MIPS_has_inlines: - result = "MIPS_has_inlines"; - break; - - case DW_AT_MIPS_stride_byte: - result = "MIPS_stride_byte"; - break; - - case DW_AT_MIPS_stride_elem: - result = "MIPS_stride_elem"; - break; - - case DW_AT_MIPS_ptr_dopetype: - result = "MIPS_ptr_dopetype"; - break; - - case DW_AT_MIPS_allocatable_dopetype: - result = "MIPS_allocatable_dopetype"; - break; - - case DW_AT_MIPS_assumed_shape_dopetype: - result = "MIPS_assumed_shape_dopetype"; - break; - - case DW_AT_MIPS_assumed_size: - result = "MIPS_assumed_size"; - break; - - case DW_AT_sf_names: - result = "sf_names"; - break; - - case DW_AT_src_info: - result = "src_info"; - break; - - case DW_AT_mac_info: - result = "mac_info"; - break; - - case DW_AT_src_coords: - result = "src_coords"; - break; - - case DW_AT_body_begin: - result = "body_begin"; - break; - - case DW_AT_body_end: - result = "body_end"; - break; - - case DW_AT_GNU_vector: - result = "GNU_vector"; - break; - - case DW_AT_GNU_guarded_by: - result = "GNU_guarded_by"; - break; - - case DW_AT_GNU_pt_guarded_by: - result = "GNU_pt_guarded_by"; - break; - - case DW_AT_GNU_guarded: - result = "GNU_guarded"; - break; - - case DW_AT_GNU_pt_guarded: - result = "GNU_pt_guarded"; - break; - - case DW_AT_GNU_locks_excluded: - result = "GNU_locks_excluded"; - break; - - case DW_AT_GNU_exclusive_locks_required: - result = "GNU_exclusive_locks_required"; - break; - - case DW_AT_GNU_shared_locks_required: - result = "GNU_shared_locks_required"; - break; - - case DW_AT_GNU_odr_signature: - result = "GNU_odr_signature"; - break; - - case DW_AT_GNU_template_name: - result = "GNU_template_name"; - break; - - case DW_AT_GNU_call_site_value: - result = "GNU_call_site_value"; - break; - - case DW_AT_GNU_call_site_data_value: - result = "GNU_call_site_data_value"; - break; - - case DW_AT_GNU_call_site_target: - result = "GNU_call_site_target"; - break; - - case DW_AT_GNU_call_site_target_clobbered: - result = "GNU_call_site_target_clobbered"; - break; - - case DW_AT_GNU_tail_call: - result = "GNU_tail_call"; - break; - - case DW_AT_GNU_all_tail_call_sites: - result = "GNU_all_tail_call_sites"; - break; - - case DW_AT_GNU_all_call_sites: - result = "GNU_all_call_sites"; - break; - - case DW_AT_GNU_all_source_call_sites: - result = "GNU_all_source_call_sites"; - break; - - case DW_AT_GNU_macros: - result = "GNU_macros"; - break; - - default: - if (attrnum < DW_AT_lo_user) - snprintf (buf, sizeof buf, gettext ("unknown attribute %hx"), - attrnum); - else - snprintf (buf, sizeof buf, gettext ("unknown user attribute %hx"), - attrnum); - result = buf; - break; - } - - return result; + switch (attrnum) + { +#define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_AT +#undef ONE_KNOWN_DW_AT + default: + return NULL; + } }
static const char * dwarf_form_string (unsigned int form) { - static const char *const known_forms[] = - { - [DW_FORM_addr] = "addr", - [DW_FORM_block2] = "block2", - [DW_FORM_block4] = "block4", - [DW_FORM_data2] = "data2", - [DW_FORM_data4] = "data4", - [DW_FORM_data8] = "data8", - [DW_FORM_string] = "string", - [DW_FORM_block] = "block", - [DW_FORM_block1] = "block1", - [DW_FORM_data1] = "data1", - [DW_FORM_flag] = "flag", - [DW_FORM_sdata] = "sdata", - [DW_FORM_strp] = "strp", - [DW_FORM_udata] = "udata", - [DW_FORM_ref_addr] = "ref_addr", - [DW_FORM_ref1] = "ref1", - [DW_FORM_ref2] = "ref2", - [DW_FORM_ref4] = "ref4", - [DW_FORM_ref8] = "ref8", - [DW_FORM_ref_udata] = "ref_udata", - [DW_FORM_indirect] = "indirect", - [DW_FORM_sec_offset] = "sec_offset", - [DW_FORM_exprloc] = "exprloc", - [DW_FORM_flag_present] = "flag_present", - [DW_FORM_ref_sig8] = "ref_sig8", - }; - const unsigned int nknown_forms = (sizeof (known_forms) - / sizeof (known_forms[0])); - static char buf[40]; - const char *result = NULL; - - if (likely (form < nknown_forms)) - result = known_forms[form]; - else - { - /* GNU extensions use vendor numbers. */ - switch (form) - { - case DW_FORM_GNU_ref_alt: - result = "GNU_ref_alt"; - break; - - case DW_FORM_GNU_strp_alt: - result = "GNU_strp_alt"; - break; - } - } - - if (unlikely (result == NULL)) + switch (form) { - snprintf (buf, sizeof buf, gettext ("unknown form %#" PRIx64), - (uint64_t) form); - result = buf; +#define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE) +#define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_FORM +#undef ONE_KNOWN_DW_FORM +#undef ONE_KNOWN_DW_FORM_DESC + default: + return NULL; } - - return result; }
static const char * dwarf_lang_string (unsigned int lang) { - static const char *const known[] = - { - [DW_LANG_C89] = "ISO C89", - [DW_LANG_C] = "C", - [DW_LANG_Ada83] = "Ada83", - [DW_LANG_C_plus_plus] = "C++", - [DW_LANG_Cobol74] = "Cobol74", - [DW_LANG_Cobol85] = "Cobol85", - [DW_LANG_Fortran77] = "Fortran77", - [DW_LANG_Fortran90] = "Fortran90", - [DW_LANG_Pascal83] = "Pascal83", - [DW_LANG_Modula2] = "Modula2", - [DW_LANG_Java] = "Java", - [DW_LANG_C99] = "ISO C99", - [DW_LANG_Ada95] = "Ada95", - [DW_LANG_Fortran95] = "Fortran95", - [DW_LANG_PL1] = "PL1", - [DW_LANG_ObjC] = "Objective C", - [DW_LANG_ObjC_plus_plus] = "Objective C++", - [DW_LANG_UPC] = "UPC", - [DW_LANG_D] = "D", - }; - - if (likely (lang < sizeof (known) / sizeof (known[0]))) - return known[lang]; - else if (lang == DW_LANG_Mips_Assembler) - /* This language tag is used for assembler in general. */ - return "Assembler"; - - if (lang >= DW_LANG_lo_user && lang <= DW_LANG_hi_user) + switch (lang) { - static char buf[30]; - snprintf (buf, sizeof (buf), "lo_user+%u", lang - DW_LANG_lo_user); - return buf; +#define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME; + ALL_KNOWN_DW_LANG +#undef ONE_KNOWN_DW_LANG_DESC + default: + return NULL; } - - return "???"; }
@@ -3725,16 +3246,15 @@ dwarf_inline_string (unsigned int code) { static const char *const known[] = { - [DW_INL_not_inlined] = "not_inlined", - [DW_INL_inlined] = "inlined", - [DW_INL_declared_not_inlined] = "declared_not_inlined", - [DW_INL_declared_inlined] = "declared_inlined" +#define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_INL +#undef ONE_KNOWN_DW_INL };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3743,35 +3263,15 @@ dwarf_encoding_string (unsigned int code) { static const char *const known[] = { - [DW_ATE_void] = "void", - [DW_ATE_address] = "address", - [DW_ATE_boolean] = "boolean", - [DW_ATE_complex_float] = "complex_float", - [DW_ATE_float] = "float", - [DW_ATE_signed] = "signed", - [DW_ATE_signed_char] = "signed_char", - [DW_ATE_unsigned] = "unsigned", - [DW_ATE_unsigned_char] = "unsigned_char", - [DW_ATE_imaginary_float] = "imaginary_float", - [DW_ATE_packed_decimal] = "packed_decimal", - [DW_ATE_numeric_string] = "numeric_string", - [DW_ATE_edited] = "edited", - [DW_ATE_signed_fixed] = "signed_fixed", - [DW_ATE_unsigned_fixed] = "unsigned_fixed", - [DW_ATE_decimal_float] = "decimal_float", +#define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ATE +#undef ONE_KNOWN_DW_ATE };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user) - { - static char buf[30]; - snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user); - return buf; - } - - return "???"; + return NULL; }
@@ -3780,15 +3280,15 @@ dwarf_access_string (unsigned int code) { static const char *const known[] = { - [DW_ACCESS_public] = "public", - [DW_ACCESS_protected] = "protected", - [DW_ACCESS_private] = "private" +#define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ACCESS +#undef ONE_KNOWN_DW_ACCESS };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3797,15 +3297,15 @@ dwarf_visibility_string (unsigned int code) { static const char *const known[] = { - [DW_VIS_local] = "local", - [DW_VIS_exported] = "exported", - [DW_VIS_qualified] = "qualified" +#define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_VIS +#undef ONE_KNOWN_DW_VIS };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3814,15 +3314,15 @@ dwarf_virtuality_string (unsigned int code) { static const char *const known[] = { - [DW_VIRTUALITY_none] = "none", - [DW_VIRTUALITY_virtual] = "virtual", - [DW_VIRTUALITY_pure_virtual] = "pure_virtual" +#define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_VIRTUALITY +#undef ONE_KNOWN_DW_VIRTUALITY };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3831,16 +3331,15 @@ dwarf_identifier_case_string (unsigned int code) { static const char *const known[] = { - [DW_ID_case_sensitive] = "sensitive", - [DW_ID_up_case] = "up_case", - [DW_ID_down_case] = "down_case", - [DW_ID_case_insensitive] = "insensitive" +#define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ID +#undef ONE_KNOWN_DW_ID };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3849,22 +3348,15 @@ dwarf_calling_convention_string (unsigned int code) { static const char *const known[] = { - [DW_CC_normal] = "normal", - [DW_CC_program] = "program", - [DW_CC_nocall] = "nocall", +#define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_CC +#undef ONE_KNOWN_DW_CC };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- if (code >= DW_CC_lo_user && code <= DW_CC_hi_user) - { - static char buf[30]; - snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_CC_lo_user); - return buf; - } - - return "???"; + return NULL; }
@@ -3873,14 +3365,15 @@ dwarf_ordering_string (unsigned int code) { static const char *const known[] = { - [DW_ORD_row_major] = "row_major", - [DW_ORD_col_major] = "col_major" +#define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ORD +#undef ONE_KNOWN_DW_ORD };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- return "???"; + return NULL; }
@@ -3889,17 +3382,171 @@ dwarf_discr_list_string (unsigned int code) { static const char *const known[] = { - [DW_DSC_label] = "label", - [DW_DSC_range] = "range" +#define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_DSC +#undef ONE_KNOWN_DW_DSC };
if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
+ return NULL; +} + + +static const char * +dwarf_locexpr_opcode_string (unsigned int code) +{ + static const char *const known[] = + { + /* Normally we can't affort building huge table of 64K entries, + most of them zero, just because there are a couple defined + values at the far end. In case of opcodes, it's OK. */ +#define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE) +#define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_OP +#undef ONE_KNOWN_DW_OP +#undef ONE_KNOWN_DW_OP_DESC + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} + + +/* Used by all dwarf_foo_name functions. */ +static const char * +string_or_unknown (const char *known, unsigned int code, + unsigned int lo_user, unsigned int hi_user, + bool print_unknown_num) +{ + static char unknown_buf[20]; + + if (likely (known != NULL)) + return known; + + if (lo_user != 0 && code >= lo_user && code <= hi_user) + { + snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x", + code - lo_user); + return unknown_buf; + } + + if (print_unknown_num) + { + snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code); + return unknown_buf; + } + return "???"; }
+static const char * +dwarf_tag_name (unsigned int tag) +{ + const char *ret = dwarf_tag_string (tag); + return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true); +} + +static const char * +dwarf_attr_name (unsigned int attr) +{ + const char *ret = dwarf_attr_string (attr); + return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true); +} + + +static const char * +dwarf_form_name (unsigned int form) +{ + const char *ret = dwarf_form_string (form); + return string_or_unknown (ret, form, 0, 0, true); +} + + +static const char * +dwarf_lang_name (unsigned int lang) +{ + const char *ret = dwarf_lang_string (lang); + return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false); +} + + +static const char * +dwarf_inline_name (unsigned int code) +{ + const char *ret = dwarf_inline_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_encoding_name (unsigned int code) +{ + const char *ret = dwarf_encoding_string (code); + return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false); +} + + +static const char * +dwarf_access_name (unsigned int code) +{ + const char *ret = dwarf_access_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_visibility_name (unsigned int code) +{ + const char *ret = dwarf_visibility_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_virtuality_name (unsigned int code) +{ + const char *ret = dwarf_virtuality_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_identifier_case_name (unsigned int code) +{ + const char *ret = dwarf_identifier_case_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_calling_convention_name (unsigned int code) +{ + const char *ret = dwarf_calling_convention_string (code); + return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false); +} + + +static const char * +dwarf_ordering_name (unsigned int code) +{ + const char *ret = dwarf_ordering_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + +static const char * +dwarf_discr_list_name (unsigned int code) +{ + const char *ret = dwarf_discr_list_string (code); + return string_or_unknown (ret, code, 0, 0, false); +} + + static void print_block (size_t n, const void *block) { @@ -3923,174 +3570,6 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, { const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
- static const char *const known[] = - { - [DW_OP_addr] = "addr", - [DW_OP_deref] = "deref", - [DW_OP_const1u] = "const1u", - [DW_OP_const1s] = "const1s", - [DW_OP_const2u] = "const2u", - [DW_OP_const2s] = "const2s", - [DW_OP_const4u] = "const4u", - [DW_OP_const4s] = "const4s", - [DW_OP_const8u] = "const8u", - [DW_OP_const8s] = "const8s", - [DW_OP_constu] = "constu", - [DW_OP_consts] = "consts", - [DW_OP_dup] = "dup", - [DW_OP_drop] = "drop", - [DW_OP_over] = "over", - [DW_OP_pick] = "pick", - [DW_OP_swap] = "swap", - [DW_OP_rot] = "rot", - [DW_OP_xderef] = "xderef", - [DW_OP_abs] = "abs", - [DW_OP_and] = "and", - [DW_OP_div] = "div", - [DW_OP_minus] = "minus", - [DW_OP_mod] = "mod", - [DW_OP_mul] = "mul", - [DW_OP_neg] = "neg", - [DW_OP_not] = "not", - [DW_OP_or] = "or", - [DW_OP_plus] = "plus", - [DW_OP_plus_uconst] = "plus_uconst", - [DW_OP_shl] = "shl", - [DW_OP_shr] = "shr", - [DW_OP_shra] = "shra", - [DW_OP_xor] = "xor", - [DW_OP_bra] = "bra", - [DW_OP_eq] = "eq", - [DW_OP_ge] = "ge", - [DW_OP_gt] = "gt", - [DW_OP_le] = "le", - [DW_OP_lt] = "lt", - [DW_OP_ne] = "ne", - [DW_OP_skip] = "skip", - [DW_OP_lit0] = "lit0", - [DW_OP_lit1] = "lit1", - [DW_OP_lit2] = "lit2", - [DW_OP_lit3] = "lit3", - [DW_OP_lit4] = "lit4", - [DW_OP_lit5] = "lit5", - [DW_OP_lit6] = "lit6", - [DW_OP_lit7] = "lit7", - [DW_OP_lit8] = "lit8", - [DW_OP_lit9] = "lit9", - [DW_OP_lit10] = "lit10", - [DW_OP_lit11] = "lit11", - [DW_OP_lit12] = "lit12", - [DW_OP_lit13] = "lit13", - [DW_OP_lit14] = "lit14", - [DW_OP_lit15] = "lit15", - [DW_OP_lit16] = "lit16", - [DW_OP_lit17] = "lit17", - [DW_OP_lit18] = "lit18", - [DW_OP_lit19] = "lit19", - [DW_OP_lit20] = "lit20", - [DW_OP_lit21] = "lit21", - [DW_OP_lit22] = "lit22", - [DW_OP_lit23] = "lit23", - [DW_OP_lit24] = "lit24", - [DW_OP_lit25] = "lit25", - [DW_OP_lit26] = "lit26", - [DW_OP_lit27] = "lit27", - [DW_OP_lit28] = "lit28", - [DW_OP_lit29] = "lit29", - [DW_OP_lit30] = "lit30", - [DW_OP_lit31] = "lit31", - [DW_OP_reg0] = "reg0", - [DW_OP_reg1] = "reg1", - [DW_OP_reg2] = "reg2", - [DW_OP_reg3] = "reg3", - [DW_OP_reg4] = "reg4", - [DW_OP_reg5] = "reg5", - [DW_OP_reg6] = "reg6", - [DW_OP_reg7] = "reg7", - [DW_OP_reg8] = "reg8", - [DW_OP_reg9] = "reg9", - [DW_OP_reg10] = "reg10", - [DW_OP_reg11] = "reg11", - [DW_OP_reg12] = "reg12", - [DW_OP_reg13] = "reg13", - [DW_OP_reg14] = "reg14", - [DW_OP_reg15] = "reg15", - [DW_OP_reg16] = "reg16", - [DW_OP_reg17] = "reg17", - [DW_OP_reg18] = "reg18", - [DW_OP_reg19] = "reg19", - [DW_OP_reg20] = "reg20", - [DW_OP_reg21] = "reg21", - [DW_OP_reg22] = "reg22", - [DW_OP_reg23] = "reg23", - [DW_OP_reg24] = "reg24", - [DW_OP_reg25] = "reg25", - [DW_OP_reg26] = "reg26", - [DW_OP_reg27] = "reg27", - [DW_OP_reg28] = "reg28", - [DW_OP_reg29] = "reg29", - [DW_OP_reg30] = "reg30", - [DW_OP_reg31] = "reg31", - [DW_OP_breg0] = "breg0", - [DW_OP_breg1] = "breg1", - [DW_OP_breg2] = "breg2", - [DW_OP_breg3] = "breg3", - [DW_OP_breg4] = "breg4", - [DW_OP_breg5] = "breg5", - [DW_OP_breg6] = "breg6", - [DW_OP_breg7] = "breg7", - [DW_OP_breg8] = "breg8", - [DW_OP_breg9] = "breg9", - [DW_OP_breg10] = "breg10", - [DW_OP_breg11] = "breg11", - [DW_OP_breg12] = "breg12", - [DW_OP_breg13] = "breg13", - [DW_OP_breg14] = "breg14", - [DW_OP_breg15] = "breg15", - [DW_OP_breg16] = "breg16", - [DW_OP_breg17] = "breg17", - [DW_OP_breg18] = "breg18", - [DW_OP_breg19] = "breg19", - [DW_OP_breg20] = "breg20", - [DW_OP_breg21] = "breg21", - [DW_OP_breg22] = "breg22", - [DW_OP_breg23] = "breg23", - [DW_OP_breg24] = "breg24", - [DW_OP_breg25] = "breg25", - [DW_OP_breg26] = "breg26", - [DW_OP_breg27] = "breg27", - [DW_OP_breg28] = "breg28", - [DW_OP_breg29] = "breg29", - [DW_OP_breg30] = "breg30", - [DW_OP_breg31] = "breg31", - [DW_OP_regx] = "regx", - [DW_OP_fbreg] = "fbreg", - [DW_OP_bregx] = "bregx", - [DW_OP_piece] = "piece", - [DW_OP_deref_size] = "deref_size", - [DW_OP_xderef_size] = "xderef_size", - [DW_OP_nop] = "nop", - [DW_OP_push_object_address] = "push_object_address", - [DW_OP_call2] = "call2", - [DW_OP_call4] = "call4", - [DW_OP_call_ref] = "call_ref", - [DW_OP_form_tls_address] = "form_tls_address", - [DW_OP_call_frame_cfa] = "call_frame_cfa", - [DW_OP_bit_piece] = "bit_piece", - [DW_OP_implicit_value] = "implicit_value", - [DW_OP_stack_value] = "stack_value", - [DW_OP_GNU_push_tls_address] = "GNU_push_tls_address", - [DW_OP_GNU_uninit] = "GNU_uninit", - [DW_OP_GNU_encoded_addr] = "GNU_encoded_addr", - [DW_OP_GNU_implicit_pointer] = "GNU_implicit_pointer", - [DW_OP_GNU_entry_value] = "GNU_entry_value", - [DW_OP_GNU_const_type] = "GNU_const_type", - [DW_OP_GNU_regval_type] = "GNU_regval_type", - [DW_OP_GNU_deref_type] = "GNU_deref_type", - [DW_OP_GNU_convert] = "GNU_convert", - [DW_OP_GNU_reinterpret] = "GNU_reinterpret", - }; - if (len == 0) { printf ("%*s(empty)\n", indent, ""); @@ -4105,6 +3584,17 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, { uint_fast8_t op = *data++;
+ const char *op_name = dwarf_locexpr_opcode_string (op); + if (unlikely (op_name == NULL)) + { + static char buf[20]; + if (op >= DW_OP_lo_user) + snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user); + else + snprintf (buf, sizeof buf, "??? (%#x)", op); + op_name = buf; + } + switch (op) { case DW_OP_addr:; @@ -4123,7 +3613,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
char *a = format_dwarf_addr (dwflmod, 0, addr); printf ("%*s[%4" PRIuMAX "] %s %s\n", - indent, "", (uintmax_t) offset, known[op], a); + indent, "", (uintmax_t) offset, op_name, a); free (a);
offset += 1 + addrsize; @@ -4144,7 +3634,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX "\n", indent, "", (uintmax_t) offset, - known[op], (uintmax_t) addr); + op_name, (uintmax_t) addr); offset += 1 + ref_size; break;
@@ -4156,7 +3646,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 "\n", indent, "", (uintmax_t) offset, - known[op], *((uint8_t *) data)); + op_name, *((uint8_t *) data)); ++data; --len; offset += 2; @@ -4167,7 +3657,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", indent, "", (uintmax_t) offset, - known[op], read_2ubyte_unaligned (dbg, data)); + op_name, read_2ubyte_unaligned (dbg, data)); CONSUME (2); data += 2; offset += 3; @@ -4178,7 +3668,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", indent, "", (uintmax_t) offset, - known[op], read_4ubyte_unaligned (dbg, data)); + op_name, read_4ubyte_unaligned (dbg, data)); CONSUME (4); data += 4; offset += 5; @@ -4189,7 +3679,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", indent, "", (uintmax_t) offset, - known[op], (uint64_t) read_8ubyte_unaligned (dbg, data)); + op_name, (uint64_t) read_8ubyte_unaligned (dbg, data)); CONSUME (8); data += 8; offset += 9; @@ -4200,7 +3690,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId8 "\n", indent, "", (uintmax_t) offset, - known[op], *((int8_t *) data)); + op_name, *((int8_t *) data)); ++data; --len; offset += 2; @@ -4211,7 +3701,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId16 "\n", indent, "", (uintmax_t) offset, - known[op], read_2sbyte_unaligned (dbg, data)); + op_name, read_2sbyte_unaligned (dbg, data)); CONSUME (2); data += 2; offset += 3; @@ -4222,7 +3712,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId32 "\n", indent, "", (uintmax_t) offset, - known[op], read_4sbyte_unaligned (dbg, data)); + op_name, read_4sbyte_unaligned (dbg, data)); CONSUME (4); data += 4; offset += 5; @@ -4233,7 +3723,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, // XXX value might be modified by relocation printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", indent, "", (uintmax_t) offset, - known[op], read_8sbyte_unaligned (dbg, data)); + op_name, read_8sbyte_unaligned (dbg, data)); CONSUME (8); data += 8; offset += 9; @@ -4248,7 +3738,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 "\n", - indent, "", (uintmax_t) offset, known[op], uleb); + indent, "", (uintmax_t) offset, op_name, uleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4260,7 +3750,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, get_uleb128 (uleb, data); /* XXX check overrun */ get_uleb128 (uleb2, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n", - indent, "", (uintmax_t) offset, known[op], uleb, uleb2); + indent, "", (uintmax_t) offset, op_name, uleb, uleb2); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4273,7 +3763,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); get_sleb128 (sleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRId64 "\n", - indent, "", (uintmax_t) offset, known[op], sleb); + indent, "", (uintmax_t) offset, op_name, sleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4284,7 +3774,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, get_uleb128 (uleb, data); /* XXX check overrun */ get_sleb128 (sleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n", - indent, "", (uintmax_t) offset, known[op], uleb, sleb); + indent, "", (uintmax_t) offset, op_name, uleb, sleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4292,7 +3782,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_call2: NEED (2); printf ("%*s[%4" PRIuMAX "] %s %" PRIu16 "\n", - indent, "", (uintmax_t) offset, known[op], + indent, "", (uintmax_t) offset, op_name, read_2ubyte_unaligned (dbg, data)); CONSUME (2); offset += 3; @@ -4301,7 +3791,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_call4: NEED (4); printf ("%*s[%4" PRIuMAX "] %s %" PRIu32 "\n", - indent, "", (uintmax_t) offset, known[op], + indent, "", (uintmax_t) offset, op_name, read_4ubyte_unaligned (dbg, data)); CONSUME (4); offset += 5; @@ -4311,7 +3801,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_bra: NEED (2); printf ("%*s[%4" PRIuMAX "] %s %" PRIuMAX "\n", - indent, "", (uintmax_t) offset, known[op], + indent, "", (uintmax_t) offset, op_name, (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data))); CONSUME (2); data += 2; @@ -4323,7 +3813,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s: ", - indent, "", (uintmax_t) offset, known[op]); + indent, "", (uintmax_t) offset, op_name); NEED (uleb); print_block (uleb, data); data += uleb; @@ -4348,7 +3838,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
printf ("%*s[%4" PRIuMAX "] %s %#" PRIxMAX ", %+" PRId64 "\n", indent, "", (intmax_t) offset, - known[op], (uintmax_t) addr, sleb); + op_name, (uintmax_t) addr, sleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4359,7 +3849,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s:\n", - indent, "", (uintmax_t) offset, known[op]); + indent, "", (uintmax_t) offset, op_name); NEED (uleb); print_ops (dwflmod, dbg, indent + 6, indent + 6, vers, addrsize, offset_size, uleb, data); @@ -4376,7 +3866,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, uint8_t usize = *(uint8_t *) data++; NEED (usize); printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "] ", - indent, "", (uintmax_t) offset, known[op], uleb); + indent, "", (uintmax_t) offset, op_name, uleb); print_block (usize, data); data += usize; CONSUME (data - start); @@ -4389,7 +3879,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, get_uleb128 (uleb, data); /* XXX check overrun */ get_uleb128 (uleb2, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRIu64 " %#" PRIx64 "\n", - indent, "", (uintmax_t) offset, known[op], uleb, uleb2); + indent, "", (uintmax_t) offset, op_name, uleb, uleb2); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4401,7 +3891,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n", indent, "", (uintmax_t) offset, - known[op], usize, uleb); + op_name, usize, uleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4412,7 +3902,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, NEED (1); get_uleb128 (uleb, data); /* XXX check overrun */ printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n", - indent, "", (uintmax_t) offset, known[op], uleb); + indent, "", (uintmax_t) offset, op_name, uleb); CONSUME (data - start); offset += 1 + (data - start); break; @@ -4422,7 +3912,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, DW_TAG_formal_parameter. */ NEED (4); printf ("%*s[%4" PRIuMAX "] %s [%6" PRIxMAX "]\n", - indent, "", (uintmax_t) offset, known[op], + indent, "", (uintmax_t) offset, op_name, (uintmax_t) read_4ubyte_unaligned (dbg, data)); CONSUME (4); data += 4; @@ -4431,12 +3921,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
default: /* No Operand. */ - if (op < sizeof known / sizeof known[0] && known[op] != NULL) - printf ("%*s[%4" PRIuMAX "] %s\n", - indent, "", (uintmax_t) offset, known[op]); - else - printf ("%*s[%4" PRIuMAX "] %#x\n", - indent, "", (uintmax_t) offset, op); + printf ("%*s[%4" PRIuMAX "] %s\n", + indent, "", (uintmax_t) offset, op_name); ++offset; break; } @@ -4446,7 +3932,7 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
invalid: printf (gettext ("%*s[%4" PRIuMAX "] %s <TRUNCATED>\n"), - indent, "", (uintmax_t) offset, known[op]); + indent, "", (uintmax_t) offset, op_name); break; } } @@ -4639,7 +4125,7 @@ print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), ", children: %s, tag: %s\n"), code, (int64_t) offset, has_children ? gettext ("yes") : gettext ("no"), - dwarf_tag_string (tag)); + dwarf_tag_name (tag));
size_t cnt = 0; unsigned int name; @@ -4649,7 +4135,7 @@ print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)), &name, &form, &enoffset) == 0) { printf (" attr: %s, form: %s, offset: %#" PRIx64 "\n", - dwarf_attr_string (name), dwarf_form_string (form), + dwarf_attr_name (name), dwarf_form_name (form), (uint64_t) enoffset);
++cnt; @@ -5598,8 +5084,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) } char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize, addr); printf (" %*s%-20s (%s) %s\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), a); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), a); free (a); } break; @@ -5614,8 +5100,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) if (unlikely (str == NULL)) goto attrval_out; printf (" %*s%-20s (%s) "%s"\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), str); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), str); break;
case DW_FORM_ref_addr: @@ -5632,16 +5118,16 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) goto attrval_out;
printf (" %*s%-20s (%s) [%6" PRIxMAX "]\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), (uintmax_t) dwarf_dieoffset (&ref)); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref)); break;
case DW_FORM_ref_sig8: if (cbargs->silent) break; printf (" %*s%-20s (%s) {%6" PRIx64 "}\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp)); break;
@@ -5667,8 +5153,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) { if (!cbargs->silent) printf (" %*s%-20s (%s) %" PRIxMAX "\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), (uintmax_t) num); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); return DWARF_CB_OK; } /* else fallthrough */ @@ -5690,8 +5176,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) cbargs->addrsize, cbargs->offset_size, num); if (!cbargs->silent) printf (" %*s%-20s (%s) location list [%6" PRIxMAX "]\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), (uintmax_t) num); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); return DWARF_CB_OK;
case DW_AT_ranges: @@ -5699,39 +5185,39 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) cbargs->addrsize, cbargs->offset_size, num); if (!cbargs->silent) printf (" %*s%-20s (%s) range list [%6" PRIxMAX "]\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), (uintmax_t) num); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); return DWARF_CB_OK;
case DW_AT_language: - valuestr = dwarf_lang_string (num); + valuestr = dwarf_lang_name (num); break; case DW_AT_encoding: - valuestr = dwarf_encoding_string (num); + valuestr = dwarf_encoding_name (num); break; case DW_AT_accessibility: - valuestr = dwarf_access_string (num); + valuestr = dwarf_access_name (num); break; case DW_AT_visibility: - valuestr = dwarf_visibility_string (num); + valuestr = dwarf_visibility_name (num); break; case DW_AT_virtuality: - valuestr = dwarf_virtuality_string (num); + valuestr = dwarf_virtuality_name (num); break; case DW_AT_identifier_case: - valuestr = dwarf_identifier_case_string (num); + valuestr = dwarf_identifier_case_name (num); break; case DW_AT_calling_convention: - valuestr = dwarf_calling_convention_string (num); + valuestr = dwarf_calling_convention_name (num); break; case DW_AT_inline: - valuestr = dwarf_inline_string (num); + valuestr = dwarf_inline_name (num); break; case DW_AT_ordering: - valuestr = dwarf_ordering_string (num); + valuestr = dwarf_ordering_name (num); break; case DW_AT_discr_list: - valuestr = dwarf_discr_list_string (num); + valuestr = dwarf_discr_list_name (num); break; default: /* Nothing. */ @@ -5743,12 +5229,12 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
if (valuestr == NULL) printf (" %*s%-20s (%s) %" PRIuMAX "\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), (uintmax_t) num); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), (uintmax_t) num); else printf (" %*s%-20s (%s) %s (%" PRIuMAX ")\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), valuestr, (uintmax_t) num); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), valuestr, (uintmax_t) num); break;
case DW_FORM_flag: @@ -5759,16 +5245,16 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) goto attrval_out;
printf (" %*s%-20s (%s) %s\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), nl_langinfo (flag ? YESSTR : NOSTR)); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), nl_langinfo (flag ? YESSTR : NOSTR)); break;
case DW_FORM_flag_present: if (cbargs->silent) break; printf (" %*s%-20s (%s) %s\n", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form), nl_langinfo (YESSTR)); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form), nl_langinfo (YESSTR)); break;
case DW_FORM_exprloc: @@ -5783,8 +5269,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) goto attrval_out;
printf (" %*s%-20s (%s) ", - (int) (level * 2), "", dwarf_attr_string (attr), - dwarf_form_string (form)); + (int) (level * 2), "", dwarf_attr_name (attr), + dwarf_form_name (form));
switch (attr) { @@ -5832,7 +5318,7 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) if (cbargs->silent) break; printf (" %*s%-20s (form: %#x) ???\n", - (int) (level * 2), "", dwarf_attr_string (attr), + (int) (level * 2), "", dwarf_attr_name (attr), (int) form); break; } @@ -5947,7 +5433,7 @@ print_debug_units (Dwfl_Module *dwflmod, if (!silent) printf (" [%6" PRIx64 "] %*s%s\n", (uint64_t) offset, (int) (level * 2), "", - dwarf_tag_string (tag)); + dwarf_tag_name (tag));
/* Print the attribute values. */ args.level = level; diff --git a/tests/ChangeLog b/tests/ChangeLog index 1cdd464..f0c83e6 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,14 @@ +2012-08-16 Mark Wielaard mjw@redhat.com + + * allregs.c (dwarf_encoding_string): Rewritten using known-dwarf + macros. + * show-die-info.c (tagnames): Removed. + (attrs): Removed. + (dwarf_tag_string): New function using known-dwarf macros. + (dwarf_attr_string): Likewise. + (handle): Call dwarf_tag_string and dwarf_attr_string instead. + * run-readelf-dwz-multi.sh: Expect language C89, not ISO C89. + 2012-06-27 Mark Wielaard mjw@redhat.com
* Makefile.am (TESTS): Add run-readelf-dwz-multi.sh. diff --git a/tests/allregs.c b/tests/allregs.c index b30d899..b103ce1 100644 --- a/tests/allregs.c +++ b/tests/allregs.c @@ -28,43 +28,25 @@ #include ELFUTILS_HEADER(dwfl) #include <dwarf.h>
+#include "../libdw/known-dwarf.h"
static const char * dwarf_encoding_string (unsigned int code) { - static const char *known[] = + static const char *const known[] = { - [DW_ATE_void] = "void", - [DW_ATE_address] = "address", - [DW_ATE_boolean] = "boolean", - [DW_ATE_complex_float] = "complex_float", - [DW_ATE_float] = "float", - [DW_ATE_signed] = "signed", - [DW_ATE_signed_char] = "signed_char", - [DW_ATE_unsigned] = "unsigned", - [DW_ATE_unsigned_char] = "unsigned_char", - [DW_ATE_imaginary_float] = "imaginary_float", - [DW_ATE_packed_decimal] = "packed_decimal", - [DW_ATE_numeric_string] = "numeric_string", - [DW_ATE_edited] = "edited", - [DW_ATE_signed_fixed] = "signed_fixed", - [DW_ATE_unsigned_fixed] = "unsigned_fixed", - [DW_ATE_decimal_float] = "decimal_float", +#define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ATE +#undef ONE_KNOWN_DW_ATE };
- if (code < sizeof (known) / sizeof (known[0])) + if (likely (code < sizeof (known) / sizeof (known[0]))) return known[code];
- if (code >= DW_ATE_lo_user && code <= DW_ATE_hi_user) - { - static char buf[30]; - snprintf (buf, sizeof (buf), "lo_user+%u", code - DW_ATE_lo_user); - return buf; - } - - return "???"; + return NULL; }
+ static int first_module (Dwfl_Module *mod, void **userdatap __attribute__ ((unused)), diff --git a/tests/run-readelf-dwz-multi.sh b/tests/run-readelf-dwz-multi.sh index 42e6aa4..aadbbbe 100755 --- a/tests/run-readelf-dwz-multi.sh +++ b/tests/run-readelf-dwz-multi.sh @@ -66,7 +66,7 @@ DWARF section [28] '.debug_info' at offset 0x1078: Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4 [ b] compile_unit producer (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -mtune=generic -march=x86-64 -g" - language (data1) ISO C89 (1) + language (data1) C89 (1) name (strp) "main.c" comp_dir (GNU_strp_alt) "/home/mark/src/tests/dwz" low_pc (addr) 0x00000000004006ac <main> @@ -124,7 +124,7 @@ DWARF section [25] '.debug_info' at offset 0x106c: Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4 [ b] compile_unit producer (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -fpreprocessed -mtune=generic -march=x86-64 -g -fPIC" - language (data1) ISO C89 (1) + language (data1) C89 (1) name (strp) "shared.c" comp_dir (GNU_strp_alt) "/home/mark/src/tests/dwz" low_pc (addr) +0x0000000000000670 <call_foo> diff --git a/tests/show-die-info.c b/tests/show-die-info.c index cdd0d54..0c298ac 100644 --- a/tests/show-die-info.c +++ b/tests/show-die-info.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2006 Red Hat, Inc. +/* Copyright (C) 1998-2002, 2004, 2006, 2012 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper drepper@redhat.com, 1998.
@@ -26,191 +26,33 @@ #include <string.h> #include <unistd.h>
+#include "../libdw/known-dwarf.h"
-static const char *tagnames[] = +static const char * +dwarf_tag_string (unsigned int tag) { - [DW_TAG_array_type] = "DW_TAG_array_type", - [DW_TAG_class_type] = "DW_TAG_class_type", - [DW_TAG_entry_point] = "DW_TAG_entry_point", - [DW_TAG_enumeration_type] = "DW_TAG_enumeration_type", - [DW_TAG_formal_parameter] = "DW_TAG_formal_parameter", - [DW_TAG_imported_declaration] = "DW_TAG_imported_declaration", - [DW_TAG_label] = "DW_TAG_label", - [DW_TAG_lexical_block] = "DW_TAG_lexical_block", - [DW_TAG_member] = "DW_TAG_member", - [DW_TAG_pointer_type] = "DW_TAG_pointer_type", - [DW_TAG_reference_type] = "DW_TAG_reference_type", - [DW_TAG_compile_unit] = "DW_TAG_compile_unit", - [DW_TAG_string_type] = "DW_TAG_string_type", - [DW_TAG_structure_type] = "DW_TAG_structure_type", - [DW_TAG_subroutine_type] = "DW_TAG_subroutine_type", - [DW_TAG_typedef] = "DW_TAG_typedef", - [DW_TAG_union_type] = "DW_TAG_union_type", - [DW_TAG_unspecified_parameters] = "DW_TAG_unspecified_parameters", - [DW_TAG_variant] = "DW_TAG_variant", - [DW_TAG_common_block] = "DW_TAG_common_block", - [DW_TAG_common_inclusion] = "DW_TAG_common_inclusion", - [DW_TAG_inheritance] = "DW_TAG_inheritance", - [DW_TAG_inlined_subroutine] = "DW_TAG_inlined_subroutine", - [DW_TAG_module] = "DW_TAG_module", - [DW_TAG_ptr_to_member_type] = "DW_TAG_ptr_to_member_type", - [DW_TAG_set_type] = "DW_TAG_set_type", - [DW_TAG_subrange_type] = "DW_TAG_subrange_type", - [DW_TAG_with_stmt] = "DW_TAG_with_stmt", - [DW_TAG_access_declaration] = "DW_TAG_access_declaration", - [DW_TAG_base_type] = "DW_TAG_base_type", - [DW_TAG_catch_block] = "DW_TAG_catch_block", - [DW_TAG_const_type] = "DW_TAG_const_type", - [DW_TAG_constant] = "DW_TAG_constant", - [DW_TAG_enumerator] = "DW_TAG_enumerator", - [DW_TAG_file_type] = "DW_TAG_file_type", - [DW_TAG_friend] = "DW_TAG_friend", - [DW_TAG_namelist] = "DW_TAG_namelist", - [DW_TAG_namelist_item] = "DW_TAG_namelist_item", - [DW_TAG_packed_type] = "DW_TAG_packed_type", - [DW_TAG_subprogram] = "DW_TAG_subprogram", - [DW_TAG_template_type_parameter] = "DW_TAG_template_type_parameter", - [DW_TAG_template_value_parameter] = "DW_TAG_template_value_parameter", - [DW_TAG_thrown_type] = "DW_TAG_thrown_type", - [DW_TAG_try_block] = "DW_TAG_try_block", - [DW_TAG_variant_part] = "DW_TAG_variant_part", - [DW_TAG_variable] = "DW_TAG_variable", - [DW_TAG_volatile_type] = "DW_TAG_volatile_type", - [DW_TAG_dwarf_procedure] = "DW_TAG_dwarf_procedure", - [DW_TAG_restrict_type] = "DW_TAG_restrict_type", - [DW_TAG_interface_type] = "DW_TAG_interface_type", - [DW_TAG_namespace] = "DW_TAG_namespace", - [DW_TAG_imported_module] = "DW_TAG_imported_module", - [DW_TAG_unspecified_type] = "DW_TAG_unspecified_type", - [DW_TAG_partial_unit] = "DW_TAG_partial_unit", - [DW_TAG_imported_unit] = "DW_TAG_imported_unit", - [DW_TAG_mutable_type] = "DW_TAG_mutable_type", - [DW_TAG_condition] = "DW_TAG_condition", - [DW_TAG_shared_type] = "DW_TAG_shared_type", -}; -#define ntagnames (sizeof (tagnames) / sizeof (tagnames[0])) - - -const struct -{ - int code; - const char *name; -} attrs[] = + switch (tag) + { +#define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_TAG +#undef ONE_KNOWN_DW_TAG + default: + return NULL; + } +} + +static const char * +dwarf_attr_string (unsigned int attrnum) { - { DW_AT_sibling, "sibling" }, - { DW_AT_location, "location" }, - { DW_AT_name, "name" }, - { DW_AT_ordering, "ordering" }, - { DW_AT_subscr_data, "subscr_data" }, - { DW_AT_byte_size, "byte_size" }, - { DW_AT_bit_offset, "bit_offset" }, - { DW_AT_bit_size, "bit_size" }, - { DW_AT_element_list, "element_list" }, - { DW_AT_stmt_list, "stmt_list" }, - { DW_AT_low_pc, "low_pc" }, - { DW_AT_high_pc, "high_pc" }, - { DW_AT_language, "language" }, - { DW_AT_member, "member" }, - { DW_AT_discr, "discr" }, - { DW_AT_discr_value, "discr_value" }, - { DW_AT_visibility, "visibility" }, - { DW_AT_import, "import" }, - { DW_AT_string_length, "string_length" }, - { DW_AT_common_reference, "common_reference" }, - { DW_AT_comp_dir, "comp_dir" }, - { DW_AT_const_value, "const_value" }, - { DW_AT_containing_type, "containing_type" }, - { DW_AT_default_value, "default_value" }, - { DW_AT_inline, "inline" }, - { DW_AT_is_optional, "is_optional" }, - { DW_AT_lower_bound, "lower_bound" }, - { DW_AT_producer, "producer" }, - { DW_AT_prototyped, "prototyped" }, - { DW_AT_return_addr, "return_addr" }, - { DW_AT_start_scope, "start_scope" }, - { DW_AT_bit_stride, "bit_stride" }, - { DW_AT_upper_bound, "upper_bound" }, - { DW_AT_abstract_origin, "abstract_origin" }, - { DW_AT_accessibility, "accessibility" }, - { DW_AT_address_class, "address_class" }, - { DW_AT_artificial, "artificial" }, - { DW_AT_base_types, "base_types" }, - { DW_AT_calling_convention, "calling_convention" }, - { DW_AT_count, "count" }, - { DW_AT_data_member_location, "data_member_location" }, - { DW_AT_decl_column, "decl_column" }, - { DW_AT_decl_file, "decl_file" }, - { DW_AT_decl_line, "decl_line" }, - { DW_AT_declaration, "declaration" }, - { DW_AT_discr_list, "discr_list" }, - { DW_AT_encoding, "encoding" }, - { DW_AT_external, "external" }, - { DW_AT_frame_base, "frame_base" }, - { DW_AT_friend, "friend" }, - { DW_AT_identifier_case, "identifier_case" }, - { DW_AT_macro_info, "macro_info" }, - { DW_AT_namelist_item, "namelist_item" }, - { DW_AT_priority, "priority" }, - { DW_AT_segment, "segment" }, - { DW_AT_specification, "specification" }, - { DW_AT_static_link, "static_link" }, - { DW_AT_type, "type" }, - { DW_AT_use_location, "use_location" }, - { DW_AT_variable_parameter, "variable_parameter" }, - { DW_AT_virtuality, "virtuality" }, - { DW_AT_vtable_elem_location, "vtable_elem_location" }, - { DW_AT_allocated, "allocated" }, - { DW_AT_associated, "associated" }, - { DW_AT_data_location, "data_location" }, - { DW_AT_byte_stride, "byte_stride" }, - { DW_AT_entry_pc, "entry_pc" }, - { DW_AT_use_UTF8, "use_UTF8" }, - { DW_AT_extension, "extension" }, - { DW_AT_ranges, "ranges" }, - { DW_AT_trampoline, "trampoline" }, - { DW_AT_call_column, "call_column" }, - { DW_AT_call_file, "call_file" }, - { DW_AT_call_line, "call_line" }, - { DW_AT_description, "description" }, - { DW_AT_binary_scale, "binary_scale" }, - { DW_AT_decimal_scale, "decimal_scale" }, - { DW_AT_small, "small" }, - { DW_AT_decimal_sign, "decimal_sign" }, - { DW_AT_digit_count, "digit_count" }, - { DW_AT_picture_string, "picture_string" }, - { DW_AT_mutable, "mutable" }, - { DW_AT_threads_scaled, "threads_scaled" }, - { DW_AT_explicit, "explicit" }, - { DW_AT_object_pointer, "object_pointer" }, - { DW_AT_endianity, "endianity" }, - { DW_AT_elemental, "elemental" }, - { DW_AT_pure, "pure" }, - { DW_AT_recursive, "recursive" }, - { DW_AT_MIPS_fde, "MIPS_fde" }, - { DW_AT_MIPS_loop_begin, "MIPS_loop_begin" }, - { DW_AT_MIPS_tail_loop_begin, "MIPS_tail_loop_begin" }, - { DW_AT_MIPS_epilog_begin, "MIPS_epilog_begin" }, - { DW_AT_MIPS_loop_unroll_factor, "MIPS_loop_unroll_factor" }, - { DW_AT_MIPS_software_pipeline_depth, "MIPS_software_pipeline_depth" }, - { DW_AT_MIPS_linkage_name, "MIPS_linkage_name" }, - { DW_AT_MIPS_stride, "MIPS_stride" }, - { DW_AT_MIPS_abstract_name, "MIPS_abstract_name" }, - { DW_AT_MIPS_clone_origin, "MIPS_clone_origin" }, - { DW_AT_MIPS_has_inlines, "MIPS_has_inlines" }, - { DW_AT_MIPS_stride_byte, "MIPS_stride_byte" }, - { DW_AT_MIPS_stride_elem, "MIPS_stride_elem" }, - { DW_AT_MIPS_ptr_dopetype, "MIPS_ptr_dopetype" }, - { DW_AT_MIPS_allocatable_dopetype, "MIPS_allocatable_dopetype" }, - { DW_AT_MIPS_assumed_shape_dopetype, "MIPS_assumed_shape_dopetype" }, - { DW_AT_MIPS_assumed_size, "MIPS_assumed_size" }, - { DW_AT_sf_names, "sf_names" }, - { DW_AT_src_info, "src_info" }, - { DW_AT_mac_info, "mac_info" }, - { DW_AT_src_coords, "src_coords" }, - { DW_AT_body_begin, "body_begin" }, - { DW_AT_body_end, "body_end" }, -}; -#define nattrs (sizeof (attrs) / sizeof (attrs[0])) + switch (attrnum) + { +#define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_AT +#undef ONE_KNOWN_DW_AT + default: + return NULL; + } +}
void @@ -230,9 +72,8 @@ handle (Dwarf *dbg, Dwarf_Die *die, int n) tag = dwarf_tag (die); if (tag != DW_TAG_invalid) { - if (tag < ntagnames) - str = tagnames[tag]; - else + str = dwarf_tag_string (tag); + if (str == NULL) { snprintf (buf, sizeof buf, "%#x", tag); str = buf; @@ -248,15 +89,15 @@ handle (Dwarf *dbg, Dwarf_Die *die, int n) off = dwarf_dieoffset (die); cuoff = dwarf_cuoffset (die);
- printf ("%*s%s\n", n * 5, "", str); + printf ("%*sDW_TAG_%s\n", n * 5, "", str); printf ("%*s Name : %s\n", n * 5, "", name); printf ("%*s Offset : %lld\n", n * 5, "", (long long int) off); printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);
printf ("%*s Attrs :", n * 5, ""); - for (cnt = 0; cnt < nattrs; ++cnt) - if (dwarf_hasattr (die, attrs[cnt].code)) - printf (" %s", attrs[cnt].name); + for (cnt = 0; cnt < 0xffff; ++cnt) + if (dwarf_hasattr (die, cnt)) + printf (" %s", dwarf_attr_string (cnt)); puts ("");
if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
Introduce dwarf_access_string, dwarf_attr_string, dwarf_calling_convention_string, dwarf_discr_list_string, dwarf_encoding_string, dwarf_form_string, dwarf_identifier_case_string, dwarf_inline_string, dwarf_lang_string, dwarf_line_extended_opcode_string, dwarf_line_standard_opcode_string, dwarf_locexpr_opcode_string, dwarf_ordering_string, dwarf_tag_string, dwarf_virtuality_string, dwarf_visibility_string from dwarf branch.
Remove similar functions from readelf and tests.
Signed-off-by: Mark Wielaard mjw@redhat.com --- libdw/ChangeLog | 41 +++++ libdw/Makefile.am | 12 ++- libdw/dwarf_access_string.c | 51 +++++++ libdw/dwarf_attr_string.c | 48 ++++++ libdw/dwarf_calling_convention_string.c | 51 +++++++ libdw/dwarf_discr_list_string.c | 51 +++++++ libdw/dwarf_encoding_string.c | 51 +++++++ libdw/dwarf_form_string.c | 50 ++++++ libdw/dwarf_identifier_case_string.c | 51 +++++++ libdw/dwarf_inline_string.c | 51 +++++++ libdw/dwarf_lang_string.c | 48 ++++++ libdw/dwarf_line_extended_opcode_string.c | 52 +++++++ libdw/dwarf_line_standard_opcode_string.c | 52 +++++++ libdw/dwarf_locexpr_opcode_string.c | 57 +++++++ libdw/dwarf_ordering_string.c | 51 +++++++ libdw/dwarf_tag_string.c | 48 ++++++ libdw/dwarf_virtuality_string.c | 51 +++++++ libdw/dwarf_visibility_string.c | 51 +++++++ libdw/libdw.h | 79 ++++++++++- libdw/libdw.map | 20 +++ src/ChangeLog | 17 ++ src/readelf.c | 234 ----------------------------- tests/ChangeLog | 6 + tests/allregs.c | 20 +--- tests/show-die-info.c | 28 ---- 25 files changed, 988 insertions(+), 283 deletions(-) create mode 100644 libdw/dwarf_access_string.c create mode 100644 libdw/dwarf_attr_string.c create mode 100644 libdw/dwarf_calling_convention_string.c create mode 100644 libdw/dwarf_discr_list_string.c create mode 100644 libdw/dwarf_encoding_string.c create mode 100644 libdw/dwarf_form_string.c create mode 100644 libdw/dwarf_identifier_case_string.c create mode 100644 libdw/dwarf_inline_string.c create mode 100644 libdw/dwarf_lang_string.c create mode 100644 libdw/dwarf_line_extended_opcode_string.c create mode 100644 libdw/dwarf_line_standard_opcode_string.c create mode 100644 libdw/dwarf_locexpr_opcode_string.c create mode 100644 libdw/dwarf_ordering_string.c create mode 100644 libdw/dwarf_tag_string.c create mode 100644 libdw/dwarf_virtuality_string.c create mode 100644 libdw/dwarf_visibility_string.c
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 89009f0..e61a961 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,5 +1,46 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * Makefile.am (libdw_a_SOURCES): Add dwarf_aggregate_size.c, + dwarf_getlocation_implicit_pointer.c, + dwarf_access_string.c, dwarf_inline_string.c, + dwarf_attr_string.c dwarf_lang_string.c, + dwarf_calling_convention_string.c, + dwarf_line_extended_opcode_string.c, + dwarf_discr_list_string.c, + dwarf_line_standard_opcode_string.c, + dwarf_encoding_string.c dwarf_locexpr_opcode_string.c, + dwarf_form_string.c dwarf_ordering_string.c, + dwarf_tag_string.c dwarf_virtuality_string.c, + dwarf_identifier_case_string.c and dwarf_visibility_string.c + * dwarf_access_string.c: New file. + * dwarf_attr_string.c: Likewise. + * dwarf_calling_convention_string.c: Likewise. + * dwarf_discr_list_string.c: Likewise. + * dwarf_encoding_string.c: Likewise. + * dwarf_form_string.c: Likewise. + * dwarf_identifier_case_string.c: Likewise. + * dwarf_inline_string.c: Likewise. + * dwarf_lang_string.c: Likewise. + * dwarf_line_extended_opcode_string.c: Likewise. + * dwarf_line_standard_opcode_string.c: Likewise. + * dwarf_locexpr_opcode_string.c: Likewise. + * dwarf_ordering_string.c: Likewise. + * dwarf_tag_string.c: Likewise. + * dwarf_virtuality_string.c: Likewise. + * dwarf_visibility_string.c: Likewise. + * libdw.h: Declare dwarf_tag_string, dwarf_attr_string, + dwarf_lang_string, dwarf_inline_string, dwarf_encoding_string, + dwarf_access_string, dwarf_visibility_string, + dwarf_virtuality_string, dwarf_identifier_case_string, + dwarf_calling_convention_string, dwarf_ordering_string, + dwarf_discr_list_string, dwarf_locexpr_opcode_string, + dwarf_line_standard_opcode_string and + dwarf_line_extended_opcode_string. + * libdw.map (ELFUTILS_0.155): New symbol version directive for + new functions. + +2012-08-16 Mark Wielaard mjw@redhat.com + * Makefile.am (EXTRA_DIST): Add known-dwarf.h. * dwarf.h (DW_LANG_Go): Update comment. (DW_LANG_Mips_Assembler): Likewise. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index c6ac264..f695e89 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -87,7 +87,17 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \ dwarf_cfi_addrframe.c \ dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ - dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c + dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \ + dwarf_access_string.c dwarf_inline_string.c \ + dwarf_attr_string.c dwarf_lang_string.c \ + dwarf_calling_convention_string.c \ + dwarf_line_extended_opcode_string.c \ + dwarf_discr_list_string.c \ + dwarf_line_standard_opcode_string.c \ + dwarf_encoding_string.c dwarf_locexpr_opcode_string.c \ + dwarf_form_string.c dwarf_ordering_string.c \ + dwarf_tag_string.c dwarf_virtuality_string.c \ + dwarf_identifier_case_string.c dwarf_visibility_string.c
if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_access_string.c b/libdw/dwarf_access_string.c new file mode 100644 index 0000000..6ad6e24 --- /dev/null +++ b/libdw/dwarf_access_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_access_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ACCESS +#undef ONE_KNOWN_DW_ACCESS + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_attr_string.c b/libdw/dwarf_attr_string.c new file mode 100644 index 0000000..a7c4ce4 --- /dev/null +++ b/libdw/dwarf_attr_string.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_attr_string (unsigned int attrnum) +{ + switch (attrnum) + { +#define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_AT +#undef ONE_KNOWN_DW_AT + default: + return NULL; + } +} diff --git a/libdw/dwarf_calling_convention_string.c b/libdw/dwarf_calling_convention_string.c new file mode 100644 index 0000000..f91fdef --- /dev/null +++ b/libdw/dwarf_calling_convention_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_calling_convention_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_CC +#undef ONE_KNOWN_DW_CC + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_discr_list_string.c b/libdw/dwarf_discr_list_string.c new file mode 100644 index 0000000..8967052 --- /dev/null +++ b/libdw/dwarf_discr_list_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_discr_list_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_DSC +#undef ONE_KNOWN_DW_DSC + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_encoding_string.c b/libdw/dwarf_encoding_string.c new file mode 100644 index 0000000..299957e --- /dev/null +++ b/libdw/dwarf_encoding_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_encoding_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ATE +#undef ONE_KNOWN_DW_ATE + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_form_string.c b/libdw/dwarf_form_string.c new file mode 100644 index 0000000..178f1df --- /dev/null +++ b/libdw/dwarf_form_string.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_form_string (unsigned int form) +{ + switch (form) + { +#define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE) +#define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_FORM +#undef ONE_KNOWN_DW_FORM +#undef ONE_KNOWN_DW_FORM_DESC + default: + return NULL; + } +} diff --git a/libdw/dwarf_identifier_case_string.c b/libdw/dwarf_identifier_case_string.c new file mode 100644 index 0000000..53bcde4 --- /dev/null +++ b/libdw/dwarf_identifier_case_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_identifier_case_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ID +#undef ONE_KNOWN_DW_ID + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_inline_string.c b/libdw/dwarf_inline_string.c new file mode 100644 index 0000000..04c18a2 --- /dev/null +++ b/libdw/dwarf_inline_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_inline_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_INL +#undef ONE_KNOWN_DW_INL + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_lang_string.c b/libdw/dwarf_lang_string.c new file mode 100644 index 0000000..d6dd288 --- /dev/null +++ b/libdw/dwarf_lang_string.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_lang_string (unsigned int lang) +{ + switch (lang) + { +#define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME; + ALL_KNOWN_DW_LANG +#undef ONE_KNOWN_DW_LANG_DESC + default: + return NULL; + } +} diff --git a/libdw/dwarf_line_extended_opcode_string.c b/libdw/dwarf_line_extended_opcode_string.c new file mode 100644 index 0000000..c90061a --- /dev/null +++ b/libdw/dwarf_line_extended_opcode_string.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_line_extended_opcode_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_LNE(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_LNE +#undef ONE_KNOWN_DW_LNE + }; + + const char *ret = NULL; + if (likely (code < sizeof (known) / sizeof (known[0]))) + ret = known[code]; + + return ret; +} diff --git a/libdw/dwarf_line_standard_opcode_string.c b/libdw/dwarf_line_standard_opcode_string.c new file mode 100644 index 0000000..b154ec3 --- /dev/null +++ b/libdw/dwarf_line_standard_opcode_string.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_line_standard_opcode_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_LNS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_LNS +#undef ONE_KNOWN_DW_LNS + }; + + const char *ret = NULL; + if (likely (code < sizeof (known) / sizeof (known[0]))) + ret = known[code]; + + return ret; +} diff --git a/libdw/dwarf_locexpr_opcode_string.c b/libdw/dwarf_locexpr_opcode_string.c new file mode 100644 index 0000000..06a24b0 --- /dev/null +++ b/libdw/dwarf_locexpr_opcode_string.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_locexpr_opcode_string (unsigned int code) +{ + static const char *const known[] = + { + /* Normally we can't affort building huge table of 64K entries, + most of them zero, just because there are a couple defined + values at the far end. In case of opcodes, it's OK. */ +#define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE) +#define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_OP +#undef ONE_KNOWN_DW_OP +#undef ONE_KNOWN_DW_OP_DESC + }; + + const char *ret = NULL; + if (likely (code < sizeof (known) / sizeof (known[0]))) + ret = known[code]; + + return ret; +} diff --git a/libdw/dwarf_ordering_string.c b/libdw/dwarf_ordering_string.c new file mode 100644 index 0000000..4c8abc6 --- /dev/null +++ b/libdw/dwarf_ordering_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_ordering_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_ORD +#undef ONE_KNOWN_DW_ORD + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_tag_string.c b/libdw/dwarf_tag_string.c new file mode 100644 index 0000000..ad26326 --- /dev/null +++ b/libdw/dwarf_tag_string.c @@ -0,0 +1,48 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_tag_string (unsigned int tag) +{ + switch (tag) + { +#define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; + ALL_KNOWN_DW_TAG +#undef ONE_KNOWN_DW_TAG + default: + return NULL; + } +} diff --git a/libdw/dwarf_virtuality_string.c b/libdw/dwarf_virtuality_string.c new file mode 100644 index 0000000..129e0fd --- /dev/null +++ b/libdw/dwarf_virtuality_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_virtuality_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_VIRTUALITY +#undef ONE_KNOWN_DW_VIRTUALITY + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_visibility_string.c b/libdw/dwarf_visibility_string.c new file mode 100644 index 0000000..ce99a5e --- /dev/null +++ b/libdw/dwarf_visibility_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_visibility_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_VIS +#undef ONE_KNOWN_DW_VIS + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/libdw.h b/libdw/libdw.h index f5fc4e2..4ed3a45 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -1,5 +1,5 @@ /* Interfaces for libdw. - Copyright (C) 2002-2010 Red Hat, Inc. + Copyright (C) 2002-2010, 2012 Red Hat, Inc. This file is part of elfutils.
This file is free software; you can redistribute it and/or modify @@ -830,6 +830,83 @@ extern const char *dwarf_errmsg (int err); extern Dwarf_OOM dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler);
+/* Returns the tag name, without the DW_TAG_ prefix, if known. + Returns NULL if the given tag code is unknown. */ +extern const char *dwarf_tag_string (unsigned int code); + +/* Returns the attribute name, without the DW_AT_ prefix, if known. + Returns NULL if the given attribute code is unknown. */ +extern const char *dwarf_attr_string (unsigned int code); + +/* Returns the form name, without the DW_FORM_ prefix, if known. + Returns NULL if the given form code is unknown. */ +extern const char *dwarf_form_string (unsigned int code); + +/* Returns the language name, without the DW_LANG_ prefix, if known. + Returns NULL if the given language code is unknown. */ +extern const char *dwarf_lang_string (unsigned int code); + +/* Returns the inline name, without the DW_INL_ prefix, as used with + the DW_AT_inline attribute, if known. Returns NULL if the given + DW_LANG code is unknown. */ +extern const char *dwarf_inline_string (unsigned int code); + +/* Returns the encoding name, without the DW_ATE_ prefix, as used with + the DW_AT_encoding attribute, if known. Returns NULL if the given + DW_ATE code is unknown. */ +extern const char *dwarf_encoding_string (unsigned int code); + +/* Returns the access name, without the DW_ACCESS_ prefix, as used with + the DW_AT_accessibility attribute, if known. Returns NULL if the given + DW_ACCESS code is unknown. */ +extern const char *dwarf_access_string (unsigned int code); + +/* Returns the access name, without the DW_VIS_ prefix, as used with + the DW_AT_visibility attribute, if known. Returns NULL if the given + DW_VIS code is unknown. */ +extern const char *dwarf_visibility_string (unsigned int code); + +/* Returns the virtuality name, with the DW_VIRTUALITY_ prefix, as used + with the DW_AT_virtuality attribute, if known. Returns NULL if the + given DW_VIRTUALITY code is unknown. */ +extern const char *dwarf_virtuality_string (unsigned int code); + +/* Returns the identifier case name, without the DW_ID_ prefix, as used + with the DW_AT_identifier_case attribute, if known. Returns NULL if + the given DW_ID code is unknown. */ +extern const char *dwarf_identifier_case_string (unsigned int code); + +/* Returns the calling convention name, without the DW_CC_ prefix, as + used with the DW_AT_calling_convention attribute, if known. Returns + NULL if the given DW_CC code is unknown. */ +extern const char *dwarf_calling_convention_string (unsigned int code); + +/* Returns the ordering name, without the DW_ORD_ prefix, as + used with the DW_AT_ordering attribute, if known. Returns + NULL if the given DW_CC code is unknown. */ +extern const char *dwarf_ordering_string (unsigned int code); + +/* Returns the discriminant list name, without the DW_ORD_ prefix, as + used in the DW_AT_ordering attribute block, if known. Returns + NULL if the given DW_CC code is unknown. */ +extern const char *dwarf_discr_list_string (unsigned int code); + +/* Returns the operation name, without the DW_OP_ prefix, as + used in a DWARF location expression block, if known. Returns + NULL if the given DW_OP code is unknown. */ +extern const char *dwarf_locexpr_opcode_string (unsigned int code); + +/* Returns the standard line information opcode name, without the + DW_LNS_ prefix, as used in the line number program instructions, + if known. Returns NULL if the given DW_LNS opcode is unknown. */ +extern const char *dwarf_line_standard_opcode_string (unsigned int code); + +/* Returns the extended line information opcode name, without the + DW_LNE_ prefix, as used in the line number program instructions, + if known. Returns NULL if the given DW_LNE opcode is unknown. */ +extern const char *dwarf_line_extended_opcode_string (unsigned int code); + + /* Inline optimizations. */ #ifdef __OPTIMIZE__ /* Return attribute code of given attribute. */ diff --git a/libdw/libdw.map b/libdw/libdw.map index 1f71d03..c3d7c25 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -254,3 +254,23 @@ ELFUTILS_0.149 {
dwfl_dwarf_line; } ELFUTILS_0.148; + +ELFUTILS_0.155 { + global: + dwarf_tag_string; + dwarf_attr_string; + dwarf_form_string; + dwarf_lang_string; + dwarf_inline_string; + dwarf_encoding_string; + dwarf_access_string; + dwarf_visibility_string; + dwarf_virtuality_string; + dwarf_identifier_case_string; + dwarf_calling_convention_string; + dwarf_ordering_string; + dwarf_discr_list_string; + dwarf_locexpr_opcode_string; + dwarf_line_standard_opcode_string; + dwarf_line_extended_opcode_string; +} ELFUTILS_0.149; diff --git a/src/ChangeLog b/src/ChangeLog index 725554d..1b06ea2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,22 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * readelf.c (dwarf_tag_string): Removed. + (dwarf_attr_string): Likewise. + (dwarf_form_string): Likewise. + (dwarf_lang_string): Likewise. + (dwarf_inline_string): Likewise. + (dwarf_encoding_string): Likewise. + (dwarf_access_string): Likewise. + (dwarf_visibility_string): Likewise. + (dwarf_virtuality_string): Likewise. + (dwarf_identifier_case_string): Likewise. + (dwarf_calling_convention_string): Likewise. + (dwarf_ordering_string): Likewise. + (dwarf_discr_list_string): Likewise. + (dwarf_locexpr_opcode_string): Likewise. + +2012-08-16 Mark Wielaard mjw@redhat.com + * readelf.c (dwarf_tag_name): Renamed from dwarf_tag_string. Uses new dwarf_tag_string or adds ??? or lo_user+%#x when appropriate. diff --git a/src/readelf.c b/src/readelf.c index dc49669..34ccbf5 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -51,8 +51,6 @@ #include "../libdwfl/libdwflP.h" #include "../libdw/memory-access.h"
-#include "../libdw/known-dwarf.h" -
/* Name and version of program. */ static void print_version (FILE *stream, struct argp_state *state); @@ -3183,238 +3181,6 @@ format_dwarf_addr (Dwfl_Module *dwflmod, return result; }
-static const char * -dwarf_tag_string (unsigned int tag) -{ - switch (tag) - { -#define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; - ALL_KNOWN_DW_TAG -#undef ONE_KNOWN_DW_TAG - default: - return NULL; - } -} - - -static const char * -dwarf_attr_string (unsigned int attrnum) -{ - switch (attrnum) - { -#define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; - ALL_KNOWN_DW_AT -#undef ONE_KNOWN_DW_AT - default: - return NULL; - } -} - - -static const char * -dwarf_form_string (unsigned int form) -{ - switch (form) - { -#define ONE_KNOWN_DW_FORM_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_FORM (NAME, CODE) -#define ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME; - ALL_KNOWN_DW_FORM -#undef ONE_KNOWN_DW_FORM -#undef ONE_KNOWN_DW_FORM_DESC - default: - return NULL; - } -} - - -static const char * -dwarf_lang_string (unsigned int lang) -{ - switch (lang) - { -#define ONE_KNOWN_DW_LANG_DESC(NAME, CODE, DESC) case CODE: return #NAME; - ALL_KNOWN_DW_LANG -#undef ONE_KNOWN_DW_LANG_DESC - default: - return NULL; - } -} - - -static const char * -dwarf_inline_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_INL -#undef ONE_KNOWN_DW_INL - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_encoding_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_ATE -#undef ONE_KNOWN_DW_ATE - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_access_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_ACCESS -#undef ONE_KNOWN_DW_ACCESS - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_visibility_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_VIS -#undef ONE_KNOWN_DW_VIS - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_virtuality_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_VIRTUALITY -#undef ONE_KNOWN_DW_VIRTUALITY - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_identifier_case_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_ID -#undef ONE_KNOWN_DW_ID - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_calling_convention_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_CC -#undef ONE_KNOWN_DW_CC - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_ordering_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_ORD -#undef ONE_KNOWN_DW_ORD - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_discr_list_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_DSC -#undef ONE_KNOWN_DW_DSC - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} - - -static const char * -dwarf_locexpr_opcode_string (unsigned int code) -{ - static const char *const known[] = - { - /* Normally we can't affort building huge table of 64K entries, - most of them zero, just because there are a couple defined - values at the far end. In case of opcodes, it's OK. */ -#define ONE_KNOWN_DW_OP_DESC(NAME, CODE, DESC) ONE_KNOWN_DW_OP (NAME, CODE) -#define ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_OP -#undef ONE_KNOWN_DW_OP -#undef ONE_KNOWN_DW_OP_DESC - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} -
/* Used by all dwarf_foo_name functions. */ static const char * diff --git a/tests/ChangeLog b/tests/ChangeLog index f0c83e6..1c5d921 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,11 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * allregs.c (dwarf_encoding_string): Removed. + * show-die-info.c (dwarf_tag_string): Removed. + (dwarf_attr_string): Removed. + +2012-08-16 Mark Wielaard mjw@redhat.com + * allregs.c (dwarf_encoding_string): Rewritten using known-dwarf macros. * show-die-info.c (tagnames): Removed. diff --git a/tests/allregs.c b/tests/allregs.c index b103ce1..85bcb5c 100644 --- a/tests/allregs.c +++ b/tests/allregs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005, 2006 Red Hat, Inc. +/* Copyright (C) 2005, 2006, 2012 Red Hat, Inc. This file is part of elfutils.
This file is free software; you can redistribute it and/or modify @@ -28,24 +28,6 @@ #include ELFUTILS_HEADER(dwfl) #include <dwarf.h>
-#include "../libdw/known-dwarf.h" - -static const char * -dwarf_encoding_string (unsigned int code) -{ - static const char *const known[] = - { -#define ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME, - ALL_KNOWN_DW_ATE -#undef ONE_KNOWN_DW_ATE - }; - - if (likely (code < sizeof (known) / sizeof (known[0]))) - return known[code]; - - return NULL; -} -
static int first_module (Dwfl_Module *mod, diff --git a/tests/show-die-info.c b/tests/show-die-info.c index 0c298ac..624a71d 100644 --- a/tests/show-die-info.c +++ b/tests/show-die-info.c @@ -26,34 +26,6 @@ #include <string.h> #include <unistd.h>
-#include "../libdw/known-dwarf.h" - -static const char * -dwarf_tag_string (unsigned int tag) -{ - switch (tag) - { -#define ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME; - ALL_KNOWN_DW_TAG -#undef ONE_KNOWN_DW_TAG - default: - return NULL; - } -} - -static const char * -dwarf_attr_string (unsigned int attrnum) -{ - switch (attrnum) - { -#define ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME; - ALL_KNOWN_DW_AT -#undef ONE_KNOWN_DW_AT - default: - return NULL; - } -} -
void handle (Dwarf *dbg, Dwarf_Die *die, int n)
Signed-off-by: Mark Wielaard mjw@redhat.com --- tests/ChangeLog | 6 ++++++ tests/Makefile.am | 4 +++- tests/run-readelf-unknown-self.sh | 21 +++++++++++++++++++++ tests/test-subr.sh | 28 ++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletions(-) create mode 100755 tests/run-readelf-unknown-self.sh
diff --git a/tests/ChangeLog b/tests/ChangeLog index 1c5d921..444ca3c 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,11 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * run-readelf-unknown-self.sh: New test. + * Makefile.am (TESTS): Add run-readelf-unknown-self.sh. + (EXTRA_DIST): Likewise. + +2012-08-16 Mark Wielaard mjw@redhat.com + * allregs.c (dwarf_encoding_string): Removed. * show-die-info.c (dwarf_tag_string): Removed. (dwarf_attr_string): Removed. diff --git a/tests/Makefile.am b/tests/Makefile.am index df66db6..0570569 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,7 +73,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \ run-nm-self.sh run-readelf-self.sh \ run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ run-readelf-test4.sh run-readelf-twofiles.sh \ - run-readelf-macro.sh run-readelf-dwz-multi.sh \ + run-readelf-unknown-self.sh run-readelf-macro.sh \ + run-readelf-dwz-multi.sh \ run-native-test.sh run-bug1-test.sh \ dwfl-bug-addr-overflow run-addrname-test.sh \ dwfl-bug-fd-leak dwfl-bug-report \ @@ -132,6 +133,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ coverage.sh test-subr.sh test-wrapper.sh \ run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ run-readelf-test4.sh run-readelf-twofiles.sh \ + run-readelf-unknown-self.sh \ run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ testfile29.bz2 testfile29.rdwr.bz2 \ testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ diff --git a/tests/run-readelf-unknown-self.sh b/tests/run-readelf-unknown-self.sh new file mode 100755 index 0000000..8e4ccce --- /dev/null +++ b/tests/run-readelf-unknown-self.sh @@ -0,0 +1,21 @@ +#! /bin/sh +# Copyright (C) 2012 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/. + +. $srcdir/test-subr.sh + +# Make sure there are no unknown DWARF codes. +testrun_on_self_nomatch "??? ([x0-9]+)|lo_user+0x[0-9a-f]+" ../src/readelf -N -w diff --git a/tests/test-subr.sh b/tests/test-subr.sh index ff29136..e05d22a 100644 --- a/tests/test-subr.sh +++ b/tests/test-subr.sh @@ -136,3 +136,31 @@ testrun_on_self_quiet() # Only exit if something failed if test $exit_status != 0; then exit $exit_status; fi } + +# Make sure the testrun doesn't contain some regular expression output. +# First argument is an egrep regular expression, the rest is the command +# to run on all self test files. +testrun_on_self_nomatch() +{ + pattern="$1" + shift + + exit_status=0 + tempfiles self_matches.in self_matches.out + + for file in $self_test_files; do + testrun "$@" $file > self_matches.in + # egrep should fail to match anything, but we also want to show + # what it matched if it doesn't fail, so save output. + grep_ok=0 + egrep -o "$pattern" < self_matches.in > self_matches.out || grep_ok=1 + if test $grep_ok == 0; then + echo "*** failure in $* $file" + sort -u self_matches.out + exit_status=1; + fi + done + + # Only exit if something failed + test $exit_status == 0 || exit $exit_status +}
--- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,11 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
- run-readelf-unknown-self.sh: New test.
- Makefile.am (TESTS): Add run-readelf-unknown-self.sh.
- (EXTRA_DIST): Likewise.
+2012-08-16 Mark Wielaard mjw@redhat.com
(dwarf_attr_string): Removed.
- allregs.c (dwarf_encoding_string): Removed.
- show-die-info.c (dwarf_tag_string): Removed.
No redundant header lines when the previous top change has the same header.
+# Make sure there are no unknown DWARF codes. +testrun_on_self_nomatch "??? ([x0-9]+)|lo_user+0x[0-9a-f]+" ../src/readelf -N -w
This is still "" and should be ''.
- for file in $self_test_files; do
- testrun "$@" $file > self_matches.in
This should fail the test if testrun (i.e. readelf) exits nonzero.
exit_status=1;
Still superfluous ; here.
Did you resend the old version of the patch instead of a new one?
Thanks, Roland
On Thu, 2012-08-16 at 16:34 -0700, Roland McGrath wrote:
Did you resend the old version of the patch instead of a new one?
Looks like git played some tricks on me. I'll stash this patch for now and come back to it later after we dealt with the actual dwarf strings functions patch itself.
Thanks,
Mark
Only build and tested by self tests if a g++ with C++x0 is available. Almost empty C++ program, can be extended to test more features.
Signed-off-by: Mark Wielaard mjw@redhat.com --- ChangeLog | 4 ++ configure.ac | 5 ++ m4/ChangeLog | 4 ++ m4/ax_cxx_compile_stdcxx_0x.m4 | 107 ++++++++++++++++++++++++++++++++++++++++ tests/ChangeLog | 10 ++++ tests/Makefile.am | 6 ++ tests/cxx-various.cc | 65 ++++++++++++++++++++++++ tests/test-subr.sh | 12 +++++ tests/testfile-cxx-various.bz2 | Bin 0 -> 11377 bytes 9 files changed, 213 insertions(+), 0 deletions(-) create mode 100644 m4/ax_cxx_compile_stdcxx_0x.m4 create mode 100644 tests/cxx-various.cc create mode 100755 tests/testfile-cxx-various.bz2
diff --git a/ChangeLog b/ChangeLog index 5842492..3f8598b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2012-08-16 Mark Wielaard mjw@redhat.com + + * configure.ac: Add AX_CXX_COMPILE_STDCXX_0X check. + 2012-07-24 Mark Wielaard mjw@redhat.com
* TODO: Add note on shdrs after elf_cntl (ELF_C_FDREAD). diff --git a/configure.ac b/configure.ac index 7932489..50db343 100644 --- a/configure.ac +++ b/configure.ac @@ -72,6 +72,11 @@ AC_PROG_RANLIB AC_PROG_YACC AM_PROG_LEX
+# Check whether we can use g++ with -std=c++0x for the test. +AC_PROG_CXX +AX_CXX_COMPILE_STDCXX_0X +AM_CONDITIONAL(HAVE_STDCXX_0X, test "x$ax_cv_cxx_compile_cxx0x_cxx" == "xyes") + AC_CACHE_CHECK([for gcc with C99 support], ac_cv_c99, [dnl old_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -std=gnu99" diff --git a/m4/ChangeLog b/m4/ChangeLog index d4f2bc1..d00fd9e 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2012-08-16 Mark Wielaard mjw@redhat.com + + * ax_cxx_compile_stdcxx_0x.m4: Add from autoconf-archive. + 2010-04-14 Roland McGrath roland@redhat.com
* gettext.m4: Upgrade to gettext-0.17. diff --git a/m4/ax_cxx_compile_stdcxx_0x.m4 b/m4/ax_cxx_compile_stdcxx_0x.m4 new file mode 100644 index 0000000..a4e556f --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx_0x.m4 @@ -0,0 +1,107 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_0X +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++0x +# standard. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik bkoz@redhat.com +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X]) +AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [ + AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, + ax_cv_cxx_compile_cxx0x_native, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c);],, + ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no) + AC_LANG_RESTORE + ]) + + AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, + ax_cv_cxx_compile_cxx0x_cxx, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -std=c++0x" + AC_TRY_COMPILE([ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c);],, + ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no) + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE + ]) + + AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, + ax_cv_cxx_compile_cxx0x_gxx, + [AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -std=gnu++0x" + AC_TRY_COMPILE([ + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + typedef check<check<bool>> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check<int> check_type; + check_type c; + check_type&& cr = static_cast<check_type&&>(c);],, + ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no) + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE + ]) + + if test "$ax_cv_cxx_compile_cxx0x_native" = yes || + test "$ax_cv_cxx_compile_cxx0x_cxx" = yes || + test "$ax_cv_cxx_compile_cxx0x_gxx" = yes; then + AC_DEFINE(HAVE_STDCXX_0X,,[Define if g++ supports C++0x features. ]) + fi +]) diff --git a/tests/ChangeLog b/tests/ChangeLog index 444ca3c..d63bb68 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,15 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * testfile-cxx-various.bz2: New testfile. + * cxx-various.cxx: New test source. + * Makefile.am (cxx_various_SOURCES): New. + (HAVE_STDCXX_0X): Add cxx-various and -std=c++0x if exists. + (EXTRA_DIST): Add cxx-various.cxx and testfile-cxx-various.bz2. + * test-subr.sh: Add testfile-cxx-various and cxx-various to + self_test_files if they exist. + +2012-08-16 Mark Wielaard mjw@redhat.com + * run-readelf-unknown-self.sh: New test. * Makefile.am (TESTS): Add run-readelf-unknown-self.sh. (EXTRA_DIST): Likewise. diff --git a/tests/Makefile.am b/tests/Makefile.am index 0570569..4c0c765 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -97,6 +97,11 @@ check_PROGRAMS += $(asm_TESTS) TESTS += $(asm_TESTS) endif
+if HAVE_STDCXX_0X +check_PROGRAMS += cxx-various +AM_CXXFLAGS = -std=c++0x +cxx_various_SOURCES = cxx-various.cc +endif
EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-show-die-info.sh run-get-files.sh run-get-lines.sh \ @@ -134,6 +139,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \ run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \ run-readelf-test4.sh run-readelf-twofiles.sh \ run-readelf-unknown-self.sh \ + cxx-various.cc testfile-cxx-various.bz2 \ run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \ testfile29.bz2 testfile29.rdwr.bz2 \ testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \ diff --git a/tests/cxx-various.cc b/tests/cxx-various.cc new file mode 100644 index 0000000..5ddfc30 --- /dev/null +++ b/tests/cxx-various.cc @@ -0,0 +1,65 @@ +/* Test program for testing C++11 features are recognized. + Copyright (C) 2012 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/. */ + +// NOTE this file is the source of the binary testfile-cxx-various created +// with g++ -std=c++0x -g -o testfile-cxx-various cxx-various.cc +// +// When you edit this file to add more C++ contructs either create +// a new source file, or regenerate the binary test file. We always +// want to include the source code of all our test binaries. + +#include <iostream> +using namespace std; + +// Make sure we recognize the encoding of some of the standard types. +// char16_t and char_32_t use DW_ATE_UTF. +char c; +signed char sc; +unsigned char uc; +int i; +float f; +double d; +wchar_t wc; +char16_t c16; +char32_t c32; +long l; + +long +standard_types_func (char ac, signed char asc, unsigned char auc, + int ai, float af, double ad, wchar_t awc, + char16_t ac16, char32_t ac32, long al) +{ + c = ac; + sc = asc; + uc = auc; + i = ai; + f = af; + d = ad; + wc = awc; + c16 = ac16; + c32 = ac32; + l = al; + return ac + asc + auc + ai + af + ad + awc + ac16 + ac32 + al; +} + +int main () +{ + long answer; + answer = standard_types_func (1, 2, 3, 4, 5.0, 6.0, 7, 8, 9, -10L); + cout << "answer: " << answer << endl; + return 0; +} diff --git a/tests/test-subr.sh b/tests/test-subr.sh index e05d22a..c78795f 100644 --- a/tests/test-subr.sh +++ b/tests/test-subr.sh @@ -109,11 +109,21 @@ self_test_files=`echo ../src/addr2line ../src/elfcmp ../src/elflint \ ../src/size ../src/strip ../libelf/libelf.so ../libdw/libdw.so \ ../libasm/libasm.so ../backends/libebl_*.so`
+# Prebuild binary in case we don't have a C++11 capable compiler around. +extra_self_test_files=testfile-cxx-various +self_test_files="$self_test_files $extra_self_test_files" + +# This file might not exist if we don't have a C++ compiler around. +if test -f cxx-various; then + self_test_files="$self_test_files cxx-various" +fi + # Provide a command to run on all self-test files with testrun. testrun_on_self() { exit_status=0
+ testfiles $extra_self_test_files for file in $self_test_files; do testrun $* $file \ || { echo "*** failure in $* $file"; exit_status=1; } @@ -128,6 +138,7 @@ testrun_on_self_quiet() { exit_status=0
+ testfiles $extra_self_test_files for file in $self_test_files; do testrun $* $file > /dev/null \ || { echo "*** failure in $* $file"; exit_status=1; } @@ -148,6 +159,7 @@ testrun_on_self_nomatch() exit_status=0 tempfiles self_matches.in self_matches.out
+ testfiles $extra_self_test_files for file in $self_test_files; do testrun "$@" $file > self_matches.in # egrep should fail to match anything, but we also want to show diff --git a/tests/testfile-cxx-various.bz2 b/tests/testfile-cxx-various.bz2 new file mode 100755 index 0000000000000000000000000000000000000000..518bcf8b7023490fe31f9850f2305ea76ac3c426 GIT binary patch literal 11377 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
literal 0 HcmV?d00001
dwarf_endianity_string for DW_END codes used with DW_AT_endianity. dwarf_decimal_sign_string for DW_DS codes used with DW_AT_decimal_sign.
Signed-off-by: Mark Wielaard mjw@redhat.com --- libdw/ChangeLog | 11 ++++++++ libdw/Makefile.am | 3 +- libdw/dwarf_decimal_sign_string.c | 51 +++++++++++++++++++++++++++++++++++++ libdw/dwarf_endianity_string.c | 51 +++++++++++++++++++++++++++++++++++++ libdw/libdw.h | 10 +++++++ libdw/libdw.map | 2 + src/ChangeLog | 7 +++++ src/readelf.c | 19 +++++++++++++ 8 files changed, 153 insertions(+), 1 deletions(-) create mode 100644 libdw/dwarf_decimal_sign_string.c create mode 100644 libdw/dwarf_endianity_string.c
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index e61a961..87b2d1b 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,5 +1,16 @@ 2012-08-16 Mark Wielaard mjw@redhat.com
+ * Makefile.am (libdw_a_SOURCES): Add dwarf_endianity_string.c and + dwarf_decimal_sign_string.c. + * dwarf_endianity_string.c: New file. + * dwarf_decimal_sign_string.c: New file. + * libdw.h: Declare dwarf_endianity_string and + dwarf_decimal_sign_string. + * libdw.map (ELFUTILS_0.155): Add dwarf_endianity_string and + dwarf_decimal_sign_string. + +2012-08-16 Mark Wielaard mjw@redhat.com + * Makefile.am (libdw_a_SOURCES): Add dwarf_aggregate_size.c, dwarf_getlocation_implicit_pointer.c, dwarf_access_string.c, dwarf_inline_string.c, diff --git a/libdw/Makefile.am b/libdw/Makefile.am index f695e89..e35e8e9 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -97,7 +97,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_encoding_string.c dwarf_locexpr_opcode_string.c \ dwarf_form_string.c dwarf_ordering_string.c \ dwarf_tag_string.c dwarf_virtuality_string.c \ - dwarf_identifier_case_string.c dwarf_visibility_string.c + dwarf_identifier_case_string.c dwarf_visibility_string.c \ + dwarf_endianity_string.c dwarf_decimal_sign_string.c
if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_decimal_sign_string.c b/libdw/dwarf_decimal_sign_string.c new file mode 100644 index 0000000..ee0f414 --- /dev/null +++ b/libdw/dwarf_decimal_sign_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_decimal_sign_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_DS(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_DS +#undef ONE_KNOWN_DW_DS + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/dwarf_endianity_string.c b/libdw/dwarf_endianity_string.c new file mode 100644 index 0000000..d1c07f8 --- /dev/null +++ b/libdw/dwarf_endianity_string.c @@ -0,0 +1,51 @@ +/* Copyright (C) 2012 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/. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stddef.h> + +#include "known-dwarf.h" +#include "dwarf.h" + +const char * +dwarf_endianity_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_END(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_END +#undef ONE_KNOWN_DW_END + }; + + if (likely (code < sizeof (known) / sizeof (known[0]))) + return known[code]; + + return NULL; +} diff --git a/libdw/libdw.h b/libdw/libdw.h index 4ed3a45..c1e1319 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -906,6 +906,16 @@ extern const char *dwarf_line_standard_opcode_string (unsigned int code); if known. Returns NULL if the given DW_LNE opcode is unknown. */ extern const char *dwarf_line_extended_opcode_string (unsigned int code);
+/* Returns the endianity name, without the DW_END_ prefix, as used in + the DW_AT_endianity attribute, if known. Returns NULL if the given + DW_END code is unknown. */ +extern const char *dwarf_endianity_string (unsigned int code); + +/* Returns the decimal sign name, without the DW_DS_ prefix, as used in + the DW_AT_decimal_sign attribute, if known. Returns NULL if the given + DW_DS code is unknown. */ +extern const char *dwarf_decimal_sign_string (unsigned int code); +
/* Inline optimizations. */ #ifdef __OPTIMIZE__ diff --git a/libdw/libdw.map b/libdw/libdw.map index c3d7c25..4f31b1a 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -273,4 +273,6 @@ ELFUTILS_0.155 { dwarf_locexpr_opcode_string; dwarf_line_standard_opcode_string; dwarf_line_extended_opcode_string; + dwarf_endianity_string; + dwarf_decimal_sign_string; } ELFUTILS_0.149; diff --git a/src/ChangeLog b/src/ChangeLog index 1b06ea2..5739013 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2012-08-11 Mark Wielaard mjw@redhat.com + + * readelf.c (dwarf_endianity_name): New function. + (dwarf_decimal_sign_string): Likewise. + (attr_callback): Use dwarf_endianity_name for DW_AT_endianity + and use dwarf_decimal_sign_string for DW_AT_decimal_sign. + 2012-08-16 Mark Wielaard mjw@redhat.com
* readelf.c (dwarf_tag_string): Removed. diff --git a/src/readelf.c b/src/readelf.c index 34ccbf5..9960534 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3312,6 +3312,19 @@ dwarf_discr_list_name (unsigned int code) return string_or_unknown (ret, code, 0, 0, false); }
+static const char * +dwarf_endianity_name (unsigned int code) +{ + const char *ret = dwarf_endianity_string (code); + return string_or_unknown (ret, code, DW_END_lo_user, DW_END_hi_user, false); +} + +static const char * +dwarf_decimal_sign_name (unsigned int code) +{ + const char *ret = dwarf_decimal_sign_string (code); + return string_or_unknown (ret, code, 0, 0, false); +}
static void print_block (size_t n, const void *block) @@ -4985,6 +4998,12 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) case DW_AT_discr_list: valuestr = dwarf_discr_list_name (num); break; + case DW_AT_endianity: + valuestr = dwarf_endianity_name (num); + break; + case DW_AT_decimal_sign: + valuestr = dwarf_decimal_sign_name (num); + break; default: /* Nothing. */ break;
elfutils-devel@lists.fedorahosted.org