#include <cstdlib>
#include <fcntl.h>
#include <memory>
+#include <unordered_map>
#include <utility>
#include <boost/range/algorithm.hpp>
static TagClass classify_tag(int tag)
{
- switch (tag) {
- case DW_TAG_array_type:
- case DW_TAG_class_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_typedef:
- case DW_TAG_pointer_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_string_type:
- case DW_TAG_structure_type:
- case DW_TAG_subroutine_type:
- case DW_TAG_union_type:
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_set_type:
- case DW_TAG_subrange_type:
- case DW_TAG_base_type:
- case DW_TAG_const_type:
- case DW_TAG_file_type:
- case DW_TAG_packed_type:
- case DW_TAG_volatile_type:
- case DW_TAG_restrict_type:
- case DW_TAG_interface_type:
- case DW_TAG_unspecified_type:
- case DW_TAG_shared_type:
- return TagClass::Type;
-
- case DW_TAG_subprogram:
- return TagClass::Subprogram;
-
- case DW_TAG_variable:
- case DW_TAG_formal_parameter:
- return TagClass::Variable;
-
- case DW_TAG_lexical_block:
- case DW_TAG_try_block:
- case DW_TAG_catch_block:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_with_stmt:
- return TagClass::Scope;
-
- case DW_TAG_namespace:
- return TagClass::Namespace;
-
- default:
- return TagClass::Unknown;
- }
+ static const std::unordered_map<int, TagClass> map = {
+ {DW_TAG_array_type, TagClass::Type}, {DW_TAG_class_type, TagClass::Type},
+ {DW_TAG_enumeration_type, TagClass::Type}, {DW_TAG_typedef, TagClass::Type},
+ {DW_TAG_pointer_type, TagClass::Type}, {DW_TAG_reference_type, TagClass::Type},
+ {DW_TAG_rvalue_reference_type, TagClass::Type}, {DW_TAG_string_type, TagClass::Type},
+ {DW_TAG_structure_type, TagClass::Type}, {DW_TAG_subroutine_type, TagClass::Type},
+ {DW_TAG_union_type, TagClass::Type}, {DW_TAG_ptr_to_member_type, TagClass::Type},
+ {DW_TAG_set_type, TagClass::Type}, {DW_TAG_subrange_type, TagClass::Type},
+ {DW_TAG_base_type, TagClass::Type}, {DW_TAG_const_type, TagClass::Type},
+ {DW_TAG_file_type, TagClass::Type}, {DW_TAG_packed_type, TagClass::Type},
+ {DW_TAG_volatile_type, TagClass::Type}, {DW_TAG_restrict_type, TagClass::Type},
+ {DW_TAG_interface_type, TagClass::Type}, {DW_TAG_unspecified_type, TagClass::Type},
+ {DW_TAG_shared_type, TagClass::Type},
+
+ {DW_TAG_subprogram, TagClass::Subprogram},
+
+ {DW_TAG_variable, TagClass::Variable}, {DW_TAG_formal_parameter, TagClass::Variable},
+
+ {DW_TAG_lexical_block, TagClass::Scope}, {DW_TAG_try_block, TagClass::Scope},
+ {DW_TAG_catch_block, TagClass::Scope}, {DW_TAG_inlined_subroutine, TagClass::Scope},
+ {DW_TAG_with_stmt, TagClass::Scope},
+
+ {DW_TAG_namespace, TagClass::Namespace}};
+
+ auto res = map.find(tag);
+ return res != map.end() ? res->second : TagClass::Unknown;
}
/** @brief Find the DWARF data class for a given DWARF data form
* */
static FormClass classify_form(int form)
{
- switch (form) {
- case DW_FORM_addr:
- return FormClass::Address;
- case DW_FORM_block2:
- case DW_FORM_block4:
- case DW_FORM_block:
- case DW_FORM_block1:
- return FormClass::Block;
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- case DW_FORM_udata:
- case DW_FORM_sdata:
- return FormClass::Constant;
- case DW_FORM_string:
- case DW_FORM_strp:
- return FormClass::String;
- case DW_FORM_ref_addr:
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- return FormClass::Reference;
- case DW_FORM_flag:
- case DW_FORM_flag_present:
- return FormClass::Flag;
- case DW_FORM_exprloc:
- return FormClass::ExprLoc;
+ static const std::unordered_map<int, FormClass> map = {
+ {DW_FORM_addr, FormClass::Address},
+
+ {DW_FORM_block2, FormClass::Block}, {DW_FORM_block4, FormClass::Block},
+ {DW_FORM_block, FormClass::Block}, {DW_FORM_block1, FormClass::Block},
+
+ {DW_FORM_data1, FormClass::Constant}, {DW_FORM_data2, FormClass::Constant},
+ {DW_FORM_data4, FormClass::Constant}, {DW_FORM_data8, FormClass::Constant},
+ {DW_FORM_udata, FormClass::Constant}, {DW_FORM_sdata, FormClass::Constant},
+
+ {DW_FORM_string, FormClass::String}, {DW_FORM_strp, FormClass::String},
+
+ {DW_FORM_ref_addr, FormClass::Reference}, {DW_FORM_ref1, FormClass::Reference},
+ {DW_FORM_ref2, FormClass::Reference}, {DW_FORM_ref4, FormClass::Reference},
+ {DW_FORM_ref8, FormClass::Reference}, {DW_FORM_ref_udata, FormClass::Reference},
+
+ {DW_FORM_flag, FormClass::Flag}, {DW_FORM_flag_present, FormClass::Flag},
+
+ {DW_FORM_exprloc, FormClass::ExprLoc}
+
// TODO sec offset
// TODO indirect
- default:
- return FormClass::Unknown;
- }
+ };
+
+ auto res = map.find(form);
+ return res != map.end() ? res->second : FormClass::Unknown;
}
/** @brief Get the name of the tag of a given DIE
* */
static uint64_t MC_dwarf_default_lower_bound(int lang)
{
- switch (lang) {
- case DW_LANG_C:
- case DW_LANG_C89:
- case DW_LANG_C99:
- case DW_LANG_C_plus_plus:
- case DW_LANG_D:
- case DW_LANG_Java:
- case DW_LANG_ObjC:
- case DW_LANG_ObjC_plus_plus:
- case DW_LANG_Python:
- case DW_LANG_UPC:
- return 0;
- case DW_LANG_Ada83:
- case DW_LANG_Ada95:
- case DW_LANG_Fortran77:
- case DW_LANG_Fortran90:
- case DW_LANG_Fortran95:
- case DW_LANG_Modula2:
- case DW_LANG_Pascal83:
- case DW_LANG_PL1:
- case DW_LANG_Cobol74:
- case DW_LANG_Cobol85:
- return 1;
- default:
- xbt_die("No default DW_TAG_lower_bound for language %i and none given", lang);
- return 0;
- }
+ const std::unordered_map<int, unsigned> map = {
+ {DW_LANG_C, 0}, {DW_LANG_C89, 0}, {DW_LANG_C99, 0}, {DW_LANG_C_plus_plus, 0},
+ {DW_LANG_D, 0}, {DW_LANG_Java, 0}, {DW_LANG_ObjC, 0}, {DW_LANG_ObjC_plus_plus, 0},
+ {DW_LANG_Python, 0}, {DW_LANG_UPC, 0},
+
+ {DW_LANG_Ada83, 1}, {DW_LANG_Ada95, 1}, {DW_LANG_Fortran77, 1}, {DW_LANG_Fortran90, 1},
+ {DW_LANG_Fortran95, 1}, {DW_LANG_Modula2, 1}, {DW_LANG_Pascal83, 1}, {DW_LANG_PL1, 1},
+ {DW_LANG_Cobol74, 1}, {DW_LANG_Cobol85, 1}};
+
+ auto res = map.find(lang);
+ xbt_assert(res != map.end(), "No default DW_TAG_lower_bound for language %i and none given", lang);
+ return res->second;
}
/** @brief Finds the number of elements in a DW_TAG_subrange_type or DW_TAG_enumeration_type DIE
#elif defined(__i386__)
// Couldn't find the authoritative source of information for this.
// This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517.
- switch (dwarf_register) {
- case 0:
- return UNW_X86_EAX;
- case 1:
- return UNW_X86_ECX;
- case 2:
- return UNW_X86_EDX;
- case 3:
- return UNW_X86_EBX;
- case 4:
- return UNW_X86_ESP;
- case 5:
- return UNW_X86_EBP;
- case 6:
- return UNW_X86_ESI;
- case 7:
- return UNW_X86_EDI;
- case 8:
- return UNW_X86_EIP;
- case 9:
- return UNW_X86_EFLAGS;
- case 10:
- return UNW_X86_CS;
- case 11:
- return UNW_X86_SS;
- case 12:
- return UNW_X86_DS;
- case 13:
- return UNW_X86_ES;
- case 14:
- return UNW_X86_FS;
- case 15:
- return UNW_X86_GS;
- case 16:
- return UNW_X86_ST0;
- case 17:
- return UNW_X86_ST1;
- case 18:
- return UNW_X86_ST2;
- case 19:
- return UNW_X86_ST3;
- case 20:
- return UNW_X86_ST4;
- case 21:
- return UNW_X86_ST5;
- case 22:
- return UNW_X86_ST6;
- case 23:
- return UNW_X86_ST7;
- default:
- xbt_die("Bad/unknown register number.");
- }
+ constexpr std::array<int, 24> regs{
+ {/* 0 */ UNW_X86_EAX, /* 1 */ UNW_X86_ECX, /* 2 */ UNW_X86_EDX, /* 3 */ UNW_X86_EBX,
+ /* 4 */ UNW_X86_ESP, /* 5 */ UNW_X86_EBP, /* 6 */ UNW_X86_ESI, /* 7 */ UNW_X86_EDI,
+ /* 8 */ UNW_X86_EIP, /* 9 */ UNW_X86_EFLAGS, /* 10 */ UNW_X86_CS, /* 11 */ UNW_X86_SS,
+ /* 12 */ UNW_X86_DS, /* 13 */ UNW_X86_ES, /* 14 */ UNW_X86_FS, /* 15 */ UNW_X86_GS,
+ /* 16 */ UNW_X86_ST0, /* 17 */ UNW_X86_ST1, /* 18 */ UNW_X86_ST2, /* 19 */ UNW_X86_ST3,
+ /* 20 */ UNW_X86_ST4, /* 21 */ UNW_X86_ST5, /* 22 */ UNW_X86_ST6, /* 23 */ UNW_X86_ST7}};
+ return regs.at(dwarf_register);
#else
#error This architecture is not supported yet for DWARF expression evaluation.
#endif