diff --git a/.travis.yml b/.travis.yml index e9c411f4..5c54e3eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,8 +15,6 @@ script: jobs: include: - - os: linux - dist: xenial - os: linux dist: bionic - os: linux diff --git a/Makefile b/Makefile index 9e2ba974..5e6edbd7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -ROOT_DIR :=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) +mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +ROOT_DIR := $(shell cd $(shell dirname $(mkfile_path)); pwd) BUILD_DIR := $(ROOT_DIR)/build COVERAGE_DIR := $(BUILD_DIR)/coverage diff --git a/src/Juicer.cpp b/src/Juicer.cpp index ec29bd2a..5add7760 100644 --- a/src/Juicer.cpp +++ b/src/Juicer.cpp @@ -172,14 +172,12 @@ int Juicer::process_DW_TAG_array_type(ElfFile& elf, Symbol &symbol, Dwarf_Debug /* Now lets get the array size. Get the array size by getting * the first child, which should be the subrange_type. */ - res = dwarf_child(inDie, &dieSubrangeType, &error); - if(res == DW_DLV_ERROR) - { - logger.logError("Error in dwarf_child. errno=%u %s", dwarf_errno(error), - dwarf_errmsg(error)); - } - - DisplayDie(inDie); + res = dwarf_child(inDie, &dieSubrangeType, &error); + if(res == DW_DLV_ERROR) + { + logger.logError("Error in dwarf_child. errno=%u %s", dwarf_errno(error), + dwarf_errmsg(error)); + } /* Make sure this is the subrange_type tag. */ if(res == DW_DLV_OK) @@ -218,7 +216,7 @@ int Juicer::process_DW_TAG_array_type(ElfFile& elf, Symbol &symbol, Dwarf_Debug res = dwarf_formudata(attr_struct, &dwfUpperBound, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } } @@ -227,18 +225,17 @@ int Juicer::process_DW_TAG_array_type(ElfFile& elf, Symbol &symbol, Dwarf_Debug if(res == DW_DLV_OK) { multiplicity = dwfUpperBound + 1; - logger.logDebug("size of array:%d", multiplicity); } } res = dwarf_siblingof(dbg, inDie, &sib_die, &error); - if(res == DW_DLV_ERROR) - { - logger.logError("Error in dwarf_siblingof , function process_DW_TAG_array_type. errno=%u %s" , dwarf_errno(error), + if(res == DW_DLV_ERROR) + { + logger.logError("Error in dwarf_siblingof , function process_DW_TAG_array_type. errno=%u %s" , dwarf_errno(error), dwarf_errmsg(error));; - } - else - { + } + else + { res = dwarf_diename(sib_die, &arrayName, &error); if(DW_DLV_ERROR == res || DW_DLV_NO_ENTRY == res ) { @@ -253,8 +250,6 @@ int Juicer::process_DW_TAG_array_type(ElfFile& elf, Symbol &symbol, Dwarf_Debug */ std::string stdString{arrayName}; - logger.logDebug("Name for array-->%s", arrayName); - Symbol* arraySymbol = getBaseTypeSymbol(elf, inDie, multiplicity); if(nullptr == arraySymbol) @@ -269,12 +264,10 @@ int Juicer::process_DW_TAG_array_type(ElfFile& elf, Symbol &symbol, Dwarf_Debug outSymbol = elf.getSymbol(arrayBaseType); outSymbol->addField(stdString, 0, *outSymbol, multiplicity, elf.isLittleEndian()); } - - logger.logDebug("Name for array-->%s", arrayName); } - } + } - return res; + return res; } char * Juicer::getFirstAncestorName(Dwarf_Die inDie) @@ -457,8 +450,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult /* Get the type attribute. */ res = dwarf_attr(inDie, DW_AT_type, &attr_struct, &error); - DisplayDie(inDie); - if(res != DW_DLV_OK) { logger.logWarning("Cannot find data type. Skipping. %u errno=%u %s ", __LINE__, dwarf_errno(error), @@ -491,8 +482,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult if(res == DW_DLV_OK) { - DisplayDie(typeDie); - res = dwarf_tag(typeDie, &tag, &error); if(res != DW_DLV_OK) { @@ -503,17 +492,12 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult if(res == DW_DLV_OK) { - logger.logDebug("res == DW_DLV_OK"); switch(tag) { case DW_TAG_pointer_type: { - DisplayDie(inDie); - outSymbol = process_DW_TAG_pointer_type(elf, dbg, typeDie); - - logger.logDebug("DW_TAG_pointer_type"); break; } @@ -523,8 +507,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult Dwarf_Bool parentHasName = false; Dwarf_Unsigned byteSize = 0; - logger.logDebug("DW_TAG_structure_type"); - /* Does the structure type itself have the name? */ res = dwarf_hasattr(typeDie, DW_AT_name, &structHasName, &error); if(res != DW_DLV_OK) @@ -611,15 +593,12 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult case DW_TAG_base_type: { outSymbol = process_DW_TAG_base_type(elf, dbg, typeDie); - - logger.logDebug("DW_TAG_base_type"); break; } case DW_TAG_typedef: { outSymbol = process_DW_TAG_typedef(elf, dbg, typeDie); - logger.logDebug("DW_TAG_typedef"); break; } @@ -629,8 +608,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult Dwarf_Bool parentHasName = false; Dwarf_Unsigned byteSize = 0; - logger.logDebug("DW_TAG_enumeration_type"); - /* Does the structure type itself have the name? */ res = dwarf_hasattr(typeDie, DW_AT_name, &structHasName, &error); if(res != DW_DLV_OK) @@ -715,8 +692,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult Dwarf_Die dieSubrangeType; Dwarf_Unsigned dwfUpperBound = 0; - logger.logDebug("DW_TAG_array_type"); - /* First get the base type itself. */ outSymbol = getBaseTypeSymbol(elf, typeDie, multiplicity); @@ -769,7 +744,7 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult res = dwarf_formudata(attr_struct, &dwfUpperBound, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } } @@ -787,7 +762,6 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult case DW_TAG_class_type: { /* TODO */ - logger.logDebug("DW_TAG_class_type"); break; } @@ -805,14 +779,12 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult case DW_TAG_reference_type: { /* TODO */ - logger.logDebug("DW_TAG_reference_type"); break; } case DW_TAG_union_type: { /* TODO */ - logger.logDebug("DW_TAG_union_type"); break; } @@ -820,13 +792,11 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult /* Fallthru */ case DW_TAG_unspecified_type: { - logger.logDebug("DW_TAG_unspecified_type"); break; } case DW_TAG_rvalue_reference_type: { /* Ignore these tags. */ - logger.logDebug("DW_TAG_rvalue_reference_type"); break; } @@ -847,7 +817,7 @@ Symbol * Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &mult return outSymbol; } -void Juicer::DisplayDie(Dwarf_Die inDie) +void Juicer::DisplayDie(Dwarf_Die inDie, uint32_t level) { int res = DW_DLV_OK; Dwarf_Attribute *attribs; @@ -855,10 +825,13 @@ void Juicer::DisplayDie(Dwarf_Die inDie) Dwarf_Off globalOffset; Dwarf_Off localOffset; Dwarf_Attribute attr_struct; - char *dieName; + char *dieName = 0; Dwarf_Half tag = 0; int abbrevCode = 0; Dwarf_Half hasChildrenFlag = 0; + char tagName[255]; + char output[2000]; + char line[255]; if(inDie != 0) { @@ -867,41 +840,290 @@ void Juicer::DisplayDie(Dwarf_Die inDie) { switch(tag) { - case DW_TAG_typedef: - logger.logDebug("DW_TAG_typedef"); + case DW_TAG_array_type: + sprintf(tagName, "DW_TAG_array_type"); + break; + + case DW_TAG_class_type: + sprintf(tagName, "DW_TAG_class_type"); + break; + + case DW_TAG_entry_point: + sprintf(tagName, "DW_TAG_entry_point"); + break; + + case DW_TAG_enumeration_type: + sprintf(tagName, "DW_TAG_enumeration_type"); + break; + + case DW_TAG_formal_parameter: + sprintf(tagName, "DW_TAG_formal_parameter"); + break; + + case DW_TAG_imported_declaration: + sprintf(tagName, "DW_TAG_imported_declaration"); + break; + + case DW_TAG_label: + sprintf(tagName, "DW_TAG_label"); + break; + + case DW_TAG_lexical_block: + sprintf(tagName, "DW_TAG_lexical_block"); + break; + + case DW_TAG_member: + sprintf(tagName, "DW_TAG_member"); + break; + + case DW_TAG_pointer_type: + sprintf(tagName, "DW_TAG_pointer_type"); + break; + + case DW_TAG_reference_type: + sprintf(tagName, "DW_TAG_reference_type"); + break; + + case DW_TAG_compile_unit: + sprintf(tagName, "DW_TAG_compile_unit"); + break; + + case DW_TAG_string_type: + sprintf(tagName, "DW_TAG_string_type"); break; case DW_TAG_structure_type: - logger.logDebug("DW_TAG_structure_type"); + sprintf(tagName, "DW_TAG_structure_type"); break; - default: - logger.logDebug("0x%02x", tag); + case DW_TAG_subroutine_type: + sprintf(tagName, "DW_TAG_subroutine_type"); break; - } - } - else - { - logger.logDebug(" "); - } - res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error); - if(res == DW_DLV_OK) - { - res = dwarf_formstring(attr_struct, &dieName, &error); - if(res != DW_DLV_OK) - { - logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), - dwarf_errmsg(error)); - } - else - { - logger.logDebug(":%s\n", dieName); + case DW_TAG_typedef: + sprintf(tagName, "DW_TAG_typedef"); + break; + + case DW_TAG_union_type: + sprintf(tagName, "DW_TAG_union_type"); + break; + + case DW_TAG_unspecified_parameters: + sprintf(tagName, "DW_TAG_unspecified_parameters"); + break; + + case DW_TAG_variant: + sprintf(tagName, "DW_TAG_variant"); + break; + + case DW_TAG_common_block: + sprintf(tagName, "DW_TAG_common_block"); + break; + + case DW_TAG_common_inclusion: + sprintf(tagName, "DW_TAG_common_inclusion"); + break; + + case DW_TAG_inheritance: + sprintf(tagName, "DW_TAG_inheritance"); + break; + + case DW_TAG_inlined_subroutine: + sprintf(tagName, "DW_TAG_inlined_subroutine"); + break; + + case DW_TAG_module: + sprintf(tagName, "DW_TAG_module"); + break; + + case DW_TAG_ptr_to_member_type: + sprintf(tagName, "DW_TAG_ptr_to_member_type"); + break; + + case DW_TAG_set_type: + sprintf(tagName, "DW_TAG_set_type"); + break; + + case DW_TAG_subrange_type: + sprintf(tagName, "DW_TAG_subrange_type"); + break; + + case DW_TAG_with_stmt: + sprintf(tagName, "DW_TAG_with_stmt"); + break; + + case DW_TAG_access_declaration: + sprintf(tagName, "DW_TAG_access_declaration"); + break; + + case DW_TAG_base_type: + sprintf(tagName, "DW_TAG_base_type"); + break; + + case DW_TAG_catch_block: + sprintf(tagName, "DW_TAG_catch_block"); + break; + + case DW_TAG_const_type: + sprintf(tagName, "DW_TAG_const_type"); + break; + + case DW_TAG_constant: + sprintf(tagName, "DW_TAG_constant"); + break; + + case DW_TAG_enumerator: + sprintf(tagName, "DW_TAG_enumerator"); + break; + + case DW_TAG_file_type: + sprintf(tagName, "DW_TAG_file_type"); + break; + + case DW_TAG_friend: + sprintf(tagName, "DW_TAG_friend"); + break; + + case DW_TAG_namelist: + sprintf(tagName, "DW_TAG_namelist"); + break; + + case DW_TAG_namelist_item: + sprintf(tagName, "DW_TAG_namelist_item"); + break; + + case DW_TAG_packed_type: + sprintf(tagName, "DW_TAG_packed_type"); + break; + + case DW_TAG_subprogram: + sprintf(tagName, "DW_TAG_subprogram"); + break; + + case DW_TAG_template_type_parameter: + sprintf(tagName, "DW_TAG_template_type_parameter"); + break; + + case DW_TAG_template_value_parameter: + sprintf(tagName, "DW_TAG_template_value_parameter"); + break; + + case DW_TAG_thrown_type: + sprintf(tagName, "DW_TAG_thrown_type"); + break; + + case DW_TAG_try_block: + sprintf(tagName, "DW_TAG_try_block"); + break; + + case DW_TAG_variant_part: + sprintf(tagName, "DW_TAG_variant_part"); + break; + + case DW_TAG_variable: + sprintf(tagName, "DW_TAG_variable"); + break; + + case DW_TAG_volatile_type: + sprintf(tagName, "DW_TAG_volatile_type"); + break; + + case DW_TAG_dwarf_procedure: + sprintf(tagName, "DW_TAG_dwarf_procedure"); + break; + + case DW_TAG_restrict_type: + sprintf(tagName, "DW_TAG_restrict_type"); + break; + + case DW_TAG_interface_type: + sprintf(tagName, "DW_TAG_interface_type"); + break; + + case DW_TAG_namespace: + sprintf(tagName, "DW_TAG_namespace"); + break; + + case DW_TAG_imported_module: + sprintf(tagName, "DW_TAG_imported_module"); + break; + + case DW_TAG_unspecified_type: + sprintf(tagName, "DW_TAG_unspecified_type"); + break; + + case DW_TAG_partial_unit: + sprintf(tagName, "DW_TAG_partial_unit"); + break; + + case DW_TAG_imported_unit: + sprintf(tagName, "DW_TAG_imported_unit"); + break; + + case DW_TAG_mutable_type: + sprintf(tagName, "DW_TAG_mutable_type"); + break; + + case DW_TAG_condition: + sprintf(tagName, "DW_TAG_condition"); + break; + + case DW_TAG_shared_type: + sprintf(tagName, "DW_TAG_shared_type"); + break; + + case DW_TAG_type_unit: + sprintf(tagName, "DW_TAG_type_unit"); + break; + + case DW_TAG_rvalue_reference_type: + sprintf(tagName, "DW_TAG_rvalue_reference_type"); + break; + + case DW_TAG_template_alias: + sprintf(tagName, "DW_TAG_template_alias"); + break; + + case DW_TAG_coarray_type: + sprintf(tagName, "DW_TAG_coarray_type"); + break; + + case DW_TAG_generic_subrange: + sprintf(tagName, "DW_TAG_generic_subrange"); + break; + + case DW_TAG_dynamic_type: + sprintf(tagName, "DW_TAG_dynamic_type"); + break; + + case DW_TAG_atomic_type: + sprintf(tagName, "DW_TAG_dynamic_type"); + break; + + case DW_TAG_call_site: + sprintf(tagName, "DW_TAG_call_site"); + break; + + case DW_TAG_call_site_parameter: + sprintf(tagName, "DW_TAG_call_site_parameter"); + break; + + case DW_TAG_skeleton_unit: + sprintf(tagName, "DW_TAG_skeleton_unit"); + break; + + case DW_TAG_immutable_type: + sprintf(tagName, "DW_TAG_immutable_type"); + break; + + default: + sprintf(tagName, "UNKNOWN (0x%04x)", tag); + break; } } else { - logger.logDebug("\n"); + sprintf(tagName, "<< error >>"); } res = dwarf_die_offsets(inDie, &globalOffset, &localOffset, &error); @@ -910,43 +1132,31 @@ void Juicer::DisplayDie(Dwarf_Die inDie) logger.logError("Error in dwarf_die_offsets. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error)); } - else - { - logger.logDebug(" DIE offset (local) : 0x%08llx\n", localOffset); - logger.logDebug(" DIE offset (global): 0x%08llx\n", globalOffset); - } abbrevCode = dwarf_die_abbrev_code(inDie); - logger.logDebug(" Abbrev code: %i\n", abbrevCode); - res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag); - if(res != DW_DLV_OK) - { - logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), - dwarf_errmsg(error)); - } - else - { - logger.logDebug(" Has children: %s\n", hasChildrenFlag ? "True" : "False"); - } - - int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, - Dwarf_Half * /*ab_has_child*/); + sprintf(line, "<%u><%x>: Abbrev Number: %u (%s)\n", level, globalOffset, abbrevCode, tagName); + strcpy(output, line); res = dwarf_attrlist(inDie, &attribs, &attribCount, &error); if(res != DW_DLV_OK) { logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error), - dwarf_errmsg(error)); + dwarf_errmsg(error)); } else { if(attribCount > 0) { - logger.logDebug(" Attributes:\n"); for(uint32_t i = 0; i < attribCount; ++i) { Dwarf_Half attrNum; + char attribName[255]; + char formName[50]; + char value[50]; + + strcpy(value, "<< Form Not Supported >>"); + res = dwarf_whatattr(attribs[i], &attrNum, &error); if(res != DW_DLV_OK) { @@ -957,47 +1167,510 @@ void Juicer::DisplayDie(Dwarf_Die inDie) { Dwarf_Half formID; - switch(attrNum) - { - case DW_AT_sibling: - logger.logDebug(" DW_AT_sibling"); + switch(attrNum) + { + case DW_AT_sibling: + strcpy(attribName, "DW_AT_sibling"); + break; + + case DW_AT_location: + strcpy(attribName, "DW_AT_location"); + break; + + case DW_AT_name: + strcpy(attribName, "DW_AT_name"); + break; + + case DW_AT_ordering: + strcpy(attribName, "DW_AT_ordering"); + break; + + case DW_AT_subscr_data: + strcpy(attribName, "DW_AT_subscr_data"); + break; + + case DW_AT_byte_size: + strcpy(attribName, "DW_AT_byte_size"); + break; + + case DW_AT_bit_offset: + strcpy(attribName, "DW_AT_bit_offset"); + break; + + case DW_AT_bit_size: + strcpy(attribName, "DW_AT_bit_size"); + break; + + case DW_AT_element_list: + strcpy(attribName, "DW_AT_element_list"); + break; + + case DW_AT_stmt_list: + strcpy(attribName, "DW_AT_stmt_list"); + break; + + case DW_AT_low_pc: + strcpy(attribName, "DW_AT_low_pc"); + break; + + case DW_AT_high_pc: + strcpy(attribName, "DW_AT_high_pc"); + break; + + case DW_AT_language: + strcpy(attribName, "DW_AT_language"); + break; + + case DW_AT_member: + strcpy(attribName, "DW_AT_member"); + break; + + case DW_AT_discr: + strcpy(attribName, "DW_AT_discr"); + break; + + case DW_AT_discr_value: + strcpy(attribName, "DW_AT_discr_value"); + break; + + case DW_AT_visibility: + strcpy(attribName, "DW_AT_visibility"); + break; + + case DW_AT_import: + strcpy(attribName, "DW_AT_import"); + break; + + case DW_AT_string_length: + strcpy(attribName, "DW_AT_string_length"); + break; + + case DW_AT_common_reference: + strcpy(attribName, "DW_AT_common_reference"); + break; + + case DW_AT_comp_dir: + strcpy(attribName, "DW_AT_comp_dir"); + break; + + case DW_AT_const_value: + strcpy(attribName, "DW_AT_const_value"); + break; + + case DW_AT_containing_type: + strcpy(attribName, "DW_AT_containing_type"); + break; + + case DW_AT_default_value: + strcpy(attribName, "DW_AT_default_value"); + break; + + case DW_AT_inline: + strcpy(attribName, "DW_AT_inline"); + break; + + case DW_AT_is_optional: + strcpy(attribName, "DW_AT_is_optional"); + break; + + case DW_AT_lower_bound: + strcpy(attribName, "DW_AT_lower_bound"); + break; + + case DW_AT_producer: + strcpy(attribName, "DW_AT_producer"); + break; + + case DW_AT_prototyped: + strcpy(attribName, "DW_AT_prototyped"); + break; + + case DW_AT_return_addr: + strcpy(attribName, "DW_AT_return_addr"); + break; + + case DW_AT_start_scope: + strcpy(attribName, "DW_AT_start_scope"); + break; + + case DW_AT_bit_stride: + strcpy(attribName, "DW_AT_bit_stride"); + break; + + case DW_AT_upper_bound: + strcpy(attribName, "DW_AT_upper_bound"); + break; + + case DW_AT_abstract_origin: + strcpy(attribName, "DW_AT_abstract_origin"); + break; + + case DW_AT_accessibility: + strcpy(attribName, "DW_AT_accessibility"); + break; + + case DW_AT_address_class: + strcpy(attribName, "DW_AT_address_class"); + break; + + case DW_AT_artificial: + strcpy(attribName, "DW_AT_artificial"); + break; + + case DW_AT_base_types: + strcpy(attribName, "DW_AT_base_types"); + break; + + case DW_AT_calling_convention: + strcpy(attribName, "DW_AT_calling_convention"); + break; + + case DW_AT_count: + strcpy(attribName, "DW_AT_count"); + break; + + case DW_AT_data_member_location: + strcpy(attribName, "DW_AT_data_member_location"); + break; + + case DW_AT_decl_column: + strcpy(attribName, "DW_AT_decl_column"); + break; + + case DW_AT_decl_file: + strcpy(attribName, "DW_AT_decl_file"); + break; + + case DW_AT_decl_line: + strcpy(attribName, "DW_AT_decl_line"); + break; + + case DW_AT_declaration: + strcpy(attribName, "DW_AT_declaration"); + break; + + case DW_AT_discr_list: + strcpy(attribName, "DW_AT_discr_list"); + break; + + case DW_AT_encoding: + strcpy(attribName, "DW_AT_encoding"); + break; + + case DW_AT_external: + strcpy(attribName, "DW_AT_external"); + break; + + case DW_AT_frame_base: + strcpy(attribName, "DW_AT_frame_base"); + break; + + case DW_AT_friend: + strcpy(attribName, "DW_AT_friend"); + break; + + case DW_AT_identifier_case: + strcpy(attribName, "DW_AT_identifier_case"); + break; + + case DW_AT_macro_info: + strcpy(attribName, "DW_AT_macro_info"); + break; + + case DW_AT_namelist_item: + strcpy(attribName, "DW_AT_namelist_item"); + break; + + case DW_AT_priority: + strcpy(attribName, "DW_AT_priority"); + break; + + case DW_AT_segment: + strcpy(attribName, "DW_AT_segment"); + break; + + case DW_AT_specification: + strcpy(attribName, "DW_AT_specification"); + break; + + case DW_AT_static_link: + strcpy(attribName, "DW_AT_static_link"); + break; + + case DW_AT_type: + strcpy(attribName, "DW_AT_type"); + break; + + case DW_AT_use_location: + strcpy(attribName, "DW_AT_use_location"); + break; + + case DW_AT_variable_parameter: + strcpy(attribName, "DW_AT_variable_parameter"); + break; + + case DW_AT_virtuality: + strcpy(attribName, "DW_AT_virtuality"); + break; + + case DW_AT_vtable_elem_location: + strcpy(attribName, "DW_AT_vtable_elem_location"); + break; + + case DW_AT_allocated: + strcpy(attribName, "DW_AT_allocated"); + break; + + case DW_AT_associated: + strcpy(attribName, "DW_AT_associated"); + break; + + case DW_AT_data_location: + strcpy(attribName, "DW_AT_data_location"); + break; + + case DW_AT_byte_stride: + strcpy(attribName, "DW_AT_byte_stride"); + break; + + case DW_AT_entry_pc: + strcpy(attribName, "DW_AT_entry_pc"); + break; + + case DW_AT_use_UTF8: + strcpy(attribName, "DW_AT_use_UTF8"); + break; + + case DW_AT_extension: + strcpy(attribName, "DW_AT_extension"); + break; + + case DW_AT_ranges: + strcpy(attribName, "DW_AT_ranges"); + break; + + case DW_AT_trampoline: + strcpy(attribName, "DW_AT_trampoline"); + break; + + case DW_AT_call_column: + strcpy(attribName, "DW_AT_call_column"); + break; + + case DW_AT_call_file: + strcpy(attribName, "DW_AT_call_file"); + break; + + case DW_AT_call_line: + strcpy(attribName, "DW_AT_call_line"); + break; + + case DW_AT_description: + strcpy(attribName, "DW_AT_description"); + break; + + case DW_AT_binary_scale: + strcpy(attribName, "DW_AT_binary_scale"); + break; + + case DW_AT_decimal_scale: + strcpy(attribName, "DW_AT_decimal_scale"); + break; + + case DW_AT_small: + strcpy(attribName, "DW_AT_small"); + break; + + case DW_AT_decimal_sign: + strcpy(attribName, "DW_AT_decimal_sign"); + break; + + case DW_AT_digit_count: + strcpy(attribName, "DW_AT_digit_count"); + break; + + case DW_AT_picture_string: + strcpy(attribName, "DW_AT_picture_string"); + break; + + case DW_AT_mutable: + strcpy(attribName, "DW_AT_mutable"); + break; + + case DW_AT_threads_scaled: + strcpy(attribName, "DW_AT_threads_scaled"); + break; + + case DW_AT_explicit: + strcpy(attribName, "DW_AT_explicit"); + break; + + case DW_AT_object_pointer: + strcpy(attribName, "DW_AT_object_pointer"); + break; + + case DW_AT_endianity: + strcpy(attribName, "DW_AT_endianity"); + break; + + case DW_AT_elemental: + strcpy(attribName, "DW_AT_elemental"); + break; + + case DW_AT_pure: + strcpy(attribName, "DW_AT_pure"); + break; + + case DW_AT_recursive: + strcpy(attribName, "DW_AT_recursive"); + break; + + case DW_AT_signature: + strcpy(attribName, "DW_AT_signature"); + break; + + case DW_AT_main_subprogram: + strcpy(attribName, "DW_AT_main_subprogram"); + break; + + case DW_AT_data_bit_offset: + strcpy(attribName, "DW_AT_data_bit_offset"); + break; + + case DW_AT_const_expr: + strcpy(attribName, "DW_AT_const_expr"); + break; + + case DW_AT_enum_class: + strcpy(attribName, "DW_AT_enum_class"); + break; + + case DW_AT_linkage_name: + strcpy(attribName, "DW_AT_linkage_name"); + break; + + case DW_AT_string_length_bit_size: + strcpy(attribName, "DW_AT_string_length_bit_size"); + break; + + case DW_AT_string_length_byte_size: + strcpy(attribName, "DW_AT_string_length_byte_size"); + break; + + case DW_AT_rank: + strcpy(attribName, "DW_AT_rank"); + break; + + case DW_AT_str_offsets_base: + strcpy(attribName, "DW_AT_str_offsets_base"); + break; + + case DW_AT_addr_base: + strcpy(attribName, "DW_AT_addr_base"); + break; + + case DW_AT_rnglists_base: + strcpy(attribName, "DW_AT_rnglists_base"); + break; + + case DW_AT_dwo_id: + strcpy(attribName, "DW_AT_dwo_id"); + break; + + case DW_AT_dwo_name: + strcpy(attribName, "DW_AT_dwo_name"); + break; + + case DW_AT_reference: + strcpy(attribName, "DW_AT_reference"); + break; + + case DW_AT_rvalue_reference: + strcpy(attribName, "DW_AT_rvalue_reference"); + break; + + case DW_AT_macros: + strcpy(attribName, "DW_AT_macros"); + break; + + case DW_AT_call_all_calls: + strcpy(attribName, "DW_AT_call_all_calls"); + break; + + case DW_AT_call_all_source_calls: + strcpy(attribName, "DW_AT_call_all_source_calls"); + break; + + case DW_AT_call_all_tail_calls: + strcpy(attribName, "DW_AT_call_all_tail_calls"); + break; + + case DW_AT_call_return_pc: + strcpy(attribName, "DW_AT_call_return_pc"); + break; + + case DW_AT_call_value: + strcpy(attribName, "DW_AT_call_value"); + break; + + case DW_AT_call_origin: + strcpy(attribName, "DW_AT_call_origin"); + break; + + case DW_AT_call_parameter: + strcpy(attribName, "DW_AT_call_parameter"); + break; + + case DW_AT_call_pc: + strcpy(attribName, "DW_AT_call_pc"); break; - case DW_AT_location: - logger.logDebug(" DW_AT_location"); + case DW_AT_call_tail_call: + strcpy(attribName, "DW_AT_call_tail_call"); break; - case DW_AT_name: - logger.logDebug(" DW_AT_name"); + case DW_AT_call_target: + strcpy(attribName, "DW_AT_call_target"); break; - case DW_AT_ordering: - logger.logDebug(" DW_AT_ordering"); + case DW_AT_call_target_clobbered: + strcpy(attribName, "DW_AT_call_target_clobbered"); break; - case DW_AT_subscr_data: - logger.logDebug(" DW_AT_subscr_data"); + case DW_AT_call_data_location: + strcpy(attribName, "DW_AT_call_data_location"); break; - case DW_AT_byte_size: - logger.logDebug(" DW_AT_byte_size"); + case DW_AT_call_data_value: + strcpy(attribName, "DW_AT_call_data_value"); break; - case DW_AT_decl_file: - logger.logDebug(" DW_AT_decl_file"); + case DW_AT_noreturn: + strcpy(attribName, "DW_AT_noreturn"); break; - case DW_AT_decl_line: - logger.logDebug(" DW_AT_decl_line"); + case DW_AT_alignment: + strcpy(attribName, "DW_AT_alignment"); break; - case DW_AT_type: - logger.logDebug(" DW_AT_type"); + case DW_AT_export_symbols: + strcpy(attribName, "DW_AT_export_symbols"); break; - default: - logger.logDebug(" 0x%02x", attrNum); + case DW_AT_deleted: + strcpy(attribName, "DW_AT_deleted"); + break; + + case DW_AT_defaulted: + strcpy(attribName, "DW_AT_defaulted"); + break; + + case DW_AT_loclists_base: + strcpy(attribName, "DW_AT_loclists_base"); break; + + default: + sprintf(attribName, "UNKNOWN (%x)", attrNum); } res = dwarf_whatform(attribs[i], &attrNum, &error); @@ -1019,87 +1692,135 @@ void Juicer::DisplayDie(Dwarf_Die inDie) switch(formID) { case DW_FORM_addr: - logger.logDebug(":DW_FORM_addr\n"); + { + Dwarf_Addr addr = 0; + + strcpy(formName, "DW_FORM_addr"); + + res = dwarf_formaddr(attribs[i], &addr, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in DW_FORM_addr. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + unsigned long long data = (unsigned int) addr; + sprintf(value, "0x%016x", data); + } + break; + } case DW_FORM_block2: - logger.logDebug(":DW_FORM_block2\n"); - break; + { + Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_block2"); + + res = dwarf_formudata(attribs[i], &udata, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + unsigned short data = (unsigned short) udata; + sprintf(value, "%d", data); + } - case DW_FORM_block4: - logger.logDebug(":DW_FORM_block4\n"); break; + } - case DW_FORM_data1: + case DW_FORM_block4: { Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_block4"); + res = dwarf_formudata(attribs[i], &udata, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in DW_FORM_block4. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - char data = (char) udata; - logger.logDebug(":DW_FORM_data1:%u\n", data); + unsigned int data = (unsigned int) udata; + sprintf(value, "%d", data); } + break; } case DW_FORM_data2: { Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_data2"); + res = dwarf_formudata(attribs[i], &udata, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in DW_FORM_data2. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - unsigned short data = (unsigned short) udata; - logger.logDebug(":DW_FORM_data2:%u\n", data); + unsigned short int data = (unsigned short int) udata; + sprintf(value, "%d", data); } + break; } case DW_FORM_data4: { Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_data4"); res = dwarf_formudata(attribs[i], &udata, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { unsigned int data = (unsigned int) udata; - logger.logDebug(":DW_FORM_data4:%u\n", data); + sprintf(value, "%d", data); } + break; } case DW_FORM_data8: { Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_data8"); + res = dwarf_formudata(attribs[i], &udata, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - logger.logDebug(":DW_FORM_data8:%llu\n", udata); + sprintf(value, "%d", udata); } + break; } case DW_FORM_string: { char *str = 0; + + strcpy(formName, "DW_FORM_string"); + res = dwarf_formstring(attribs[i], &str, &error); if(res != DW_DLV_OK) { @@ -1108,22 +1829,109 @@ void Juicer::DisplayDie(Dwarf_Die inDie) } else { - logger.logDebug(":DW_FORM_string:%s\n", str); + sprintf(value, "%s", str); } + break; } case DW_FORM_block: - logger.logDebug(":DW_FORM_block\n"); + strcpy(formName, "DW_FORM_block"); break; + case DW_FORM_block1: + { + Dwarf_Block *bdata = 0; + strcpy(formName, "DW_FORM_block1"); + + res = dwarf_formblock(attribs[i], &bdata, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_formblock. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + sprintf(value, "len: %d", bdata->bl_len); + } + + break; + } + + + case DW_FORM_data1: + { + Dwarf_Unsigned udata = 0; + strcpy(formName, "DW_FORM_data1"); + + res = dwarf_formudata(attribs[i], &udata, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + uint8_t data = (uint8_t) udata; + sprintf(value, "%u", data); + } + + break; + } + + case DW_FORM_flag: + { + Dwarf_Bool dwarfBool = false; + strcpy(formName, "DW_FORM_flag"); + char *strp = 0; + + res = dwarf_formflag(attribs[i], &dwarfBool, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in DW_FORM_flag. errno=%u %s", dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + if(dwarfBool) + { + sprintf(value, "TRUE"); + } + else + { + sprintf(value, "FALSE"); + } + } + + break; + } + case DW_FORM_sdata: - logger.logDebug(":DW_FORM_sdata\n"); + { + Dwarf_Signed sdata = 0; + + strcpy(formName, "DW_FORM_sdata"); + + res = dwarf_formsdata(attribs[i], &sdata, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + sprintf(value, "%lli", sdata); + } + break; + } case DW_FORM_strp: { char *strp = 0; + + strcpy(formName, "DW_FORM_strp"); + res = dwarf_formstring(attribs[i], &strp, &error); if(res != DW_DLV_OK) { @@ -1133,134 +1941,604 @@ void Juicer::DisplayDie(Dwarf_Die inDie) else { char *text = dwarfStringToChar(strp); - logger.logDebug(":DW_FORM_strp:%s\n", text); + sprintf(value, "%s", text); } + break; } case DW_FORM_udata: { Dwarf_Unsigned udata = 0; + + strcpy(formName, "DW_FORM_udata"); + res = dwarf_formudata(attribs[i], &udata, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - logger.logDebug(":DW_FORM_udata:%llu\n", udata); + sprintf(value, "%llu", udata); } + break; } case DW_FORM_ref_addr: - logger.logDebug(":DW_FORM_ref_addr\n"); + strcpy(formName, "DW_FORM_ref_addr"); break; case DW_FORM_ref1: { Dwarf_Off ref = 0; + + strcpy(formName, "DW_FORM_ref1"); res = dwarf_formref(attribs[i], &ref, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - char data = (char) ref; - logger.logDebug(":DW_FORM_ref1:%u\n", data); + uint8_t data = (uint8_t) ref; + sprintf(value, "%u", data); } + break; } case DW_FORM_ref2: { Dwarf_Off ref = 0; + + strcpy(formName, "DW_FORM_ref1"); res = dwarf_formref(attribs[i], &ref, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { unsigned short int data = (unsigned short int) ref; - logger.logDebug(":DW_FORM_ref2:%u\n", data); + sprintf(value, "%u", data); } + break; } case DW_FORM_ref4: { Dwarf_Off ref = 0; + + strcpy(formName, "DW_FORM_ref1"); res = dwarf_formref(attribs[i], &ref, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { unsigned int data = (unsigned int) ref; - logger.logDebug(":DW_FORM_ref4:%u\n", data); + sprintf(value, "%u", data); } + break; } case DW_FORM_ref8: { Dwarf_Off ref = 0; + + strcpy(formName, "DW_FORM_ref1"); res = dwarf_formref(attribs[i], &ref, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } else { - logger.logDebug(":DW_FORM_ref4:%llu\n", ref); + sprintf(value, "%llu", ref); } + break; } case DW_FORM_ref_udata: - logger.logDebug(":DW_FORM_ref_udata\n"); + strcpy(formName, "DW_FORM_ref_udata"); break; case DW_FORM_indirect: - logger.logDebug(":DW_FORM_indirect\n"); + strcpy(formName, "DW_FORM_indirect"); break; case DW_FORM_sec_offset: - logger.logDebug(":DW_FORM_sec_offset\n"); + strcpy(formName, "DW_FORM_sec_offset"); break; case DW_FORM_exprloc: - logger.logDebug(":DW_FORM_exprloc\n"); + strcpy(formName, "DW_FORM_exprloc"); break; case DW_FORM_flag_present: - logger.logDebug(":DW_FORM_flag_present\n"); + strcpy(formName, "DW_FORM_flag_present"); + break; + + case DW_FORM_strx: + strcpy(formName, "DW_FORM_strx"); + break; + + case DW_FORM_addrx: + strcpy(formName, "DW_FORM_addrx"); + break; + + case DW_FORM_ref_sup4: + strcpy(formName, "DW_FORM_ref_sup4"); + break; + + case DW_FORM_strp_sup: + strcpy(formName, "DW_FORM_strp_sup"); + break; + + case DW_FORM_data16: + strcpy(formName, "DW_FORM_data16"); + break; + + case DW_FORM_line_strp: + strcpy(formName, "DW_FORM_line_strp"); break; case DW_FORM_ref_sig8: - logger.logDebug(":DW_FORM_ref_sig8\n"); + strcpy(formName, "DW_FORM_ref_sig8"); break; - default: - logger.logDebug(":0x%02x\n", formID); + case DW_FORM_implicit_const: + strcpy(formName, "DW_FORM_implicit_const"); + break; + + case DW_FORM_loclistx: + strcpy(formName, "DW_FORM_loclistx"); + break; + + case DW_FORM_rnglistx: + strcpy(formName, "DW_FORM_rnglistx"); + break; + + case DW_FORM_ref_sup8: + strcpy(formName, "DW_FORM_ref_sup8"); + break; + + case DW_FORM_strx1: + strcpy(formName, "DW_FORM_strx1"); + break; + + case DW_FORM_strx2: + strcpy(formName, "DW_FORM_strx2"); + break; + + case DW_FORM_strx3: + strcpy(formName, "DW_FORM_strx3"); + break; + + case DW_FORM_strx4: + strcpy(formName, "DW_FORM_strx4"); + break; + + case DW_FORM_addrx1: + strcpy(formName, "DW_FORM_addrx1"); + break; + + case DW_FORM_addrx2: + strcpy(formName, "DW_FORM_addrx2"); + break; + + case DW_FORM_addrx3: + strcpy(formName, "DW_FORM_addrx3"); + break; + + case DW_FORM_addrx4: + strcpy(formName, "DW_FORM_addrx4"); + break; + + case DW_FORM_GNU_addr_index: + strcpy(formName, "DW_FORM_GNU_addr_index"); + break; + + case DW_FORM_GNU_str_index: + strcpy(formName, "DW_FORM_GNU_str_index"); + break; + + case DW_FORM_GNU_ref_alt: + strcpy(formName, "DW_FORM_GNU_ref_alt"); + break; + + case DW_FORM_GNU_strp_alt: + strcpy(formName, "DW_FORM_GNU_strp_alt"); break; + default: + sprintf(formName, "UNKNOWN (%x)", formID); + break; } } } } + + sprintf(line, " %-20s : %-20s (%s)\n", attribName, value, formName); + strcat(output, line); } - logger.logDebug("\n"); } } + + + +// res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error); +// if(res == DW_DLV_OK) +// { +// res = dwarf_formstring(attr_struct, &dieName, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// sprintf(line, " DW_AT_name : %s", dieName); +// strcpy(output, line); +// } +// } +// +// res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } + +// else +// { +// logger.logDebug(" Has children: %s", hasChildrenFlag ? "True" : "False"); +// } +// +// int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/, +// Dwarf_Half * /*ab_has_child*/); +// +// res = dwarf_attrlist(inDie, &attribs, &attribCount, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// if(attribCount > 0) +// { +// logger.logDebug(" Attributes:"); +// for(uint32_t i = 0; i < attribCount; ++i) +// { +// Dwarf_Half attrNum; +// res = dwarf_whatattr(attribs[i], &attrNum, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// Dwarf_Half formID; +// +// switch(attrNum) +// { +// case DW_AT_sibling: +// logger.logDebug(" DW_AT_sibling"); +// break; +// +// case DW_AT_location: +// logger.logDebug(" DW_AT_location"); +// break; +// +// case DW_AT_name: +// logger.logDebug(" DW_AT_name"); +// break; +// +// case DW_AT_ordering: +// logger.logDebug(" DW_AT_ordering"); +// break; +// +// case DW_AT_subscr_data: +// logger.logDebug(" DW_AT_subscr_data"); +// break; +// +// case DW_AT_byte_size: +// logger.logDebug(" DW_AT_byte_size"); +// break; +// +// case DW_AT_decl_file: +// logger.logDebug(" DW_AT_decl_file"); +// break; +// +// case DW_AT_decl_line: +// logger.logDebug(" DW_AT_decl_line"); +// break; +// +// case DW_AT_type: +// logger.logDebug(" DW_AT_type"); +// break; +// +// default: +// logger.logDebug(" 0x%02x", attrNum); +// break; +// } +// +// res = dwarf_whatform(attribs[i], &attrNum, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// res = dwarf_whatform(attribs[i], &formID, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_whatform. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// switch(formID) +// { +// case DW_FORM_addr: +// logger.logDebug(":DW_FORM_addr"); +// break; +// +// case DW_FORM_block2: +// logger.logDebug(":DW_FORM_block2"); +// break; +// +// case DW_FORM_block4: +// logger.logDebug(":DW_FORM_block4"); +// break; +// +// case DW_FORM_data1: +// { +// Dwarf_Unsigned udata = 0; +// res = dwarf_formudata(attribs[i], &udata, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// char data = (char) udata; +// logger.logDebug(":DW_FORM_data1:%u", data); +// } +// break; +// } +// +// case DW_FORM_data2: +// { +// Dwarf_Unsigned udata = 0; +// res = dwarf_formudata(attribs[i], &udata, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// unsigned short data = (unsigned short) udata; +// logger.logDebug(":DW_FORM_data2:%u", data); +// } +// break; +// } +// +// case DW_FORM_data4: +// { +// Dwarf_Unsigned udata = 0; +// res = dwarf_formudata(attribs[i], &udata, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// unsigned int data = (unsigned int) udata; +// logger.logDebug(":DW_FORM_data4:%u", data); +// } +// break; +// } +// +// case DW_FORM_data8: +// { +// Dwarf_Unsigned udata = 0; +// res = dwarf_formudata(attribs[i], &udata, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// logger.logDebug(":DW_FORM_data8:%llu", udata); +// } +// break; +// } +// +// case DW_FORM_string: +// { +// char *str = 0; +// res = dwarf_formstring(attribs[i], &str, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// logger.logDebug(":DW_FORM_string:%s", str); +// } +// break; +// } +// +// case DW_FORM_block: +// logger.logDebug(":DW_FORM_block"); +// break; +// +// case DW_FORM_sdata: +// logger.logDebug(":DW_FORM_sdata"); +// break; +// +// case DW_FORM_strp: +// { +// char *strp = 0; +// res = dwarf_formstring(attribs[i], &strp, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// char *text = dwarfStringToChar(strp); +// logger.logDebug(":DW_FORM_strp:%s", text); +// } +// break; +// } +// +// case DW_FORM_udata: +// { +// Dwarf_Unsigned udata = 0; +// res = dwarf_formudata(attribs[i], &udata, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// logger.logDebug(":DW_FORM_udata:%llu", udata); +// } +// break; +// } +// +// case DW_FORM_ref_addr: +// logger.logDebug(":DW_FORM_ref_addr"); +// break; +// +// case DW_FORM_ref1: +// { +// Dwarf_Off ref = 0; +// res = dwarf_formref(attribs[i], &ref, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// char data = (char) ref; +// logger.logDebug(":DW_FORM_ref1:%u", data); +// } +// break; +// } +// +// case DW_FORM_ref2: +// { +// Dwarf_Off ref = 0; +// res = dwarf_formref(attribs[i], &ref, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// unsigned short int data = (unsigned short int) ref; +// logger.logDebug(":DW_FORM_ref2:%u", data); +// } +// break; +// } +// +// case DW_FORM_ref4: +// { +// Dwarf_Off ref = 0; +// res = dwarf_formref(attribs[i], &ref, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// unsigned int data = (unsigned int) ref; +// logger.logDebug(":DW_FORM_ref4:%u", data); +// } +// break; +// } +// +// case DW_FORM_ref8: +// { +// Dwarf_Off ref = 0; +// res = dwarf_formref(attribs[i], &ref, &error); +// if(res != DW_DLV_OK) +// { +// logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error), +// dwarf_errmsg(error)); +// } +// else +// { +// logger.logDebug(":DW_FORM_ref4:%llu", ref); +// } +// break; +// } +// +// case DW_FORM_ref_udata: +// logger.logDebug(":DW_FORM_ref_udata"); +// break; +// +// case DW_FORM_indirect: +// logger.logDebug(":DW_FORM_indirect"); +// break; +// +// case DW_FORM_sec_offset: +// logger.logDebug(":DW_FORM_sec_offset"); +// break; +// +// case DW_FORM_exprloc: +// logger.logDebug(":DW_FORM_exprloc"); +// break; +// +// case DW_FORM_flag_present: +// logger.logDebug(":DW_FORM_flag_present"); +// break; +// +// case DW_FORM_ref_sig8: +// logger.logDebug(":DW_FORM_ref_sig8"); +// break; +// +// default: +// logger.logDebug(":0x%02x", formID); +// break; +// +// } +// } +// } +// } +// } +// logger.logDebug("\n"); +// } +// } + + logger.logDebug(output); } } @@ -1292,31 +2570,33 @@ Symbol * Juicer::process_DW_TAG_base_type(ElfFile& elf, Dwarf_Debug dbg, Dwarf_D logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error)); } - } - - /* See if we already have this symbol. */ - cName = dieName; - outSymbol = elf.getSymbol(cName); - if(outSymbol == 0) - { - /* No. This is new. Process it. */ - - /* Get the size of this datatype. */ - if(res == DW_DLV_OK) + else { - res = dwarf_bytesize(inDie, &byteSize, &error); - if(res != DW_DLV_OK) - { - logger.logError("Error in dwarf_bytesize. %u errno=%u %s", __LINE__, dwarf_errno(error), - dwarf_errmsg(error)); - } - } + /* See if we already have this symbol. */ + cName = dieName; + outSymbol = elf.getSymbol(cName); + if(outSymbol == 0) + { + /* No. This is new. Process it. */ - /* We have everything we need. Add this to the elf. */ - if(res == DW_DLV_OK) - { - std::string sDieName = dieName; - outSymbol = elf.addSymbol(sDieName, byteSize); + /* Get the size of this datatype. */ + if(res == DW_DLV_OK) + { + res = dwarf_bytesize(inDie, &byteSize, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_bytesize. %u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + } + + /* We have everything we need. Add this to the elf. */ + if(res == DW_DLV_OK) + { + std::string sDieName = dieName; + outSymbol = elf.addSymbol(sDieName, byteSize); + } + } } } @@ -1407,7 +2687,7 @@ void Juicer::process_DW_TAG_enumeration_type(ElfFile& elf, Symbol &symbol, Dwarf res = dwarf_formudata(attr_struct, &enumeratorValue, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata. errno=%u %s", dwarf_errno(error), + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error)); } } @@ -1503,7 +2783,6 @@ Symbol * Juicer::process_DW_TAG_typedef(ElfFile& elf, Dwarf_Debug dbg, Dwarf_Die { std::string sDieName = dieName; outSymbol = elf.addSymbol(sDieName, byteSize); - logger.logDebug("name for this Symbol-->%s\n",outSymbol->getName().c_str()); } return outSymbol; @@ -1538,7 +2817,7 @@ void Juicer::process_DW_TAG_structure_type(ElfFile& elf, Symbol& symbol, Dwarf_D { char *memberName = nullptr; Symbol *memberBaseTypeSymbol = nullptr; - Dwarf_Unsigned memberLocation = 0; + uint32_t memberLocation = 0; if(res == DW_DLV_OK) { @@ -1616,11 +2895,97 @@ void Juicer::process_DW_TAG_structure_type(ElfFile& elf, Symbol& symbol, Dwarf_D /* Get the actual data member location of this member. */ if(res == DW_DLV_OK) { - res = dwarf_formudata(attr_struct, &memberLocation, &error); + Dwarf_Half formID; + + res = dwarf_whatform(attr_struct, &formID, &error); if(res != DW_DLV_OK) { - logger.logError("Error in dwarf_formudata , level %d. errno=%u %s", dwarf_errno(error), - dwarf_errmsg(error)); + logger.logError("Error in dwarf_whatform. errno=%u line=%u %s", dwarf_errno(error), + __LINE__, dwarf_errmsg(error)); + } + + switch(formID) + { + case DW_FORM_udata: + { + Dwarf_Unsigned udata = 0; + + res = dwarf_formudata(attr_struct, &udata, &error); + if(res != DW_DLV_OK) + { + DisplayDie(memberDie, 99); + + logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + memberLocation = (uint32_t) udata; + } + + break; + } + + case DW_FORM_block1: + { + Dwarf_Block *bdata = 0; + + res = dwarf_formblock(attr_struct, &bdata, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_formblock. line=%u errno=%u %s", __LINE__, dwarf_errno(error), + dwarf_errmsg(error)); + } + else + { + if(bdata->bl_from_loclist == 0) + { + /* + 7.6 Variable Length Data + Integers may be encoded using “Little Endian Base 128” (LEB128) numbers. LEB128 is a + scheme for encoding integers densely that exploits the assumption that most integers are small in + magnitude. + This encoding is equally suitable whether the target machine architecture represents data in big- + endian or little-endian order. It is “little-endian” only in the sense that it avoids using space to + represent the “big” end of an unsigned integer, when the big end is all zeroes or sign extension + bits. + Unsigned LEB128 (ULEB128) numbers are encoded as follows: start at the low order end of an + unsigned integer and chop it into 7-bit chunks. Place each chunk into the low order 7 bits of a + byte. Typically, several of the high order bytes will be zero; discard them. Emit the remaining + bytes in a stream, starting with the low order byte; set the high order bit on each byte except the + last emitted byte. The high bit of zero on the last byte indicates to the decoder that it has + encountered the last byte. + The integer zero is a special case, consisting of a single zero byte. + */ + + uint8_t *data = (uint8_t*)bdata->bl_data; + if(DW_OP_plus_uconst == data[0]) + { + int i = 0; + int shift = 0; + uint8_t *leb128 = &data[1]; + memberLocation = 0; + + for (i = 1; i < bdata->bl_len; ++i) + { + memberLocation |= (*leb128++ & ((1 << 7) - 1)) << shift; shift += 7; + } + } + } + else + { + logger.logError("Cannot parse %s. loclist %d not supported. line=%u", memberName, __LINE__, bdata->bl_from_loclist); + } + + } + + break; + } + + default: + { + logger.logError("Unable to parse '%s' member location. Unsupported form 0x%0x", memberName, formID); + } } } @@ -1635,7 +3000,6 @@ void Juicer::process_DW_TAG_structure_type(ElfFile& elf, Symbol& symbol, Dwarf_D /* Set the error code so we don't do anymore processing. */ res = DW_DLV_ERROR; } - logger.logDebug("memberBaseTypeSymbol=%d", memberBaseTypeSymbol); } /* We have everything we need. Add this field. */ @@ -1905,12 +3269,26 @@ int Juicer::getDieAndSiblings(ElfFile& elf, Dwarf_Debug dbg, Dwarf_Die in_die, i Dwarf_Attribute attr_struct; int return_value = JUICER_OK; - printDieData(dbg, in_die, in_level); - for(;;) { Dwarf_Die sib_die = 0; Dwarf_Half tag = 0; + Dwarf_Off offset = 0; + + res = dwarf_dieoffset(cur_die, &offset, &error); + if(res != DW_DLV_OK) + { + logger.logError("Error in dwarf_dieoffset , level %d. errno=%u %s", in_level, dwarf_errno(error), + dwarf_errmsg(error)); + return_value = JUICER_ERROR; + } + + DisplayDie(cur_die, in_level); + + if(offset == 0x3ad6b) + { + printf("Hello\n"); + } res = dwarf_tag(cur_die, &tag, &error); if(res != DW_DLV_OK) @@ -1969,12 +3347,6 @@ int Juicer::getDieAndSiblings(ElfFile& elf, Dwarf_Debug dbg, Dwarf_Die in_die, i } } - else - { - logger.logDebug("\n"); - } - - DisplayDie(cur_die); break; } @@ -2003,7 +3375,6 @@ int Juicer::getDieAndSiblings(ElfFile& elf, Dwarf_Debug dbg, Dwarf_Die in_die, i } else if(res == DW_DLV_OK) { - logger.logDebug("CHILD"); getDieAndSiblings(elf, dbg, child, in_level + 1); } @@ -2028,8 +3399,6 @@ int Juicer::getDieAndSiblings(ElfFile& elf, Dwarf_Debug dbg, Dwarf_Die in_die, i dwarf_dealloc(dbg, cur_die, DW_DLA_DIE); } cur_die = sib_die; - logger.logDebug("SIBBLING"); - printDieData(dbg, cur_die, in_level); } return return_value; } @@ -2075,12 +3444,16 @@ int Juicer::printDieData(Dwarf_Debug dbg, Dwarf_Die print_me, uint32_t level) strcpy(name, ""); localname = 1; } - else { /* Do nothing */ } + if(strcmp(name,"CFE_SB_TlmHdr_t") == 0) + { + printf("hello\n"); + } + if(tag != DW_TAG_structure_type) { res = dwarf_tag(print_me, &tag, &error); @@ -2130,14 +3503,6 @@ int Juicer::printDieData(Dwarf_Debug dbg, Dwarf_Die print_me, uint32_t level) } } - /* Log a nicely formatted string with indentation representing levels. */ - for(uint32_t i = 0; i < level; ++i) - { - outputText.append(" "); - } - outputText.append("tag: %d %s name: \"%s\""); - logger.logDebug(outputText.c_str(), tag, tagname, name); - if(!localname) { dwarf_dealloc(dbg, name, DW_DLA_STRING); @@ -2174,11 +3539,11 @@ JuicerEndianness_t Juicer::getEndianness() ident_buffer = elf_hdr_64->e_ident; - if(ident_buffer[EI_DATA] == 0) + if(ident_buffer[EI_DATA] == ELFDATA2MSB) { rc = JUICER_ENDIAN_BIG; } - else if(ident_buffer[EI_DATA] == 1) + else if(ident_buffer[EI_DATA] == ELFDATA2LSB) { rc = JUICER_ENDIAN_LITTLE; } @@ -2203,11 +3568,11 @@ JuicerEndianness_t Juicer::getEndianness() ident_buffer = elf_hdr_32->e_ident; - if(ident_buffer[EI_DATA] == 0) + if(ident_buffer[EI_DATA] == ELFDATA2MSB) { rc = JUICER_ENDIAN_BIG; } - else if(ident_buffer[EI_DATA] == 1) + else if(ident_buffer[EI_DATA] == ELFDATA2LSB) { rc = JUICER_ENDIAN_LITTLE; } @@ -2306,8 +3671,6 @@ int Juicer::parse( std::string& elfFilePath) std::string date {""}; elf->setChecksum(checkSum); - elf->isLittleEndian(JUICER_ENDIAN_BIG == endianness? - false: true); elf->setDate(date); if(JUICER_ENDIAN_BIG == endianness) @@ -2325,6 +3688,9 @@ int Juicer::parse( std::string& elfFilePath) logger.logError("Endian is unknown. Aborting parse."); return_value = JUICER_ERROR; } + + elf->isLittleEndian(JUICER_ENDIAN_BIG == endianness? + false: true); } if(JUICER_OK == return_value) @@ -2343,7 +3709,7 @@ int Juicer::parse( std::string& elfFilePath) if(JUICER_OK == return_value) { /* All done. Write it out. */ - logger.logDebug("Parsing of elf file '%s' is complete. Writing to data container.", elfFilePath.c_str()); + logger.logInfo("Parsing of elf file '%s' is complete. Writing to data container.", elfFilePath.c_str()); return_value = idc->write(*elf.get()); } } @@ -2355,3 +3721,4 @@ void Juicer::setIDC(IDataContainer *inIdc) { idc = inIdc; } + diff --git a/src/Juicer.h b/src/Juicer.h index 80e1242f..ea187edb 100644 --- a/src/Juicer.h +++ b/src/Juicer.h @@ -121,7 +121,7 @@ class Juicer IDataContainer *idc = 0; bool isIDCSet(void); Symbol * getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, uint32_t &multiplicity); - void DisplayDie(Dwarf_Die inDie); + void DisplayDie(Dwarf_Die inDie, uint32_t level); }; diff --git a/src/SQLiteDB.cpp b/src/SQLiteDB.cpp index 3fc85b3f..9b22e254 100644 --- a/src/SQLiteDB.cpp +++ b/src/SQLiteDB.cpp @@ -530,20 +530,14 @@ int SQLiteDB::writeFieldsToDatabase(ElfFile& inElf) if(SQLITE_OK == rc) { - logger.logDebug("Field values were written to the fields schema with " - "SQLITE_OK status."); - /*Write the id to this field so that other tables can use it as *a foreign key */ sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database); field->setId(lastRowId); - - } else { - logger.logDebug("There was an error while data to the fields table."); - logger.logDebug("%s.", errorMessage); + logger.logError("There was an error while writing data to the fields table. %s.", errorMessage); if(sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE) { @@ -608,8 +602,7 @@ int SQLiteDB::writeEnumerationsToDatabase(ElfFile& inElf) } else { - logger.logDebug("There was an error while data to the enumerations table."); - logger.logDebug("%s.", errorMessage); + logger.logDebug("There was an error while writing data to the enumerations table. %s.", errorMessage); if(sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE) {