diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a496fb3f7..9c19878f97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ set(RT_BINARY_DIR ${PROJECT_BINARY_DIR}/dyninstAPI_RT) include (${DYNINST_ROOT}/cmake/shared.cmake) -configure_file(cmake/version.h.in common/h/version.h) +configure_file(cmake/version.h.in common/h/dyninstversion.h) include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR}/common/h) set (HEADER_DIRS common diff --git a/cmake/Modules/FindLibDwarf.cmake b/cmake/Modules/FindLibDwarf.cmake index 7b289eeb7c..d745226cf1 100644 --- a/cmake/Modules/FindLibDwarf.cmake +++ b/cmake/Modules/FindLibDwarf.cmake @@ -18,18 +18,14 @@ endif (LIBDWARF_LIBRARIES AND LIBDWARF_INCLUDE_DIRS) find_path (LIBDWARF_INCLUDE_DIR NAMES - libdw.h + elfutils/libdw.h HINTS ${LIBDWARF_INCLUDE_DIRS} PATHS /usr/include - /usr/include/elfutils /usr/local/include /opt/local/include /sw/include - /usr/local/include/elfutils - /opt/local/include/elfutils - /sw/include/elfutils ENV CPATH) # PATH and INCLUDE will also work find_library (LIBDWARF_LIBRARIES diff --git a/cmake/packages.cmake b/cmake/packages.cmake index 9b04458fe2..e9bf7d5609 100644 --- a/cmake/packages.cmake +++ b/cmake/packages.cmake @@ -15,7 +15,7 @@ if (UNIX) ) set(LIBELF_INCLUDE_DIR ${CMAKE_BINARY_DIR}/elfutils/include) set(LIBELF_LIBRARIES ${CMAKE_BINARY_DIR}/elfutils/lib/libelf.so) - set(LIBDWARF_INCLUDE_DIR ${CMAKE_BINARY_DIR}/elfutils/include/elfutils) + set(LIBDWARF_INCLUDE_DIR ${CMAKE_BINARY_DIR}/elfutils/include) set(LIBDWARF_LIBRARIES ${CMAKE_BINARY_DIR}/elfutils/lib/libdw.so) set(SHOULD_INSTALL_LIBELF 1) else() diff --git a/dwarf/h/dwarfExprParser.h b/dwarf/h/dwarfExprParser.h index b0197b9097..0a6c1e589f 100644 --- a/dwarf/h/dwarfExprParser.h +++ b/dwarf/h/dwarfExprParser.h @@ -33,7 +33,7 @@ #include #include "dyn_regs.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "dwarf.h" #include "util.h" diff --git a/dwarf/h/dwarfFrameParser.h b/dwarf/h/dwarfFrameParser.h index 21510fd946..50ab4048b0 100644 --- a/dwarf/h/dwarfFrameParser.h +++ b/dwarf/h/dwarfFrameParser.h @@ -36,7 +36,7 @@ #include "dyntypes.h" #include "dyn_regs.h" #include "ProcReader.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "util.h" namespace Dyninst { diff --git a/dwarf/h/dwarfHandle.h b/dwarf/h/dwarfHandle.h index 992d89880f..d3f38afdc4 100644 --- a/dwarf/h/dwarfHandle.h +++ b/dwarf/h/dwarfHandle.h @@ -31,7 +31,7 @@ #if !defined(DWARF_HANDLE_H_) #define DWARF_HANDLE_H_ -#include "libdw.h" +#include "elfutils/libdw.h" #include "dyntypes.h" #include #include diff --git a/dwarf/h/dwarfResult.h b/dwarf/h/dwarfResult.h index fb256ebc96..bb793f8311 100644 --- a/dwarf/h/dwarfResult.h +++ b/dwarf/h/dwarfResult.h @@ -33,7 +33,7 @@ #include "dyn_regs.h" #include "dyntypes.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "util.h" namespace Dyninst { diff --git a/dwarf/src/dwarfFrameParser.C b/dwarf/src/dwarfFrameParser.C index ce610297c1..6359b45941 100644 --- a/dwarf/src/dwarfFrameParser.C +++ b/dwarf/src/dwarfFrameParser.C @@ -33,7 +33,7 @@ #include "dwarfResult.h" #include "VariableLocation.h" #include "Types.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include #include #include "debug_common.h" // dwarf_printf diff --git a/dwarf/src/dwarfHandle.C b/dwarf/src/dwarfHandle.C index 46602b1227..27881ecabb 100644 --- a/dwarf/src/dwarfHandle.C +++ b/dwarf/src/dwarfHandle.C @@ -28,7 +28,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libdw.h" +#include "elfutils/libdw.h" #include "Elf_X.h" #include "dwarfHandle.h" #include "dwarfFrameParser.h" diff --git a/dyninstAPI/h/BPatch.h b/dyninstAPI/h/BPatch.h index 4f03c189f2..6be15cf07c 100644 --- a/dyninstAPI/h/BPatch.h +++ b/dyninstAPI/h/BPatch.h @@ -42,7 +42,7 @@ #include "BPatch_callbacks.h" #include -#include "version.h" +#include "dyninstversion.h" class BPatch_typeCollection; class BPatch_libInfo; diff --git a/dyninstAPI/src/image.C b/dyninstAPI/src/image.C index 6569447cad..38b21a4890 100644 --- a/dyninstAPI/src/image.C +++ b/dyninstAPI/src/image.C @@ -67,7 +67,7 @@ #if defined( cap_dwarf ) #include "dwarf.h" -#include "libdw.h" +#include "elfutils/libdw.h" #endif #if defined(_MSC_VER) diff --git a/instructionAPI/src/Instruction.C b/instructionAPI/src/Instruction.C index cd7a484704..2b3cf0be86 100644 --- a/instructionAPI/src/Instruction.C +++ b/instructionAPI/src/Instruction.C @@ -48,7 +48,7 @@ #include #include "common/src/arch-x86.h" -#include "version.h" +#include "dyninstversion.h" using namespace std; using namespace NS_x86; diff --git a/parseAPI/src/CodeObject.C b/parseAPI/src/CodeObject.C index 2ab2e56205..c0c1c93ed1 100644 --- a/parseAPI/src/CodeObject.C +++ b/parseAPI/src/CodeObject.C @@ -35,7 +35,7 @@ #include "Parser.h" #include "debug_parse.h" -#include "version.h" +#include "dyninstversion.h" using namespace std; using namespace Dyninst; diff --git a/patchAPI/src/PatchMgr.C b/patchAPI/src/PatchMgr.C index f0d2f71465..df8431675a 100644 --- a/patchAPI/src/PatchMgr.C +++ b/patchAPI/src/PatchMgr.C @@ -35,7 +35,7 @@ #include "Point.h" #include "PatchCallback.h" -#include "version.h" +#include "dyninstversion.h" using namespace Dyninst; using namespace PatchAPI; diff --git a/proccontrol/src/process.C b/proccontrol/src/process.C index c0c3837e25..165f49aacd 100644 --- a/proccontrol/src/process.C +++ b/proccontrol/src/process.C @@ -27,7 +27,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "version.h" +#include "dyninstversion.h" #include "int_process.h" #include "irpc.h" #include "procpool.h" diff --git a/stackwalk/h/walker.h b/stackwalk/h/walker.h index 50681df4c7..b33664c346 100644 --- a/stackwalk/h/walker.h +++ b/stackwalk/h/walker.h @@ -38,7 +38,7 @@ #include #include -#include "version.h" +#include "dyninstversion.h" #define SW_MAJOR DYNINST_MAJOR_VERSION #define SW_MINOR DYNINST_MINOR_VERSION diff --git a/stackwalk/src/dbginfo-stepper.C b/stackwalk/src/dbginfo-stepper.C index dd20c829b4..9127e43d48 100644 --- a/stackwalk/src/dbginfo-stepper.C +++ b/stackwalk/src/dbginfo-stepper.C @@ -55,7 +55,7 @@ static std::map dwarf_info; #include #include "dwarf.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "Elf_X.h" static DwarfFrameParser::Ptr getAuxDwarfInfo(std::string s) diff --git a/symtabAPI/h/Module.h b/symtabAPI/h/Module.h index 4ce5352c75..b4831f774c 100644 --- a/symtabAPI/h/Module.h +++ b/symtabAPI/h/Module.h @@ -39,7 +39,7 @@ #include "IBSTree.h" #include "IBSTree-fast.h" #if defined(cap_dwarf) -#include "libdw.h" +#include "elfutils/libdw.h" #endif #include #include "RangeLookup.h" diff --git a/symtabAPI/h/Symtab.h b/symtabAPI/h/Symtab.h index cad95014ab..69fcc3232a 100644 --- a/symtabAPI/h/Symtab.h +++ b/symtabAPI/h/Symtab.h @@ -42,7 +42,7 @@ #include "ProcReader.h" #include "IBSTree.h" -#include "version.h" +#include "dyninstversion.h" #include "boost/shared_ptr.hpp" #include "boost/multi_index_container.hpp" diff --git a/symtabAPI/src/Object-elf.C b/symtabAPI/src/Object-elf.C index 9dfe3c0aa3..37b9954374 100644 --- a/symtabAPI/src/Object-elf.C +++ b/symtabAPI/src/Object-elf.C @@ -2415,13 +2415,14 @@ string Object::find_symbol(string name) #if defined(cap_dwarf) -void pd_dwarf_handler(Dwarf_Error error, Dwarf_Ptr /*userData*/) +void pd_dwarf_handler() { - if (error == NULL) + const char *dwarf_msg = dwarf_errmsg(0); + + if (dwarf_msg == NULL) return; - char *dwarf_msg = dwarf_errmsg(error); - string str = string("DWARF Error: ")+ dwarf_msg; + string str = string("DWARF Error: ") + dwarf_msg; dwarf_err_func(str.c_str()); //bperr( "DWARF error: %s\n", dwarf_msg); @@ -2430,35 +2431,37 @@ void pd_dwarf_handler(Dwarf_Error error, Dwarf_Ptr /*userData*/) Dwarf_Sword declFileNo = 0; char ** declFileNoToName = NULL; -bool Object::dwarf_parse_aranges(Dwarf dbg, std::set& dies_seen) +bool Object::dwarf_parse_aranges(::Dwarf * dbg, std::set& dies_seen) { - Dwarf_Arange* ranges; - Dwarf_Sword num_ranges; - int status = dwarf_get_aranges(dbg, &ranges, &num_ranges, NULL); - if(status != DW_DLV_OK) return false; - Dwarf_Off cu_die_off; - Dwarf_Die cu_die; + Dwarf_Aranges* ranges; + size_t num_ranges; + int status = dwarf_getaranges(dbg, &ranges, &num_ranges); + if(status != 0) return false; // cout << "Processing " << num_ranges << "DWARF ranges" << endl; - for(int i = 0; i < num_ranges; i++) + for(size_t i = 0; i < num_ranges; i++) { + Dwarf_Arange * range = dwarf_onearange(ranges, i); + if(!range) continue; + Dwarf_Addr start; - Dwarf_Unsigned len, segment, segment_size; - // TODO: info_b has segment info from DWARF4 - status = dwarf_get_arange_info_b(ranges[i], &segment, &segment_size, &start, &len, &cu_die_off, NULL); - assert(status == DW_DLV_OK); - if(segment_size > 0) - { - cout << "WARNING: ignoring segment info" << endl; - } - if(dies_seen.find(cu_die_off) != dies_seen.end()) continue; + Dwarf_Word len; + Dwarf_Off cu_die_off; + status = dwarf_getarangeinfo(range, &start, &len, &cu_die_off); + assert(status == 0); + + if(dies_seen.count(cu_die_off) != 0) continue; if(len == 0) continue; - status = dwarf_offdie_b(dbg, cu_die_off, Dwarf_Bool(true), &cu_die, NULL); - assert(status == DW_DLV_OK); + + Dwarf_Die cu_die, * cu_die_p; + cu_die_p = dwarf_offdie(dbg, cu_die_off, &cu_die); + assert(cu_die_p != NULL); + std::string modname; if(!DwarfWalker::findDieName(dbg, cu_die, modname)) { modname = associated_symtab->file(); // default module } + Offset actual_start, actual_end; convertDebugOffset(start, actual_start); convertDebugOffset(start + len, actual_end); @@ -2467,25 +2470,23 @@ bool Object::dwarf_parse_aranges(Dwarf dbg, std::set& dies_seen) m->addDebugInfo(cu_die); DwarfWalker::buildSrcFiles(dbg, cu_die, m->getStrings()); dies_seen.insert(cu_die_off); - dwarf_dealloc(dbg, ranges[i], DW_DLA_ARANGE); } - dwarf_dealloc(dbg, ranges, DW_DLA_LIST); return true; } bool Object::fix_global_symbol_modules_static_dwarf() { /* Initialize libdwarf. */ - Dwarf *dbg_ptr = dwarf->type_dbg(); + ::Dwarf **dbg_ptr = dwarf->type_dbg(); if (!dbg_ptr) return false; - Dwarf dbg = *dbg_ptr; + ::Dwarf *dbg = *dbg_ptr; std::set dies_seen; Dwarf_Off cu_die_off; Dwarf_Die cu_die; dwarf_parse_aranges(dbg, dies_seen); /* Iterate over the compilation-unit headers. */ - while (dwarf_next_cu_header_c(dbg, Dwarf_Bool(true), + while (dwarf_next_cu_header_c(dbg, bool(true), NULL, NULL, NULL, @@ -2496,7 +2497,7 @@ bool Object::fix_global_symbol_modules_static_dwarf() NULL, &cu_die_off, NULL) == DW_DLV_OK ) { - int status = dwarf_siblingof_b(dbg, NULL, Dwarf_Bool(true), &cu_die, NULL); + int status = dwarf_siblingof_b(dbg, NULL, bool(true), &cu_die, NULL); assert(status == DW_DLV_OK); if(dies_seen.find(cu_die_off) != dies_seen.end()) continue; std::string modname; @@ -2530,7 +2531,7 @@ bool Object::fix_global_symbol_modules_static_dwarf() { if((dwarf_lineaddr(lines[i], &low, NULL) == DW_DLV_OK) && low) { - Dwarf_Bool is_end = false; + bool is_end = false; Dwarf_Addr high = low; int result = DW_DLV_OK; for(; (i < num_lines) && @@ -3347,7 +3348,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, { Dwarf_Error err = (Dwarf_Error) NULL; Dwarf_Addr low_pc; - Dwarf_Unsigned bytes_in_cie; + unsigned long long bytes_in_cie; Dwarf_Off fde_offset, cie_offset; Dwarf_FDE fde; Dwarf_CIE cie; @@ -3357,7 +3358,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, unsigned long value, table_end, region_start, region_size, landingpad_base; unsigned long catch_block, action, augmentor_len; Dwarf_Small *fde_augdata, *cie_augdata; - Dwarf_Unsigned fde_augdata_len, cie_augdata_len; + unsigned long long fde_augdata_len, cie_augdata_len; //For each FDE for (int i = 0; i < fde_count; i++) { @@ -3370,9 +3371,9 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, unsigned char *fde_bytes, *cie_bytes; //Get the FDE - status = dwarf_get_fde_n(fde_data, (Dwarf_Unsigned) i, &fde, &err); + status = dwarf_get_fde_n(fde_data, (unsigned long long) i, &fde, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } @@ -3384,7 +3385,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, NULL, &cie_offset, NULL, &fde_offset, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } //The LSB strays from the DWARF here, when parsing the except_eh section @@ -3397,7 +3398,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, //Get the CIE for the FDE status = dwarf_get_cie_of_fde(fde, &cie, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } @@ -3405,7 +3406,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, status = dwarf_get_cie_info(cie, &bytes_in_cie, NULL, &augmentor, NULL, NULL, NULL, NULL, NULL, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } @@ -3439,7 +3440,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, &cie_augdata_len, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } @@ -3489,7 +3490,7 @@ int read_except_table_gcc3(Dwarf_FDE *fde_data, Dwarf_Sword fde_count, &fde_augdata_len, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } cur_augdata = (unsigned char *) fde_augdata; @@ -3680,7 +3681,7 @@ bool Object::find_catch_blocks(Elf_X_Shdr *eh_frame, Dwarf_FDE *fde_data; Dwarf_Sword cie_count, fde_count; Dwarf_Error err = (Dwarf_Error) NULL; - Dwarf_Unsigned bytes_in_cie; + unsigned long long bytes_in_cie; char *augmentor; int status, gcc_ver = 3; unsigned i; @@ -3691,12 +3692,12 @@ bool Object::find_catch_blocks(Elf_X_Shdr *eh_frame, return true; } - Dwarf *dbg_ptr = dwarf->frame_dbg(); + ::Dwarf *dbg_ptr = dwarf->frame_dbg(); if (!dbg_ptr) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); return false; } - Dwarf &dbg = *dbg_ptr; + ::Dwarf &dbg = *dbg_ptr; //Read the FDE and CIE information status = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_count, @@ -3719,7 +3720,7 @@ bool Object::find_catch_blocks(Elf_X_Shdr *eh_frame, status = dwarf_get_cie_info(cie_data[i], &bytes_in_cie, NULL, &augmentor, NULL, NULL, NULL, NULL, NULL, &err); if (status != DW_DLV_OK) { - pd_dwarf_handler(err, NULL); + pd_dwarf_handler(); goto cleanup; } if (augmentor[0] == 'e' && augmentor[1] == 'h') { @@ -3945,19 +3946,19 @@ void Object::getModuleLanguageInfo(dyn_hash_map *mod if (hasDwarfInfo()) { int status; - Dwarf *dbg_ptr = dwarf->type_dbg(); + ::Dwarf *dbg_ptr = dwarf->type_dbg(); if (!dbg_ptr) return; - Dwarf &dbg = *dbg_ptr; + ::Dwarf &dbg = *dbg_ptr; - Dwarf_Unsigned hdr; + unsigned long long hdr; char * moduleName = NULL; Dwarf_Die moduleDIE = NULL; Dwarf_Attribute languageAttribute = NULL; bool done = false; /* Only .debug_info for now, not .debug_types */ - Dwarf_Bool is_info = 1; + bool is_info = 1; while( !done && dwarf_next_cu_header_c( dbg, is_info, @@ -3967,7 +3968,7 @@ void Object::getModuleLanguageInfo(dyn_hash_map *mod & hdr, NULL ) == DW_DLV_OK ) { Dwarf_Half moduleTag; - Dwarf_Unsigned languageConstant; + unsigned long long languageConstant; status = dwarf_siblingof_b(dbg, NULL, is_info, &moduleDIE, NULL); if (status != DW_DLV_OK) { @@ -4322,10 +4323,10 @@ void Object::parseStabFileLineInfo() } /* end parseStabFileLineInfo() */ struct open_statement { - Dwarf_Unsigned string_table_index; + unsigned long long string_table_index; Dwarf_Addr start_addr; Dwarf_Addr end_addr; - Dwarf_Unsigned line_number; + unsigned long long line_number; Dwarf_Sword column_number; }; @@ -4333,11 +4334,11 @@ struct open_statement { void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module) { std::vector open_statements; - Dwarf *dbg_ptr = dwarf->line_dbg(); + ::Dwarf *dbg_ptr = dwarf->line_dbg(); if (!dbg_ptr) return; if(!cuDIE) return; - Dwarf dbg = *dbg_ptr; + ::Dwarf dbg = *dbg_ptr; /* Acquire this CU's source lines. */ Dwarf_Line * lineBuffer; Dwarf_Sword lineCount; @@ -4433,7 +4434,7 @@ void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module) } current_statement.string_table_index += offset; - Dwarf_Bool isEndOfSequence; + bool isEndOfSequence; status = dwarf_lineendsequence( lineBuffer[i], & isEndOfSequence, NULL ); if ( status != DW_DLV_OK ) { cout << "dwarf_lineendsequence failed" << endl; @@ -4442,7 +4443,7 @@ void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module) if(i == lineCount - 1) { isEndOfSequence = true; } - Dwarf_Bool isStatement; + bool isStatement; status = dwarf_linebeginstatement(lineBuffer[i], &isStatement, NULL); if(status != DW_DLV_OK) { cout << "dwarf_linebeginstatement failed" << endl; @@ -4497,7 +4498,7 @@ void Object::parseLineInfoForCU(Dwarf_Die cuDIE, LineInformation* li_for_module) void Object::parseLineInfoForAddr(Offset addr_to_find) { - Dwarf *dbg_ptr = dwarf->line_dbg(); + ::Dwarf *dbg_ptr = dwarf->line_dbg(); if (!dbg_ptr) return; std::set mod_for_offset; @@ -4545,7 +4546,7 @@ void Object::parseTypeInfo() #endif parseStabTypes(); - Dwarf* typeInfo = dwarf->type_dbg(); + ::Dwarf* typeInfo = dwarf->type_dbg(); if(!typeInfo) return; DwarfWalker walker(associated_symtab, *typeInfo); walker.parse(); diff --git a/symtabAPI/src/Object-elf.h b/symtabAPI/src/Object-elf.h index 7bf468eab4..6f6246d4c5 100644 --- a/symtabAPI/src/Object-elf.h +++ b/symtabAPI/src/Object-elf.h @@ -39,7 +39,7 @@ #if defined(cap_dwarf) //#include "dwarf.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "dwarfHandle.h" #endif @@ -522,10 +522,10 @@ class Object; public: void parseDwarfFileLineInfo(); void parseLineInfoForAddr(Offset addr_to_find); - - private: - void parseLineInfoForCU(Module::DebugInfoT cuDIE, LineInformation* li); - bool dwarf_parse_aranges(::Dwarf *dbg, std::set& dies_seen); + +private: + void parseLineInfoForCU(Module::DebugInfoT cuDIE, LineInformation* li); + bool dwarf_parse_aranges(::Dwarf *dbg, std::set& dies_seen); void parseDwarfTypes(Symtab *obj); void parseStabTypes(); diff --git a/symtabAPI/src/Symtab.C b/symtabAPI/src/Symtab.C index 989bbbf4ec..5b612be023 100644 --- a/symtabAPI/src/Symtab.C +++ b/symtabAPI/src/Symtab.C @@ -63,7 +63,7 @@ #include #include -#include "version.h" +#include "dyninstversion.h" using namespace Dyninst; using namespace Dyninst::SymtabAPI; diff --git a/symtabAPI/src/dwarfWalker.C b/symtabAPI/src/dwarfWalker.C index 3a06dfadd5..041a6bf558 100644 --- a/symtabAPI/src/dwarfWalker.C +++ b/symtabAPI/src/dwarfWalker.C @@ -110,7 +110,7 @@ bool DwarfWalker::parse() { /* First .debug_types (0), then .debug_info (1) */ for (int i = 0; i < 2; ++i) { - Dwarf_Bool is_info = i; + bool is_info = i; /* NB: parseModule used to compute compile_offset as 11 bytes before the * first die offset, to account for the header. This would need 23 bytes @@ -172,7 +172,7 @@ bool DwarfWalker::parse() { return true; } -bool DwarfWalker::parseModule(Dwarf_Bool is_info, Module *&fixUnknownMod) { +bool DwarfWalker::parseModule(bool is_info, Module *&fixUnknownMod) { /* Obtain the module DIE. */ Dwarf_Die moduleDIE; DWARF_FAIL_RET(dwarf_siblingof_b( dbg(), NULL, is_info, &moduleDIE, NULL )); @@ -425,7 +425,7 @@ bool DwarfWalker::parse_int(Dwarf_Die e, bool p) { dwarf_printf("(0x%lx) Asking for sibling\n", id()); Dwarf_Die siblingDwarf; - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry()); + bool is_info = dwarf_get_die_infotypes_flag(entry()); int status = dwarf_siblingof_b( dbg(), entry(), is_info, & siblingDwarf, NULL ); DWARF_CHECK_RET(status == DW_DLV_ERROR); @@ -446,7 +446,7 @@ bool DwarfWalker::parse_int(Dwarf_Die e, bool p) { bool DwarfWalker::parseCallsite() { - Dwarf_Bool has_line = false, has_file = false; + bool has_line = false, has_file = false; DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_call_file, &has_file, NULL)); if (!has_file) return true; @@ -845,7 +845,7 @@ bool DwarfWalker::parseVariable() { if (!findType(type, false)) return false; assert(type); - Dwarf_Unsigned variableLineNo; + unsigned long long variableLineNo; bool hasLineNumber = false; std::string fileName; @@ -899,7 +899,7 @@ void DwarfWalker::createGlobalVariable(const vector &locs, Typ } void DwarfWalker::createLocalVariable(const vector &locs, Type *type, - Dwarf_Unsigned variableLineNo, + unsigned long long variableLineNo, const string &fileName) { localVar * newVariable = new localVar(curName(), type, @@ -974,7 +974,7 @@ bool DwarfWalker::parseFormalParam() { Type *paramType = NULL; if (!findType(paramType, false)) return false; - Dwarf_Unsigned lineNo = 0; + unsigned long long lineNo = 0; bool hasLineNumber = false; std::string fileName; if (!getLineInformation(lineNo, hasLineNumber, fileName)) return false; @@ -983,7 +983,7 @@ bool DwarfWalker::parseFormalParam() { return true; } -void DwarfWalker::createParameter(const vector &locs, Type *paramType, Dwarf_Unsigned lineNo, +void DwarfWalker::createParameter(const vector &locs, Type *paramType, unsigned long long lineNo, const string &fileName) { localVar * newParameter = new localVar(curName(), paramType, @@ -1327,7 +1327,7 @@ bool DwarfWalker::parseTypeReferences() { } bool DwarfWalker::hasDeclaration(bool &isDecl) { - Dwarf_Bool tmp; + bool tmp; DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_declaration, &tmp, NULL )); @@ -1357,7 +1357,7 @@ bool DwarfWalker::handleAbstractOrigin(bool &isAbstract) { dwarf_printf("(0x%lx) Checking for abstract origin\n", id()); isAbstract = false; - Dwarf_Bool isAbstractOrigin; + bool isAbstractOrigin; DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_abstract_origin, @@ -1374,7 +1374,7 @@ bool DwarfWalker::handleAbstractOrigin(bool &isAbstract) { Dwarf_Off abstractOffset; if (!findDieOffset( abstractAttribute, abstractOffset )) return false; - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry()); + bool is_info = dwarf_get_die_infotypes_flag(entry()); DWARF_FAIL_RET(dwarf_offdie_b( dbg(), abstractOffset, is_info, & absE, NULL)); dwarf_dealloc( dbg() , abstractAttribute, DW_DLA_ATTR ); @@ -1390,7 +1390,7 @@ bool DwarfWalker::handleSpecification(bool &hasSpec) { dwarf_printf("(0x%lx) Checking for separate specification\n", id()); hasSpec = false; - Dwarf_Bool hasSpecification; + bool hasSpecification; DWARF_FAIL_RET(dwarf_hasattr( entry(), DW_AT_specification, & hasSpecification, NULL )); if (!hasSpecification) return true; @@ -1405,7 +1405,7 @@ bool DwarfWalker::handleSpecification(bool &hasSpec) { Dwarf_Off specOffset; if (!findDieOffset( specAttribute, specOffset )) return false; - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry()); + bool is_info = dwarf_get_die_infotypes_flag(entry()); DWARF_FAIL_RET(dwarf_offdie_b( dbg(), specOffset, is_info, & specE, NULL )); dwarf_dealloc( dbg(), specAttribute, DW_DLA_ATTR ); @@ -1497,7 +1497,7 @@ bool DwarfWalker::getReturnType(bool hasSpecification, Type *&returnType) { Dwarf_Attribute typeAttribute; int status = DW_DLV_OK; - Dwarf_Bool is_info = true; + bool is_info = true; if (hasSpecification) { is_info = dwarf_get_die_infotypes_flag(specEntry()); status = dwarf_attr( specEntry(), DW_AT_type, & typeAttribute, NULL ); @@ -1588,7 +1588,7 @@ bool DwarfWalker::findType(Type *&type, bool defaultToVoid) { return false; } - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(specEntry()); + bool is_info = dwarf_get_die_infotypes_flag(specEntry()); bool ret = findAnyType( typeAttribute, is_info, type ); dwarf_dealloc( dbg(), typeAttribute, DW_DLA_ATTR ); @@ -1622,12 +1622,12 @@ bool DwarfWalker::findDieOffset(Dwarf_Attribute attr, Dwarf_Off &offset) { } bool DwarfWalker::findAnyType(Dwarf_Attribute typeAttribute, - Dwarf_Bool is_info, Type *&type) { + bool is_info, Type *&type) { /* If this is a ref_sig8, look for the type elsewhere. */ Dwarf_Half form; DWARF_FAIL_RET(dwarf_whatform(typeAttribute, &form, NULL)); if (form == DW_FORM_ref_sig8) { - Dwarf_Sig8 signature; + char signature[8]; DWARF_FAIL_RET(dwarf_formsig8(typeAttribute, &signature, NULL)); return findSig8Type(&signature, type); } @@ -1658,7 +1658,7 @@ bool DwarfWalker::findAnyType(Dwarf_Attribute typeAttribute, return true; } -bool DwarfWalker::getLineInformation(Dwarf_Unsigned &variableLineNo, +bool DwarfWalker::getLineInformation(unsigned long long &variableLineNo, bool &hasLineNumber, std::string &fileName) { Dwarf_Attribute fileDeclAttribute; @@ -1670,7 +1670,7 @@ bool DwarfWalker::getLineInformation(Dwarf_Unsigned &variableLineNo, } else if (status == DW_DLV_OK) { StringTablePtr files = srcFiles(); - Dwarf_Unsigned fileNameDeclVal; + unsigned long long fileNameDeclVal; DWARF_FAIL_RET(dwarf_formudata(fileDeclAttribute, &fileNameDeclVal, NULL)); dwarf_dealloc( dbg(), fileDeclAttribute, DW_DLA_ATTR ); if (fileNameDeclVal >= files->size() || fileNameDeclVal <= 0) { @@ -1703,7 +1703,7 @@ bool DwarfWalker::decodeLocationList(Dwarf_Half attr, std::vector &locs) { dwarf_printf("(0x%lx) decodeLocationList for attr %d\n", id(), attr); - Dwarf_Bool hasAttr = false; + bool hasAttr = false; DWARF_FAIL_RET(dwarf_hasattr(entry(), attr, &hasAttr, NULL)); if (!hasAttr) { @@ -1844,7 +1844,7 @@ bool DwarfWalker::findString(Dwarf_Half attr, } bool DwarfWalker::findConstant(Dwarf_Half attr, Address &value, Dwarf_Die entry, Dwarf dbg) { - Dwarf_Bool has = false; + bool has = false; DWARF_FAIL_RET(dwarf_hasattr(entry, attr, &has, NULL)); if (!has) return false; @@ -1885,7 +1885,7 @@ bool DwarfWalker::findConstantWithForm(Dwarf_Attribute &locationAttribute, case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_udata: - Dwarf_Unsigned u_tmp; + unsigned long long u_tmp; DWARF_FAIL_RET(dwarf_formudata(locationAttribute, &u_tmp, NULL)); value = (Address) u_tmp; return true; @@ -1934,12 +1934,12 @@ bool DwarfWalker::constructConstantVariableLocation(Address value, } bool DwarfWalker::findSize(unsigned &size) { - Dwarf_Bool hasSize; + bool hasSize; DWARF_FAIL_RET(dwarf_hasattr(entry(), DW_AT_byte_size, &hasSize, NULL)); if (!hasSize) return false; Dwarf_Attribute byteSizeAttr; - Dwarf_Unsigned byteSize; + unsigned long long byteSize; DWARF_FAIL_RET(dwarf_attr( specEntry(), DW_AT_byte_size, & byteSizeAttr, NULL )); DWARF_FAIL_RET(dwarf_formudata( byteSizeAttr, & byteSize, NULL )); @@ -1960,7 +1960,7 @@ bool DwarfWalker::findVisibility(visibility_t &visibility) { return true; } - Dwarf_Unsigned visValue; + unsigned long long visValue; DWARF_FAIL_RET(dwarf_formudata( visAttr, & visValue, NULL )); switch( visValue ) { @@ -2006,7 +2006,7 @@ bool DwarfWalker::fixBitFields(std::vector &locs, if ( status == DW_DLV_OK && locs.size() ) { - Dwarf_Unsigned memberOffset_du = locs[0].frameOffset; + unsigned long long memberOffset_du = locs[0].frameOffset; DWARF_FAIL_RET(dwarf_formudata( bitOffset, &memberOffset_du, NULL )); @@ -2015,7 +2015,7 @@ bool DwarfWalker::fixBitFields(std::vector &locs, Dwarf_Attribute bitSize; DWARF_FAIL_RET(dwarf_attr( entry(), DW_AT_bit_size, & bitSize, NULL )); - Dwarf_Unsigned memberSize_du = size; + unsigned long long memberSize_du = size; DWARF_FAIL_RET(dwarf_formudata( bitSize, &memberSize_du, NULL )); dwarf_dealloc( dbg(), bitSize, DW_DLA_ATTR ); @@ -2088,7 +2088,7 @@ bool DwarfWalker::parseSubrangeAUX(Dwarf_Die entry, /* Look for the lower bound. */ Dwarf_Attribute lowerBoundAttribute; - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry); + bool is_info = dwarf_get_die_infotypes_flag(entry); int status = dwarf_attr( entry, DW_AT_lower_bound, & lowerBoundAttribute, NULL ); DWARF_CHECK_RET(status == DW_DLV_ERROR); @@ -2159,7 +2159,7 @@ typeArray *DwarfWalker::parseMultiDimensionalArray(Dwarf_Die range, /* Does the recursion continue? */ Dwarf_Die nextSibling; - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(range); + bool is_info = dwarf_get_die_infotypes_flag(range); int status = dwarf_siblingof_b( dbg(), range, is_info, & nextSibling, NULL ); DWARF_CHECK_RET_VAL(status == DW_DLV_ERROR, NULL); @@ -2195,7 +2195,7 @@ typeArray *DwarfWalker::parseMultiDimensionalArray(Dwarf_Die range, return outerType; } /* end parseMultiDimensionalArray() */ -bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_info, +bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, bool is_info, std::string &boundString ) { Dwarf_Half boundForm; @@ -2211,7 +2211,7 @@ bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_in dwarf_printf("(0x%lx) Decoding form %d with formudata\n", id(), boundForm); - Dwarf_Unsigned constantBound; + unsigned long long constantBound; DWARF_FAIL_RET(dwarf_formudata( boundAttribute, & constantBound, NULL )); char bString[40]; sprintf(bString, "%llu", (unsigned long long)constantBound); @@ -2257,7 +2257,7 @@ bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_in DWARF_CHECK_RET(status == DW_DLV_ERROR); if ( status == DW_DLV_OK ) { - Dwarf_Unsigned constBoundValue; + unsigned long long constBoundValue; DWARF_FAIL_RET(dwarf_formudata( constBoundAttribute, & constBoundValue, NULL )); char bString[40]; @@ -2294,7 +2294,7 @@ bool DwarfWalker::decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_in bool DwarfWalker::decodeExpression(Dwarf_Attribute &attr, std::vector &locs) { - Dwarf_Unsigned expr_len; + unsigned long long expr_len; Dwarf_Ptr expr_ptr; DWARF_FAIL_RET(dwarf_formexprloc(attr, &expr_len, &expr_ptr, NULL)); unsigned char *bitstream = (unsigned char *) expr_ptr; @@ -2497,7 +2497,7 @@ typeId_t DwarfWalker::get_type_id(Dwarf_Off offset, bool is_info) typeId_t DwarfWalker::type_id() { - Dwarf_Bool is_info = dwarf_get_die_infotypes_flag(entry()); + bool is_info = dwarf_get_die_infotypes_flag(entry()); return get_type_id(offset(), is_info); } @@ -2507,7 +2507,7 @@ void DwarfWalker::findAllSig8Types() * In DWARF4, only .debug_types contains DW_TAG_type_unit, * but DWARF5 is considering them for .debug_info too.*/ for (int i = 0; i < 2; ++i) { - Dwarf_Bool is_info = i; + bool is_info = i; Dwarf_Error err; compile_offset = next_cu_header = 0; @@ -2528,7 +2528,7 @@ void DwarfWalker::findAllSig8Types() } } -bool DwarfWalker::parseModuleSig8(Dwarf_Bool is_info) +bool DwarfWalker::parseModuleSig8(bool is_info) { /* Obtain the type DIE. */ Dwarf_Die typeDIE; @@ -2553,7 +2553,7 @@ bool DwarfWalker::parseModuleSig8(Dwarf_Bool is_info) return true; } -bool DwarfWalker::findSig8Type(Dwarf_Sig8 *signature, Type *&returnType) +bool DwarfWalker::findSig8Type(char ** signature, Type *&returnType) { uint64_t sig8 = * reinterpret_cast(signature); auto it = sig8_type_ids_.find(sig8); diff --git a/symtabAPI/src/dwarfWalker.h b/symtabAPI/src/dwarfWalker.h index 1f1cda9ca1..bb8fa219eb 100644 --- a/symtabAPI/src/dwarfWalker.h +++ b/symtabAPI/src/dwarfWalker.h @@ -7,7 +7,7 @@ #include "elf.h" #include "libelf.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include #include #include @@ -20,363 +20,364 @@ #include namespace Dyninst { - namespace SymtabAPI { +namespace SymtabAPI { // A restructuring of walkDwarvenTree - class Symtab; - class Module; - class Object; - class Function; - class FunctionBase; - class typeCommon; - class typeEnum; - class fieldListType; - class typeCollection; - class Type; - class DwarfParseActions { - - protected: - Dwarf dbg() { return dbg_; } - - - Module *& mod() { return mod_; } - - - typeCollection *tc() { return typeCollection::getModTypeCollection(mod()); } - - private: - Module *mod_; - Dwarf dbg_; - public: - DwarfParseActions(Symtab* s, Dwarf d) : - mod_(NULL), - dbg_(d), - symtab_(s) - {} - typedef std::vector > range_set_t; - typedef boost::shared_ptr > > range_set_ptr; - private: - struct Context { - FunctionBase *func; - typeCommon *commonBlock; - typeEnum *enumType; - fieldListType *enclosure; - bool parseSibling; - bool parseChild; - Dwarf_Die entry; - Dwarf_Die specEntry; - Dwarf_Die abstractEntry; - Dwarf_Off offset; - Dwarf_Tag tag; - Address base; - range_set_ptr ranges; - Context() : - func(NULL), commonBlock(NULL), - enumType(NULL), enclosure(NULL), - parseSibling(true), parseChild(true), - entry(NULL), specEntry(NULL), abstractEntry(NULL), - offset(0), tag(0), base(0) {}; - }; - - std::stack c; - public: - void push(); - void pop(); - int stack_size() const {return c.size(); } - FunctionBase *curFunc() { return c.top().func; } - virtual std::vector& getFramePtrRefForInit(); - virtual void addMangledFuncName(std::string); - virtual void addPrettyFuncName(std::string); - typeCommon * curCommon() { return c.top().commonBlock; } - typeEnum *curEnum() { return c.top().enumType; } - fieldListType *curEnclosure() { return c.top().enclosure; } - bool parseSibling() { return c.top().parseSibling; } - bool parseChild() { return c.top().parseChild; } - Dwarf_Die entry() { return c.top().entry; } - Dwarf_Die specEntry() { return c.top().specEntry; } - Dwarf_Die abstractEntry() { return c.top().abstractEntry; } - Dwarf_Off offset() { return c.top().offset; } - Dwarf_Tag tag() { return c.top().tag; } - Address base() { return c.top().base; } - range_set_ptr ranges() { return c.top().ranges; } - - void setFunc(FunctionBase *f); - void setCommon(typeCommon *tc) { c.top().commonBlock = tc; } - void setEnum(typeEnum *e) { c.top().enumType = e; } - void setEnclosure(fieldListType *f) { c.top().enclosure = f; } - void setParseSibling(bool p) { c.top().parseSibling = p; } - void setParseChild(bool p) { c.top().parseChild = p; } - virtual void setEntry(Dwarf_Die e) { c.top().entry = e; } - void setSpecEntry(Dwarf_Die e) { c.top().specEntry = e; } - void setAbstractEntry(Dwarf_Die e) { c.top().abstractEntry = e; } - void setOffset(Dwarf_Off o) { c.top().offset = o; } - void setTag(Dwarf_Tag t) { c.top().tag = t; } - void setBase(Address a) { c.top().base = a; } - virtual void setRange(std::pair range) { - if (range.first >= range.second) - return; - if (!c.top().ranges) - c.top().ranges = range_set_ptr(new std::vector >); - c.top().ranges->push_back(range); - } - void clearRanges() { - c.top().ranges = range_set_ptr(); - } - void clearFunc(); - virtual bool isNativeCompiler() const - { - return symtab()->isNativeCompiler(); - } - virtual std::string filename() const - { - return symtab()->file(); - } - virtual void setModuleFromName(std::string moduleName); - virtual Dyninst::Architecture getArchitecture() const - { - return symtab()->getArchitecture(); - } - virtual Offset convertDebugOffset(Offset from); - virtual void setFuncReturnType() {}; - virtual Symbol* findSymbolByName(std::string name, Symbol::SymbolType type) - { - std::vector syms; - if (!symtab()->findSymbol(syms, - name, - type, - anyName)) { - - return NULL; - } - return syms[0]; - } - protected: - Symtab* symtab() const { return symtab_; } - protected: - Symtab *symtab_; - virtual Object * obj() const ; - - }; - - struct ContextGuard { - DwarfParseActions& c; - ContextGuard(DwarfParseActions& c): c(c) { c.push(); } - ~ContextGuard() { c.pop(); } - }; - - class DwarfWalker : public DwarfParseActions { - - - public: - typedef enum { - NoError - - } Error; - - DwarfWalker(Symtab *symtab, Dwarf dbg); - - virtual ~DwarfWalker(); - - bool parse(); - - // Takes current debug state as represented by dbg_; - bool parseModule(Dwarf_Bool is_info, Module *&fixUnknownMod); - - // Non-recursive version of parse - // A Context must be provided as an _input_ to this function, - // whereas parse creates a context. - bool parse_int(Dwarf_Die entry, bool parseSiblings); - static std::pair::iterator, std::vector::iterator> - parseRangeList(Dwarf_Ranges *ranges, Dwarf_Sword num_ranges, Offset initial_base); - private: - enum inline_t { - NormalFunc, - InlinedFunc - }; - - bool parseSubprogram(inline_t func_type); - bool parseLexicalBlock(); - bool parseRangeTypes(Dwarf dbg, Dwarf_Die die); - bool parseCommonBlock(); - bool parseConstant(); - virtual bool parseVariable(); - bool parseFormalParam(); - bool parseBaseType(); - bool parseTypedef(); - bool parseArray(); - bool parseSubrange(); - bool parseEnum(); - bool parseInheritance(); - bool parseStructUnionClass(); - bool parseEnumEntry(); - bool parseMember(); - bool parseConstPackedVolatile(); - bool parseTypeReferences(); - static std::pair parseHighPCLowPC(Dwarf dbg, Dwarf_Die entry); - - - // These vary as we parse the tree - - - // This is a handy scratch space that is cleared for each parse. - std::string &curName() { return name_; } - bool isMangledName() { return is_mangled_name_; } - void setMangledName(bool b) { is_mangled_name_ = b; } - bool nameDefined() { return name_ != ""; } - // These are invariant across a parse - - StringTablePtr srcFiles() { return mod()->getStrings(); } - - // For functions and variables with a separate specification, a - // pointer to that spec. For everyone else, this points to entry - // We might be able to fold this into specEntry and call it - // "authoritativeEntry" or something. - bool hasRanges() { return ranges() != NULL; } - size_t rangesSize() { return ranges()->size(); } - range_set_t::iterator ranges_begin() { return ranges()->begin(); } - range_set_t::iterator ranges_end() { return ranges()->end(); } - - // A printable ID for a particular entry - unsigned long id() { return (unsigned long) (offset() - compile_offset); } - public: - static bool buildSrcFiles(Dwarf dbg, Dwarf_Die entry, StringTablePtr strings); - private: - - bool parseCallsite(); - bool hasDeclaration(bool &decl); - bool findTag(); - bool findOffset(); - bool handleAbstractOrigin(bool &isAbstractOrigin); - bool handleSpecification(bool &hasSpec); - bool findFuncName(); - bool setFunctionFromRange(inline_t func_type); - virtual void setEntry(Dwarf_Die e); - bool getFrameBase(); - bool getReturnType(bool hasSpecification, Type *&returnType); - bool addFuncToContainer(Type *returnType); - bool isStaticStructMember(std::vector &locs, bool &isStatic); - virtual bool findType(Type *&, bool defaultToVoid); - bool findAnyType(Dwarf_Attribute typeAttribute, - Dwarf_Bool is_info, Type *&type); - bool findDieOffset(Dwarf_Attribute attr, Dwarf_Off &offset); - bool getLineInformation(Dwarf_Unsigned &variableLineNo, - bool &hasLineNumber, - std::string &filename); - public: - static bool findDieName(Dwarf dbg, Dwarf_Die die, std::string &); - private: - bool findName(std::string &); - void removeFortranUnderscore(std::string &); - bool findSize(unsigned &size); - bool findVisibility(visibility_t &visibility); - bool findValue(long &value, bool &valid); - bool fixName(std::string &name, Type *type); - bool fixBitFields(std::vector &locs, long &size); - - bool parseSubrangeAUX(Dwarf_Die entry, - std::string &lobound, - std::string &hibound); - bool decodeLocationList(Dwarf_Half attr, - Address *initialVal, - std::vector &locs); - bool checkForConstantOrExpr(Dwarf_Half attr, - Dwarf_Attribute &locationAttribute, - bool &constant, - bool &expr, - Dwarf_Half &form); - bool findString(Dwarf_Half attr, std::string &str); - public: - static bool findConstant(Dwarf_Half attr, Address &value, Dwarf_Die entry, Dwarf dbg); - static bool findConstantWithForm(Dwarf_Attribute &attr, - Dwarf_Half form, - Address &value); - static std::vector getDieRanges(Dwarf dbg, Dwarf_Die die, Offset base); - private: - bool decodeConstantLocation(Dwarf_Attribute &attr, Dwarf_Half form, - std::vector &locs); - bool constructConstantVariableLocation(Address value, - std::vector &locs); - typeArray *parseMultiDimensionalArray(Dwarf_Die firstRange, - Type *elementType); - bool decipherBound(Dwarf_Attribute boundAttribute, Dwarf_Bool is_info, - std::string &name); - - bool decodeExpression(Dwarf_Attribute &attr, - std::vector &locs); - - bool decodeLocationListForStaticOffsetOrAddress(Dwarf_Op* **locationList, - Dwarf_Sword listLength, - std::vector& locs, - Address * initialStackValue = NULL); - void deallocateLocationList(Dwarf_Op* **locationList, - Dwarf_Sword listLength); - - - // Header-only functions get multiple parsed. - std::set parsedFuncs; - private: - std::vector srcFiles_; - char** srcFileList_; - std::string name_; - bool is_mangled_name_; - - // Per-module info - Address modLow; - Address modHigh; - Dwarf_Unsigned cu_header_length; - Dwarf_Half version; - Dwarf_Unsigned abbrev_offset; - Dwarf_Half addr_size; - Dwarf_Half offset_size; - Dwarf_Half extension_size; - Dwarf_Sig8 signature; - Dwarf_Unsigned typeoffset; - Dwarf_Unsigned next_cu_header; - - // For debugging purposes; to match dwarfdump's output, - // we need to subtract a "header overall offset". - Dwarf_Off compile_offset; - - // Type IDs are just int, but Dwarf_Off is 64-bit and may be relative to - // either .debug_info or .debug_types. - dyn_hash_map info_type_ids_; // .debug_info offset -> id - dyn_hash_map types_type_ids_; // .debug_types offset -> id - typeId_t get_type_id(Dwarf_Off offset, bool is_info); - typeId_t type_id(); // get_type_id() for the current entry - - // Map to connect DW_FORM_ref_sig8 to type IDs. - dyn_hash_map sig8_type_ids_; - bool parseModuleSig8(Dwarf_Bool is_info); - void findAllSig8Types(); - bool findSig8Type(Dwarf_Sig8 *signature, Type *&type); - - protected: - virtual void setFuncReturnType(); - - virtual void createLocalVariable(const std::vector &locs, Type *type, - Dwarf_Unsigned variableLineNo, - const std::string &fileName); - - virtual bool createInlineFunc(); - - virtual void setFuncFromLowest(Address lowest); - - virtual void createParameter(const std::vector &locs, Type *paramType, Dwarf_Unsigned lineNo, - const std::string &fileName); - - virtual void setRanges(FunctionBase *func); - - virtual void createGlobalVariable(const std::vector &locs, Type *type); - - virtual bool addStaticClassVariable(const std::vector &locs, Type *type); - - virtual typeCommon *getCommonBlockType(std::string &commonBlockName); - - virtual Symbol *findSymbolForCommonBlock(const std::string &commonBlockName); - }; - +class Symtab; +class Module; +class Object; +class Function; +class FunctionBase; +class typeCommon; +class typeEnum; +class fieldListType; +class typeCollection; +class Type; + +class DwarfParseActions { + +protected: + ::Dwarf* dbg() { return dbg_; } + + Module *& mod() { return mod_; } + + typeCollection *tc() { return typeCollection::getModTypeCollection(mod()); } + +private: + Module *mod_; + ::Dwarf* dbg_; +public: + DwarfParseActions(Symtab* s, ::Dwarf* d) : + mod_(NULL), + dbg_(d), + symtab_(s) +{} + typedef std::vector > range_set_t; + typedef boost::shared_ptr > > range_set_ptr; +private: + struct Context { + FunctionBase *func; + typeCommon *commonBlock; + typeEnum *enumType; + fieldListType *enclosure; + bool parseSibling; + bool parseChild; + Dwarf_Die entry; + Dwarf_Die specEntry; + Dwarf_Die abstractEntry; + Dwarf_Off offset; + unsigned int tag; + Address base; + range_set_ptr ranges; + Context() : + func(NULL), commonBlock(NULL), + enumType(NULL), enclosure(NULL), + parseSibling(true), parseChild(true), + /*entry(NULL), specEntry(NULL), abstractEntry(NULL), + offset(0),*/ tag(0), base(0) {}; }; + + std::stack c; +public: + void push(); + void pop(); + int stack_size() const {return c.size(); } + FunctionBase *curFunc() { return c.top().func; } + virtual std::vector& getFramePtrRefForInit(); + virtual void addMangledFuncName(std::string); + virtual void addPrettyFuncName(std::string); + typeCommon * curCommon() { return c.top().commonBlock; } + typeEnum *curEnum() { return c.top().enumType; } + fieldListType *curEnclosure() { return c.top().enclosure; } + bool parseSibling() { return c.top().parseSibling; } + bool parseChild() { return c.top().parseChild; } + Dwarf_Die entry() { return c.top().entry; } + Dwarf_Die specEntry() { return c.top().specEntry; } + Dwarf_Die abstractEntry() { return c.top().abstractEntry; } + Dwarf_Off offset() { return c.top().offset; } + unsigned int tag() { return c.top().tag; } + Address base() { return c.top().base; } + range_set_ptr ranges() { return c.top().ranges; } + + void setFunc(FunctionBase *f); + void setCommon(typeCommon *tc) { c.top().commonBlock = tc; } + void setEnum(typeEnum *e) { c.top().enumType = e; } + void setEnclosure(fieldListType *f) { c.top().enclosure = f; } + void setParseSibling(bool p) { c.top().parseSibling = p; } + void setParseChild(bool p) { c.top().parseChild = p; } + virtual void setEntry(Dwarf_Die e) { c.top().entry = e; } + void setSpecEntry(Dwarf_Die e) { c.top().specEntry = e; } + void setAbstractEntry(Dwarf_Die e) { c.top().abstractEntry = e; } + void setOffset(Dwarf_Off o) { c.top().offset = o; } + void setTag(unsigned int t) { c.top().tag = t; } + void setBase(Address a) { c.top().base = a; } + virtual void setRange(std::pair range) { + if (range.first >= range.second) + return; + if (!c.top().ranges) + c.top().ranges = range_set_ptr(new std::vector >); + c.top().ranges->push_back(range); + } + void clearRanges() { + c.top().ranges = range_set_ptr(); + } + void clearFunc(); + virtual bool isNativeCompiler() const + { + return symtab()->isNativeCompiler(); + } + virtual std::string filename() const + { + return symtab()->file(); + } + virtual void setModuleFromName(std::string moduleName); + virtual Dyninst::Architecture getArchitecture() const + { + return symtab()->getArchitecture(); + } + virtual Offset convertDebugOffset(Offset from); + virtual void setFuncReturnType() {}; + virtual Symbol* findSymbolByName(std::string name, Symbol::SymbolType type) + { + std::vector syms; + if (!symtab()->findSymbol(syms, + name, + type, + anyName)) { + + return NULL; + } + return syms[0]; + } +protected: + Symtab* symtab() const { return symtab_; } +protected: + Symtab *symtab_; + virtual Object * obj() const ; + +}; // class DwarfParseActions + +struct ContextGuard { + DwarfParseActions& c; + ContextGuard(DwarfParseActions& c): c(c) { c.push(); } + ~ContextGuard() { c.pop(); } }; +class DwarfWalker : public DwarfParseActions { + +public: + typedef enum { + NoError + + } Error; + + DwarfWalker(Symtab *symtab, ::Dwarf* dbg); + + virtual ~DwarfWalker(); + + bool parse(); + + // Takes current debug state as represented by dbg_; + bool parseModule(bool is_info, Module *&fixUnknownMod); + + // Non-recursive version of parse + // A Context must be provided as an _input_ to this function, + // whereas parse creates a context. + bool parse_int(Dwarf_Die entry, bool parseSiblings); + + // FIXME: is this function needed? + //static std::pair::iterator, std::vector::iterator> + // parseRangeList(Dwarf_Ranges *ranges, Dwarf_Sword num_ranges, Offset initial_base); +private: + enum inline_t { + NormalFunc, + InlinedFunc + }; + + bool parseSubprogram(inline_t func_type); + bool parseLexicalBlock(); + bool parseRangeTypes(::Dwarf* dbg, Dwarf_Die die); + bool parseCommonBlock(); + bool parseConstant(); + virtual bool parseVariable(); + bool parseFormalParam(); + bool parseBaseType(); + bool parseTypedef(); + bool parseArray(); + bool parseSubrange(); + bool parseEnum(); + bool parseInheritance(); + bool parseStructUnionClass(); + bool parseEnumEntry(); + bool parseMember(); + bool parseConstPackedVolatile(); + bool parseTypeReferences(); + static std::pair parseHighPCLowPC(::Dwarf* dbg, Dwarf_Die entry); + + + // These vary as we parse the tree + + + // This is a handy scratch space that is cleared for each parse. + std::string &curName() { return name_; } + bool isMangledName() { return is_mangled_name_; } + void setMangledName(bool b) { is_mangled_name_ = b; } + bool nameDefined() { return name_ != ""; } + // These are invariant across a parse + + StringTablePtr srcFiles() { return mod()->getStrings(); } + + // For functions and variables with a separate specification, a + // pointer to that spec. For everyone else, this points to entry + // We might be able to fold this into specEntry and call it + // "authoritativeEntry" or something. + bool hasRanges() { return ranges() != NULL; } + size_t rangesSize() { return ranges()->size(); } + range_set_t::iterator ranges_begin() { return ranges()->begin(); } + range_set_t::iterator ranges_end() { return ranges()->end(); } + + // A printable ID for a particular entry + unsigned long id() { return (unsigned long) (offset() - compile_offset); } +public: + static bool buildSrcFiles(::Dwarf* dbg, Dwarf_Die entry, StringTablePtr strings); +private: + + bool parseCallsite(); + bool hasDeclaration(bool &decl); + bool findTag(); + bool findOffset(); + bool handleAbstractOrigin(bool &isAbstractOrigin); + bool handleSpecification(bool &hasSpec); + bool findFuncName(); + bool setFunctionFromRange(inline_t func_type); + virtual void setEntry(Dwarf_Die e); + bool getFrameBase(); + bool getReturnType(bool hasSpecification, Type *&returnType); + bool addFuncToContainer(Type *returnType); + bool isStaticStructMember(std::vector &locs, bool &isStatic); + virtual bool findType(Type *&, bool defaultToVoid); + bool findAnyType(Dwarf_Attribute typeAttribute, + bool is_info, Type *&type); + bool findDieOffset(Dwarf_Attribute attr, Dwarf_Off &offset); + bool getLineInformation(unsigned long long &variableLineNo, + bool &hasLineNumber, + std::string &filename); +public: + static bool findDieName(::Dwarf* dbg, Dwarf_Die die, std::string &); +private: + bool findName(std::string &); + void removeFortranUnderscore(std::string &); + bool findSize(unsigned &size); + bool findVisibility(visibility_t &visibility); + bool findValue(long &value, bool &valid); + bool fixName(std::string &name, Type *type); + bool fixBitFields(std::vector &locs, long &size); + + bool parseSubrangeAUX(Dwarf_Die entry, + std::string &lobound, + std::string &hibound); + bool decodeLocationList(Dwarf_Half attr, + Address *initialVal, + std::vector &locs); + bool checkForConstantOrExpr(Dwarf_Half attr, + Dwarf_Attribute &locationAttribute, + bool &constant, + bool &expr, + Dwarf_Half &form); + bool findString(Dwarf_Half attr, std::string &str); +public: + static bool findConstant(Dwarf_Half attr, Address &value, Dwarf_Die entry, ::Dwarf* dbg); + static bool findConstantWithForm(Dwarf_Attribute &attr, + Dwarf_Half form, + Address &value); + static std::vector getDieRanges(::Dwarf* dbg, Dwarf_Die die, Offset base); +private: + bool decodeConstantLocation(Dwarf_Attribute &attr, Dwarf_Half form, + std::vector &locs); + bool constructConstantVariableLocation(Address value, + std::vector &locs); + typeArray *parseMultiDimensionalArray(Dwarf_Die firstRange, + Type *elementType); + bool decipherBound(Dwarf_Attribute boundAttribute, bool is_info, + std::string &name); + + bool decodeExpression(Dwarf_Attribute &attr, + std::vector &locs); + + bool decodeLocationListForStaticOffsetOrAddress(Dwarf_Op* **locationList, + Dwarf_Sword listLength, + std::vector& locs, + Address * initialStackValue = NULL); + void deallocateLocationList(Dwarf_Op* **locationList, + Dwarf_Sword listLength); + + + // Header-only functions get multiple parsed. + std::set parsedFuncs; +private: + std::vector srcFiles_; + char** srcFileList_; + std::string name_; + bool is_mangled_name_; + + // Per-module info + Address modLow; + Address modHigh; + unsigned long long cu_header_length; + Dwarf_Half version; + unsigned long long abbrev_offset; + Dwarf_Half addr_size; + Dwarf_Half offset_size; + Dwarf_Half extension_size; + char signature[8]; + unsigned long long typeoffset; + unsigned long long next_cu_header; + + // For debugging purposes; to match dwarfdump's output, + // we need to subtract a "header overall offset". + Dwarf_Off compile_offset; + + // Type IDs are just int, but Dwarf_Off is 64-bit and may be relative to + // either .debug_info or .debug_types. + dyn_hash_map info_type_ids_; // .debug_info offset -> id + dyn_hash_map types_type_ids_; // .debug_types offset -> id + typeId_t get_type_id(Dwarf_Off offset, bool is_info); + typeId_t type_id(); // get_type_id() for the current entry + + // Map to connect DW_FORM_ref_sig8 to type IDs. + dyn_hash_map sig8_type_ids_; + bool parseModuleSig8(bool is_info); + void findAllSig8Types(); + bool findSig8Type(char ** signature, Type *&type); + +protected: + virtual void setFuncReturnType(); + + virtual void createLocalVariable(const std::vector &locs, Type *type, + unsigned long long variableLineNo, + const std::string &fileName); + + virtual bool createInlineFunc(); + + virtual void setFuncFromLowest(Address lowest); + + virtual void createParameter(const std::vector &locs, + Type *paramType, unsigned long long lineNo, const std::string &fileName); + + virtual void setRanges(FunctionBase *func); + + virtual void createGlobalVariable(const std::vector &locs, Type *type); + + virtual bool addStaticClassVariable(const std::vector &locs, Type *type); + + virtual typeCommon *getCommonBlockType(std::string &commonBlockName); + + virtual Symbol *findSymbolForCommonBlock(const std::string &commonBlockName); + +}; // class DwarfWalker + +}; // namespace SymtabAPI +}; // namespace Dyninst + #endif diff --git a/symtabAPI/src/parseDwarf.C b/symtabAPI/src/parseDwarf.C index c6e82efa3b..abcee1905e 100644 --- a/symtabAPI/src/parseDwarf.C +++ b/symtabAPI/src/parseDwarf.C @@ -32,7 +32,7 @@ #include "elf.h" #include "libelf.h" #include "dwarf.h" -#include "libdw.h" +#include "elfutils/libdw.h" #include "dwarfExprParser.h" #include "dwarfFrameParser.h" @@ -50,6 +50,7 @@ #include "annotations.h" #include "debug.h" +#if 0 #ifndef DW_FRAME_CFA_COL3 // This is a newer feature of libdwarf (which has been causing some other // compilation problems locally) -- so we just fudge it for the moment @@ -72,6 +73,7 @@ int dwarf_get_fde_info_for_cfa_reg3( } } #endif +#endif using namespace Dyninst; using namespace Dyninst::SymtabAPI; @@ -88,7 +90,7 @@ std::string convertCharToString(char *ptr) return str; } -extern void pd_dwarf_handler( Dwarf_Error, Dwarf_Ptr ); +/* extern void pd_dwarf_handler( Dwarf_Error, Dwarf_Ptr ); */ void Object::parseDwarfTypes( Symtab *) {