From 1071709d04110eb60a23fe839a528ed0cef26af2 Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Tue, 2 Jul 2024 22:31:01 -0600 Subject: [PATCH] Pull new version of libdwarf --- CMakeLists.txt | 14 +- cmake/{config.h.cmake => config.h.in} | 13 +- pull.sh | 3 +- src/lib/libdwarf/CMakeLists.txt | 10 +- src/lib/libdwarf/Makefile.am | 3 +- src/lib/libdwarf/dwarf.h | 16 +- src/lib/libdwarf/dwarf_debugaddr.c | 214 ++++++++------ src/lib/libdwarf/dwarf_debugaddr.h | 10 + src/lib/libdwarf/dwarf_die_deliv.c | 100 ++++++- src/lib/libdwarf/dwarf_elf_load_headers.c | 4 +- src/lib/libdwarf/dwarf_errmsg_list.h | 5 +- src/lib/libdwarf/dwarf_fission_to_cu.c | 11 +- src/lib/libdwarf/dwarf_form.c | 11 +- .../libdwarf/dwarf_line_table_reader_common.h | 1 - src/lib/libdwarf/dwarf_loc.c | 80 ++++-- src/lib/libdwarf/dwarf_loc.h | 64 +---- src/lib/libdwarf/dwarf_loclists.c | 265 +++++++++++++----- src/lib/libdwarf/dwarf_loclists.h | 86 ++++++ src/lib/libdwarf/dwarf_macho_loader.h | 12 +- src/lib/libdwarf/dwarf_names.c | 33 ++- src/lib/libdwarf/dwarf_opaque.h | 15 +- src/lib/libdwarf/dwarf_peread.c | 10 +- src/lib/libdwarf/dwarf_query.c | 21 -- src/lib/libdwarf/dwarf_rnglists.c | 208 ++++++++++---- src/lib/libdwarf/dwarf_rnglists.h | 13 +- src/lib/libdwarf/dwarf_tied.c | 17 +- src/lib/libdwarf/dwarf_util.h | 2 - src/lib/libdwarf/libdwarf.h | 54 +++- .../{libdwarf.pc.cmake => libdwarf.pc.in} | 2 +- 29 files changed, 911 insertions(+), 386 deletions(-) rename cmake/{config.h.cmake => config.h.in} (92%) create mode 100644 src/lib/libdwarf/dwarf_loclists.h rename src/lib/libdwarf/{libdwarf.pc.cmake => libdwarf.pc.in} (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f219f07..c53fda5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.5) -project(libdwarf VERSION 0.9.1 LANGUAGES C CXX) +project(libdwarf VERSION 0.10.1 + DESCRIPTION "Library to access DWARF debugging information" + HOMEPAGE_URL "https://github.com/davea42/libdwarf-code.git" + LANGUAGES C CXX) # libdwarf option(BUILD_NON_SHARED "build archive library libdwarf[p].a" TRUE) @@ -119,10 +122,8 @@ include(CheckCSourceCompiles) include(CheckCSourceRuns) include(CheckSymbolExists) ### Version also appears in configure.ac -set(VERSION 0.9.2) -set(PACKAGE_VERSION "\"${VERSION}\"") -set(PACKAGE_NAME "libdwarf" ) -set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"") +set(PACKAGE_BUGREPORT "https://github.com/davea42/libdwarf-code/issues") +set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" ) string(REGEX REPLACE "[^a-zA-Z0-9_]" "-" tarname "${tarname1}" ) set(PACKAGE_TARNAME "\"${tarname}\"" ) @@ -244,7 +245,7 @@ endif() # unset(DW_LIBDWARF_STATIC) #endif() -configure_file(cmake/config.h.cmake config.h) +configure_file(cmake/config.h.in config.h) if(BUILD_NON_SHARED) set(DW_LIBDWARF_STATIC -DLIBDWARF_STATIC) @@ -257,6 +258,7 @@ endif() include(GNUInstallDirs) add_subdirectory(src/lib/libdwarf) +add_subdirectory(doc) if ( BUILD_DWARFDUMP ) add_subdirectory(src/bin/dwarfdump) diff --git a/cmake/config.h.cmake b/cmake/config.h.in similarity index 92% rename from cmake/config.h.cmake rename to cmake/config.h.in index a978208..489e4dc 100644 --- a/cmake/config.h.cmake +++ b/cmake/config.h.in @@ -56,20 +56,22 @@ /* Name of package */ #cmakedefine PACKAGE +#define PACKAGE_VERSION "@PROJECT_VERSION@" + /* Define to the address where bug reports for this package should be sent. */ -#cmakedefine PACKAGE_BUGREPORT +#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" /* Define to the full name of this package. */ -#cmakedefine PACKAGE_NAME libdwarf +#define PACKAGE_NAME "@PROJECT_NAME@" /* Define to the full name and version of this package. */ -#cmakedefine PACKAGE_STRING "${PACKAGE_NAME} ${VERSION}" +#define PACKAGE_STRING "@PACKAGE_STRING@" /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME /* Define to the home page for this package. */ -#cmakedefine PACKAGE_URL "${tarname}" ) +#define PACKAGE_URL "@PROJECT_HOMEPAGE_URL@" /* If using the C implementation of alloca, define if you know the @@ -86,9 +88,6 @@ /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} -/* Version number of package */ -#cmakedefine VERSION ${VERSION} - /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/pull.sh b/pull.sh index 0742a36..dcb86e6 100644 --- a/pull.sh +++ b/pull.sh @@ -8,7 +8,8 @@ cd libdwarf-code #git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0 #git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0 #git checkout "8cdcc531f310d1c5ae61da469d8056bdd36b77e7" # v0.9.1 + cmake fixes -git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.2 +# git checkout "5e43a5ab73cb00c8a46660b361366a8c9c3c93c9" # v0.9.2 +git checkout "45ef8e2763f65c31b27cc38bed197b84dc1441d4" # v0.10.2 cd .. echo "Copying files" mkdir -p src/lib diff --git a/src/lib/libdwarf/CMakeLists.txt b/src/lib/libdwarf/CMakeLists.txt index 6cb0b24..0278755 100644 --- a/src/lib/libdwarf/CMakeLists.txt +++ b/src/lib/libdwarf/CMakeLists.txt @@ -50,7 +50,7 @@ dwarf_elfstructs.h dwarf_error.h dwarf_frame.h dwarf_gdbindex.h dwarf_global.h dwarf_harmless.h dwarf_gnu_index.h -dwarf_line.h dwarf_loc.h +dwarf_line.h dwarf_loc.h dwarf_loclists.h dwarf_machoread.h dwarf_macro.h dwarf_macro5.h dwarf_object_detector.h dwarf_opaque.h dwarf_pe_descr.h dwarf_peread.h @@ -69,7 +69,7 @@ dwarf_macho_loader.h dwarf_memcpy_swap.h) set_source_group(CONFIGURATION_FILES "Configuration Files" - ${PROJECT_SOURCE_DIR}/cmake/config.h.cmake + ${PROJECT_SOURCE_DIR}/cmake/config.h.in ${PROJECT_BINARY_DIR}/config.h) # The -DPIC is so we find the right DW_API value in libdwarf.h @@ -109,7 +109,7 @@ if(ZLIB_FOUND AND zstd_FOUND) target_link_libraries(dwarf PRIVATE ZLIB::ZLIB ${ZSTD_LIB} ) endif() set_target_properties(dwarf PROPERTIES PUBLIC_HEADER "libdwarf.h;dwarf.h") - +set_target_properties(dwarf PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}") install(TARGETS dwarf RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" @@ -117,7 +117,7 @@ install(TARGETS dwarf PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) -configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY) +configure_file(libdwarf.pc.in libdwarf.pc @ONLY) # The install has to be here, not in # another CMakeLists.txt to make install work properly @@ -125,7 +125,7 @@ configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY) # for newer cmake. include(CMakePackageConfigHelpers) configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/libdwarfConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfig.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf") -write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" COMPATIBILITY SameMinorVersion) +write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" VERSION "${PROJECT_VERSION}" COMPATIBILITY SameMinorVersion) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/libdwarfConfigVersion.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libdwarf") install(TARGETS dwarf EXPORT libdwarfTargets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" diff --git a/src/lib/libdwarf/Makefile.am b/src/lib/libdwarf/Makefile.am index 2e6a23c..2acc68e 100644 --- a/src/lib/libdwarf/Makefile.am +++ b/src/lib/libdwarf/Makefile.am @@ -66,6 +66,7 @@ dwarf_line.h \ dwarf_line_table_reader_common.h \ dwarf_loc.c \ dwarf_loc.h \ +dwarf_loclists.h \ dwarf_locationop_read.c \ dwarf_loclists.c \ dwarf_macho_loader.h \ @@ -155,7 +156,7 @@ ChangeLog2020 \ CODINGSTYLE \ dw-linetableheader.txt \ CMakeLists.txt \ -libdwarf.pc.cmake \ +libdwarf.pc.in \ cmake/libdwarfConfig.cmake.in \ meson.build \ NEWS \ diff --git a/src/lib/libdwarf/dwarf.h b/src/lib/libdwarf/dwarf.h index 07d3b1d..3967e50 100644 --- a/src/lib/libdwarf/dwarf.h +++ b/src/lib/libdwarf/dwarf.h @@ -158,8 +158,8 @@ extern "C" { /* TI = Texas Instruments, for DWARF in COFF */ /* https://www.ti.com/lit/an/spraab5/spraab5.pdf?ts=1705994928599 */ -#define DW_TAG_lo_user 0x4080 /* TI */ #define DW_TAG_TI_far_type 0x4080 /* TI */ +#define DW_TAG_lo_user 0x4080 /* TI */ #define DW_TAG_MIPS_loop 0x4081 #define DW_TAG_TI_near_type 0x4081 /* TI */ #define DW_TAG_TI_assign_register 0x4082 /* TI */ @@ -456,14 +456,13 @@ extern "C" { /* In extensions, we attempt to include the vendor extension in the name even when the vendor leaves it out. */ - #define DW_AT_HP_block_index 0x2000 /* HP */ -#define DW_AT_TI_veneer 0x2000 /* TI */ - -/* 0x2000 Follows extension so dwarfdump prints the +/* 0x2000 follows extension so dwarfdump prints the most-likely-useful name. */ #define DW_AT_lo_user 0x2000 +#define DW_AT_TI_veneer 0x2000 /* TI */ + #define DW_AT_MIPS_fde 0x2001 /* MIPS/SGI */ #define DW_AT_TI_symbol_name 0x2001 /* TI */ #define DW_AT_MIPS_loop_begin 0x2002 /* MIPS/SGI */ @@ -728,6 +727,7 @@ extern "C" { #define DW_AT_APPLE_property 0x3fed #define DW_AT_APPLE_objc_direct 0x3fee #define DW_AT_APPLE_sdk 0x3fef +#define DW_AT_APPLE_origin 0x3ff0 #define DW_AT_hi_user 0x3fff @@ -1197,6 +1197,8 @@ most-likely-useful name. */ #define DW_LANG_CPP_for_OpenCL 0x0038 /* DWARF6 */ #define DW_LANG_SYCL 0x0039 /* DWARF6 */ #define DW_LANG_Ruby 0x0040 /* DWARF6 */ +#define DW_LANG_Move 0x0041 /* DWARF6 */ +#define DW_LANG_Hylo 0x0042 /* DWARF6 */ #define DW_LANG_lo_user 0x8000 #define DW_LANG_Mips_Assembler 0x8001 /* MIPS */ @@ -1223,9 +1225,9 @@ most-likely-useful name. */ #define DW_CC_nocall 0x03 #define DW_CC_pass_by_reference 0x04 /* DWARF5 */ #define DW_CC_pass_by_value 0x05 /* DWARF5 */ -#define DW_CC_lo_user 0x40 #define DW_CC_GNU_renesas_sh 0x40 /* GNU */ +#define DW_CC_lo_user 0x40 #define DW_CC_GNU_borland_fastcall_i386 0x41 /* GNU */ /* ALTIUM extensions. */ @@ -1404,8 +1406,8 @@ most-likely-useful name. */ #define DW_CFA_val_offset 0x14 /* DWARF3f */ #define DW_CFA_val_offset_sf 0x15 /* DWARF3f */ #define DW_CFA_val_expression 0x16 /* DWARF3f */ -#define DW_CFA_lo_user 0x1c #define DW_CFA_TI_soffset_extended 0x1c /* TI */ +#define DW_CFA_lo_user 0x1c #define DW_CFA_low_user 0x1c /* Incorrect spelling, do not use. */ /* SGI/MIPS extension. */ diff --git a/src/lib/libdwarf/dwarf_debugaddr.c b/src/lib/libdwarf/dwarf_debugaddr.c index 3411e89..8433cf4 100644 --- a/src/lib/libdwarf/dwarf_debugaddr.c +++ b/src/lib/libdwarf/dwarf_debugaddr.c @@ -132,95 +132,135 @@ dwarf_debug_addr_table(Dwarf_Debug dbg, if (dw_section_offset >= section_size) { return DW_DLV_NO_ENTRY; } - curlocaloffset = 0; - data = section_start + dw_section_offset; - READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, - data,offset_size,exten_size, - error, - section_size,end_data); - if (arealen > section_size || - (arealen + offset_size +exten_size) > section_size) { - dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append_printf_u(&m, - "DW_DLE_SECTION_SIZE_ERROR: A .debug_addr " - "area size of 0x%x ",arealen); - dwarfstring_append_printf_u(&m, - "at offset 0x%x ",dw_section_offset); - dwarfstring_append_printf_u(&m, - "is larger than the entire section size of " - "0x%x. Corrupt DWARF.",section_size); - _dwarf_error_string(dbg,error, - DW_DLE_SECTION_SIZE_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; - } - tab.da_dbg = dbg; - tablelen = arealen - 4; /* 4: the rest of the header */ - tab.da_length = tablelen; - curlocaloffset = offset_size + exten_size; - offset_one_past_end = dw_section_offset - + curlocaloffset + 4 /*rest of header */ - + tablelen; - end_data = section_start + offset_one_past_end; - tab.da_end_table = end_data; - READ_UNALIGNED_CK(dbg,version,Dwarf_Half,data, - SIZEOFT16,error,end_data); - if (version != DW_CU_VERSION5) { - dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append_printf_u(&m, - "DW_DLE_VERSION_STAMP_ERROR: " - "The .debug_addr version should be 5 " - "but we find %u instead.",version); - _dwarf_error_string(dbg,error, - DW_DLE_VERSION_STAMP_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; - } - tab.da_version = version; - data += SIZEOFT16; - curlocaloffset += SIZEOFT16; - READ_UNALIGNED_CK(dbg,address_size,Dwarf_Small,data, - 1,error,end_data); - if (address_size != 4 && address_size != 8 && - address_size != 2) { - dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append_printf_u(&m, - " DW_DLE_ADDRESS_SIZE_ERROR: The " - " .debug_addr address size " - "of %u is not supported.",address_size); - _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; - } - tab.da_address_size = address_size; - data++; - curlocaloffset++; + if (dbg->de_debug_addr_version == DW_CU_VERSION4) { + /* Create a table from what we know. */ + address_size = (Dwarf_Small)dbg->de_debug_addr_address_size; + offset_size = dbg->de_debug_addr_offset_size; + tab.da_address_size = address_size; + tab.da_length_size = offset_size; + tab.da_length = section_size; + tab.da_version = dbg->de_debug_addr_version; + end_data = section_start + section_size; + tab.da_end_table = end_data; + /* Must be zero. */ + if (dw_section_offset) { + _dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR, + "DW_DLE_DEBUG_ADDR_ERROR: DWARF4 extension " + ".debug_addr has non-zero offset. Impossible"); + return DW_DLV_ERROR; + } + tab.da_table_section_offset = dw_section_offset; + tab.da_data_entries = section_start; + tab.da_entry_count= section_size/tab.da_address_size; + /* One past end of this Debug Addr Table */ + tab.da_end_table = end_data; + if (tab.da_address_size != 4 && tab.da_address_size != 8 && + tab.da_address_size != 2) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + " DW_DLE_ADDRESS_SIZE_ERROR: The " + " .debug_addr DWARF4 address size " + "of %u is not supported.",address_size); + _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + offset_one_past_end = section_size; + tab.da_dbg = dbg; + } else { + /* all other cases, assume DWARF5 table. */ + curlocaloffset = 0; + data = section_start + dw_section_offset; + READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, + data,offset_size,exten_size, + error, + section_size,end_data); + if (arealen > section_size || + (arealen + offset_size +exten_size) > section_size) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + "DW_DLE_SECTION_SIZE_ERROR: A .debug_addr " + "area size of 0x%x ",arealen); + dwarfstring_append_printf_u(&m, + "at offset 0x%x ",dw_section_offset); + dwarfstring_append_printf_u(&m, + "is larger than the entire section size of " + "0x%x. Corrupt DWARF.",section_size); + _dwarf_error_string(dbg,error, + DW_DLE_SECTION_SIZE_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + tab.da_dbg = dbg; + tablelen = arealen - 4; /* 4: the rest of the header */ + tab.da_length = tablelen; + curlocaloffset = offset_size + exten_size; + offset_one_past_end = dw_section_offset + + curlocaloffset + 4 /*rest of header */ + + tablelen; + end_data = section_start + offset_one_past_end; + tab.da_end_table = end_data; + READ_UNALIGNED_CK(dbg,version,Dwarf_Half,data, + SIZEOFT16,error,end_data); + if (version != DW_CU_VERSION5) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + "DW_DLE_VERSION_STAMP_ERROR: " + "The .debug_addr version should be 5 " + "but we find %u instead.",version); + _dwarf_error_string(dbg,error, + DW_DLE_VERSION_STAMP_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + tab.da_version = version; + data += SIZEOFT16; + curlocaloffset += SIZEOFT16; + READ_UNALIGNED_CK(dbg,address_size,Dwarf_Small,data, + 1,error,end_data); + if (address_size != 4 && address_size != 8 && + address_size != 2) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + " DW_DLE_ADDRESS_SIZE_ERROR: The " + " .debug_addr address size " + "of %u is not supported.",address_size); + _dwarf_error_string(dbg,error,DW_DLE_ADDRESS_SIZE_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + tab.da_address_size = address_size; + data++; + curlocaloffset++; - READ_UNALIGNED_CK(dbg,segment_selector_size,Dwarf_Small,data, - 1,error,end_data); - if (segment_selector_size != 0) { - dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append(&m, - " DW_DLE_DEBUG_ADDR_ERROR: The " - " .debug_addr segment selector size " - "of non-zero is not supported."); - _dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; + READ_UNALIGNED_CK(dbg,segment_selector_size,Dwarf_Small,data, + 1,error,end_data); + if (segment_selector_size != 0) { + dwarfstring m; + dwarfstring_constructor(&m); + dwarfstring_append(&m, + " DW_DLE_DEBUG_ADDR_ERROR: The " + " .debug_addr segment selector size " + "of non-zero is not supported."); + _dwarf_error_string(dbg,error,DW_DLE_DEBUG_ADDR_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + /* We do not record segment selector size, + as it is not supported. */ + curlocaloffset++; + data++; + tab.da_data_entries = data; } - /* We do not record segment selector size, - as it is not supported. */ - curlocaloffset++; - data++; - tab.da_data_entries = data; /* Now we are at the beginning of the actual table */ { Dwarf_Unsigned entry_count = 0; diff --git a/src/lib/libdwarf/dwarf_debugaddr.h b/src/lib/libdwarf/dwarf_debugaddr.h index 3ade4b8..7b01283 100644 --- a/src/lib/libdwarf/dwarf_debugaddr.h +++ b/src/lib/libdwarf/dwarf_debugaddr.h @@ -37,6 +37,16 @@ extern "C" { #define DW_ADDR_TABLE_MAGIC 0xfade +/* In DWARF5 each portion of .debug_addr has a header. + + In a DWARF4 extension gcc emits .debug_addr + but without those headers, just with the + array of data entries, so dwarf_debugaddr.c + creates a table from data in Dwarf_Debug_S + assuming every CU has the + same address_size and version as in the initial + .debug_info CU. */ + struct Dwarf_Debug_Addr_Table_s { Dwarf_Unsigned da_magic; Dwarf_Debug da_dbg; diff --git a/src/lib/libdwarf/dwarf_die_deliv.c b/src/lib/libdwarf/dwarf_die_deliv.c index 0cf6ff2..9755b4f 100644 --- a/src/lib/libdwarf/dwarf_die_deliv.c +++ b/src/lib/libdwarf/dwarf_die_deliv.c @@ -59,6 +59,96 @@ #define MINIMUM_ADDRESS_SIZE 2 #define MAXIMUM_ADDRESS_SIZE 8 +#if 0 +#include "dwarf_rnglists.h" /* for debugging declaration */ +static void +dumprnglists_context(Dwarf_Rnglists_Context *rnglists, + Dwarf_Unsigned count) +{ + Dwarf_Rnglists_Context prc = 0; + Dwarf_Unsigned i = 0; + printf("Rnglists_Context count: 0x%lu\n",(unsigned long)count); + + for ( ; i < count; ++i) { + prc = rnglists[i]; + printf("[%3lu] Rnglists_Context rc_index : %lu\n", + (unsigned long)i, + (unsigned long)prc->rc_index); + printf(" hed offset : %lu\n", + (unsigned long)prc->rc_header_offset); + printf(" rc_length : %lu\n", + (unsigned long)prc->rc_length); + printf(" Version: %u offset size: " + "%u address_size: %u \n", + prc->rc_version,prc->rc_offset_size, + prc->rc_address_size); + printf(" offset_entry count : %lu\n", + (unsigned long)prc->rc_offset_entry_count); + printf(" offsets offset_ : %lu\n", + (unsigned long)prc->rc_offsets_off_in_sect); + } +} +static void +dumpcu_context_list( Dwarf_CU_Context first) +{ + Dwarf_CU_Context ctx = 0; + unsigned cc = 0; + + for ( ctx = first; ctx ; ctx = ctx->cc_next, ++cc) { + printf("[%3u] CU_Context rnglists_base " + " : 0x%lx\n",cc, + (unsigned long)ctx->cc_rnglists_base); + printf(" rnglists_base_contr_size: 0x%lx\n", + (unsigned long)ctx->cc_rnglists_base_contr_size); + printf(" rnglists_base_present : 0x%lx\n", + (unsigned long)ctx->cc_rnglists_base_present); + printf(" rnglists_header_length_present: %lu\n", + (unsigned long)ctx->cc_rnglists_header_length_present); + printf(" ranges_base : 0x%lx\n", + (unsigned long)ctx->cc_ranges_base); + printf(" ranges_base present : 0x%lx\n", + (unsigned long)ctx->cc_ranges_base_present); + } +} +static void +dump_rnglists_data(const char *msg, + Dwarf_Debug dbg,Dwarf_CU_Context cucon) +{ + printf("Debugging dump_rnglists_data %s\n",msg); + if (!dbg->de_debug_rnglists.dss_data) { + printf("No de_rnglists section\n"); + } + if (!dbg->de_rnglists_context_count) { + printf("No de_rnglists contexts\n"); + } else { + dumprnglists_context(dbg->de_rnglists_context, + dbg->de_rnglists_context_count); + } + if (dbg->de_info_reading.de_cu_context_list) { + if (cucon) { + dumpcu_context_list(cucon); + } else { + dumpcu_context_list( + dbg->de_info_reading.de_cu_context_list); + } + } else { + printf("No debug_info cu contexts\n"); + } + if (dbg->de_types_reading.de_cu_context_list) { + if (cucon) { + dumpcu_context_list(cucon); + } else { + dumpcu_context_list( + dbg->de_types_reading.de_cu_context_list); + } + } else { + printf("No debug_types cu contexts\n"); + } + fflush(stdout); + +} +#endif + static void assign_correct_unit_type(Dwarf_CU_Context cu_context); static int find_cu_die_base_fields(Dwarf_Debug dbg, Dwarf_CU_Context cucon, @@ -1062,6 +1152,12 @@ dwarf_next_cu_header_e(Dwarf_Debug dbg, next_cu_offset, header_cu_type, error); + if (! dbg->de_debug_addr_version) { + /* To enable printing raw GNU extension .debug_addr */ + dbg->de_debug_addr_version = (Dwarf_Half)*version_stamp; + dbg->de_debug_addr_offset_size = (Dwarf_Half)*offset_size; + dbg->de_debug_addr_address_size = (Dwarf_Half)*address_size; + } return res; } @@ -1504,7 +1600,7 @@ find_cu_die_base_fields(Dwarf_Debug dbg, /* Pretending that DW_AT_entry_pc with no DW_AT_low_pc is a valid base address for - loccation lists. + location lists. DW_AT_producer 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00) uses DW_AT_entry_pc as the base address (DW_AT_entry_pc first appears in DWARF3). @@ -1971,7 +2067,7 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, } if (tres == DW_DLV_ERROR && error) { /* We'll assume any errors will be - discovered later. Lets get our CU_context + discovered later. Lets get our finished. if error NULL it's a caller issue and there is nothing we can do here */ diff --git a/src/lib/libdwarf/dwarf_elf_load_headers.c b/src/lib/libdwarf/dwarf_elf_load_headers.c index 98fe63a..4c3872d 100644 --- a/src/lib/libdwarf/dwarf_elf_load_headers.c +++ b/src/lib/libdwarf/dwarf_elf_load_headers.c @@ -1968,7 +1968,9 @@ read_gs_section_group( free(data); return res; } - groupmallocsize = count * sizeof(Dwarf_Unsigned); + /* Adding 1 is silly but possibly avoids a warning + from a particular compiler. */ + groupmallocsize = (1+count) * sizeof(Dwarf_Unsigned); if (groupmallocsize >= ep->f_filesize) { free(data); *errcode = DW_DLE_ELF_SECTION_GROUP_ERROR; diff --git a/src/lib/libdwarf/dwarf_errmsg_list.h b/src/lib/libdwarf/dwarf_errmsg_list.h index 4a7a8a6..71a5ce6 100644 --- a/src/lib/libdwarf/dwarf_errmsg_list.h +++ b/src/lib/libdwarf/dwarf_errmsg_list.h @@ -686,6 +686,9 @@ static const char _dwarf_errmsgs[DW_DLE_LAST+1][DW_MAX_MSG_LEN] = { {"DW_DLE_UNIVERSAL_BINARY_ERROR(502) Error reading Mach-O " "uninversal binary head. Corrupt Mach-O object." }, {"DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR(503) Offset/size from " - "a Mach-O universal binary has an impossible value"} + "a Mach-O universal binary has an impossible value"}, +{"DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL(504) Section size fails " + "a heuristic sanity check"} + }; #endif /* DWARF_ERRMSG_LIST_H */ diff --git a/src/lib/libdwarf/dwarf_fission_to_cu.c b/src/lib/libdwarf/dwarf_fission_to_cu.c index 9404ad2..3aaacc1 100644 --- a/src/lib/libdwarf/dwarf_fission_to_cu.c +++ b/src/lib/libdwarf/dwarf_fission_to_cu.c @@ -28,6 +28,7 @@ #include #include /* memset() */ +#include /* free() */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" @@ -44,6 +45,7 @@ #include "dwarf_string.h" #include "dwarf_str_offsets.h" #include "dwarf_loc.h" +#include "dwarf_loclists.h" #include "dwarf_rnglists.h" /* ASSERT: dbg,cu_context, and fsd are non-NULL @@ -81,7 +83,6 @@ load_xu_loclists_into_cucontext(Dwarf_Debug dbg, /* Something is badly wrong. Ignore it here. */ return DW_DLV_NO_ENTRY; } - memset(buildhere,0,sizeof(localcontxt)); res = _dwarf_internal_read_loclists_header(dbg, 0,soff_size, dbg->de_debug_loclists.dss_data, @@ -90,18 +91,22 @@ load_xu_loclists_into_cucontext(Dwarf_Debug dbg, buildhere, &nextset,error); if (res != DW_DLV_OK) { + free(buildhere->lc_offset_value_array); + buildhere->lc_offset_value_array = 0; return res; } cu_context->cc_loclists_base_present = TRUE; cu_context->cc_loclists_base_contr_size = size; cu_context->cc_loclists_base = buildhere->lc_offsets_off_in_sect; + free(buildhere->lc_offset_value_array); + buildhere->lc_offset_value_array = 0; return DW_DLV_OK; } /* - ASSERT: dbg,cu_context, and fsd are non-NULL + ASSERT: dbg,cu_context, and fsd are non-NULL as the caller ensured that. If .debug_cu_index or .debug_tu_index is present it might help us find @@ -284,6 +289,8 @@ static const char *keylist[2] = { Then, _dwarf_make_CU_Context() calls _dwarf_merge_all_base_attrs_of_cu_die() if there is a tied (executable) object known. + (not all base attrs are merged from tied. Certainly not + .debug_rnglists or .debug_loclists. Called by dwarf_die_deliv.c */ diff --git a/src/lib/libdwarf/dwarf_form.c b/src/lib/libdwarf/dwarf_form.c index ff25fd6..2d2812e 100644 --- a/src/lib/libdwarf/dwarf_form.c +++ b/src/lib/libdwarf/dwarf_form.c @@ -508,7 +508,6 @@ dwarf_formref(Dwarf_Attribute attr, case DW_FORM_ref_udata: { Dwarf_Byte_Ptr ptr = attr->ar_debug_ptr; Dwarf_Unsigned localoffset = 0; - DECODE_LEB128_UWORD_CK(ptr,localoffset, dbg,error,section_end); offset = localoffset; @@ -893,10 +892,10 @@ _dwarf_internal_global_formref_b(Dwarf_Attribute attr, Return the index itself. */ case DW_FORM_loclistx: case DW_FORM_rnglistx: { - unsigned length_size = cu_context->cc_length_size; - READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned, - attr->ar_debug_ptr, length_size, - error,section_end); + Dwarf_Unsigned val = 0; + DECODE_LEB128_UWORD_CK(attr->ar_debug_ptr, + val, dbg,error,section_end); + offset = val; } break; case DW_FORM_sec_offset: @@ -1330,7 +1329,7 @@ dwarf_formaddr(Dwarf_Attribute attr, the reference form. It is address-sized so that the linker can easily update it, but it is a reference inside the debug_info section. No longer - allowed. */ + allowed except for Metrowerks C. */ ) { Dwarf_Small *section_end = _dwarf_calculate_info_section_end_ptr(cu_context); diff --git a/src/lib/libdwarf/dwarf_line_table_reader_common.h b/src/lib/libdwarf/dwarf_line_table_reader_common.h index 67dc766..3cba430 100644 --- a/src/lib/libdwarf/dwarf_line_table_reader_common.h +++ b/src/lib/libdwarf/dwarf_line_table_reader_common.h @@ -28,7 +28,6 @@ Fifth Floor, Boston MA 02110-1301, USA. */ -#include /* This is #included twice. Once for libdwarf callers and one for dwarfdump which prints diff --git a/src/lib/libdwarf/dwarf_loc.c b/src/lib/libdwarf/dwarf_loc.c index bfe83c8..cdf3eef 100644 --- a/src/lib/libdwarf/dwarf_loc.c +++ b/src/lib/libdwarf/dwarf_loc.c @@ -31,6 +31,7 @@ #include #include /* memset() */ +#include /* for debugging printf */ #if defined(_WIN32) && defined(HAVE_STDAFX_H) #include "stdafx.h" @@ -69,7 +70,7 @@ _dwarf_locdesc_c_constructor(Dwarf_Debug dbg, void *locd) return DW_DLV_ERROR; } ldp->ld_lle_value = DW_LLE_VALUE_BOGUS; - ldp->ld_kind = DW_LKIND_unknown; + ldp->ld_lkind = DW_LKIND_unknown; return DW_DLV_OK; } @@ -492,7 +493,7 @@ _dwarf_loc_block_sanity_check(Dwarf_Debug dbg, return DW_DLV_OK; } -/* ld_kind was checked before calling this, so we +/* ld_lkind was checked before calling this, so we know its value is an intended value. */ static const char *kindset[] = { "DW_LKIND_expression", @@ -520,7 +521,7 @@ validate_lle_value(Dwarf_Debug dbg, { dwarfstring m; - if (locdesc->ld_kind != DW_LKIND_GNU_exp_list) { + if (locdesc->ld_lkind != DW_LKIND_GNU_exp_list) { switch(locdesc->ld_lle_value) { case DW_LLE_end_of_list: case DW_LLE_base_addressx: @@ -539,10 +540,10 @@ validate_lle_value(Dwarf_Debug dbg, dwarfstring_append_printf_s(&m, "DW_DLE_LOCATION_ERROR: For location kind %s (", (char *)get_loc_kind_str( - (Dwarf_Small)locdesc->ld_kind)); + (Dwarf_Small)locdesc->ld_lkind)); dwarfstring_append_printf_u(&m,"%u) the DW_LLE value is " "not properly set", - locdesc->ld_kind); + locdesc->ld_lkind); dwarfstring_append_printf_u(&m," but is %u " " which is a libdwarf bug", locdesc->ld_lle_value); @@ -565,10 +566,10 @@ validate_lle_value(Dwarf_Debug dbg, dwarfstring_append_printf_s(&m, "DW_DLE_LOCATION_ERROR: For location kind %s (", (char *)get_loc_kind_str( - (Dwarf_Small)locdesc->ld_kind)); + (Dwarf_Small)locdesc->ld_lkind)); dwarfstring_append_printf_u(&m,"%u) the DW_LLEX value is " "not properly set", - locdesc->ld_kind); + locdesc->ld_lkind); dwarfstring_append_printf_u(&m," but is %u " " which is a libdwarf bug", locdesc->ld_lle_value); @@ -621,7 +622,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, Dwarf_Small *section_end = 0; const char *section_name = 0; Dwarf_Small *blockdataptr = 0; - unsigned lkind = loc_head->ll_kind; + unsigned lkind = loc_head->ll_lkind; /* ***** BEGIN CODE ***** */ blockdataptr = loc_block->bl_data; @@ -716,7 +717,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, } /* Synthesizing the DW_LLE values for the old loclist versions. */ - switch(loc_head->ll_kind) { + switch(loc_head->ll_lkind) { case DW_LKIND_loclist: { if (highpc == 0 && lowpc == 0) { locdesc->ld_lle_value = DW_LLE_end_of_list; @@ -746,7 +747,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, "DW_DLE_LOCATION_ERROR: An impossible DW_LKIND" " value of %u encountered, likely internal " "libdwarf error or data corruption", - (unsigned)loc_head->ll_kind); + (unsigned)loc_head->ll_lkind); _dwarf_error_string(dbg,error, DW_DLE_LOCATION_ERROR, dwarfstring_string(&m)); @@ -758,7 +759,7 @@ _dwarf_fill_in_locdesc_op_c(Dwarf_Debug dbg, locdesc->ld_cents = (Dwarf_Half)op_count; locdesc->ld_s = block_loc; - locdesc->ld_kind = lkind; + locdesc->ld_lkind = lkind; locdesc->ld_section_offset = loc_block->bl_section_offset; locdesc->ld_locdesc_offset = loc_block->bl_locdesc_offset; locdesc->ld_rawlow = lowpc; @@ -1021,7 +1022,7 @@ dwarf_get_loclist_head_kind(Dwarf_Loc_Head_c ll_header, "dwarf_get_loclist_head_kind()"); return DW_DLV_ERROR; } - *kind = ll_header->ll_kind; + *kind = ll_header->ll_lkind; return DW_DLV_OK; } @@ -1037,7 +1038,7 @@ _dwarf_original_loclist_build(Dwarf_Debug dbg, int count_res = DW_DLV_ERROR; int loclist_count = 0; Dwarf_Unsigned lli = 0; - unsigned lkind = llhead->ll_kind; + unsigned lkind = llhead->ll_lkind; unsigned address_size = llhead->ll_address_size; Dwarf_Unsigned listlen = 0; Dwarf_Locdesc_c llbuf = 0; @@ -1168,7 +1169,7 @@ _dwarf_original_expression_build(Dwarf_Debug dbg, if (blkres != DW_DLV_OK) { return blkres; } - loc_blockc.bl_kind = llhead->ll_kind; + loc_blockc.bl_kind = llhead->ll_lkind; loc_blockc.bl_section_offset = (char *)loc_blockc.bl_data - (char *)dbg->de_debug_info.dss_data; @@ -1186,7 +1187,7 @@ _dwarf_original_expression_build(Dwarf_Debug dbg, } loc_blockc.bl_len = loc_block.bl_len; loc_blockc.bl_data = loc_block.bl_data; - loc_blockc.bl_kind = llhead->ll_kind; + loc_blockc.bl_kind = llhead->ll_lkind; loc_blockc.bl_section_offset = loc_block.bl_section_offset; loc_blockc.bl_locdesc_offset = 0; /* not relevant */ @@ -1657,7 +1658,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, return DW_DLV_ERROR; } llhead->ll_cuversion = cuversionstamp; - llhead->ll_kind = lkind; + llhead->ll_lkind = lkind; llhead->ll_attrnum = (Dwarf_Half)attrnum; llhead->ll_attrform = (Dwarf_Half)form; llhead->ll_dbg = dbg; @@ -1779,7 +1780,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg, llhead->ll_locdesc_count = local_listlen; llhead->ll_context = 0; /* Not available! */ llhead->ll_dbg = dbg; - llhead->ll_kind = DW_LKIND_expression; + llhead->ll_lkind = DW_LKIND_expression; /* An empty location description (block length 0) means the code generator emitted no variable, @@ -1823,6 +1824,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg, int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned index, + /* Dwarf_Unsigned lle_entry_index, */ Dwarf_Small * lle_value_out, Dwarf_Unsigned * rawval1, Dwarf_Unsigned * rawval2, @@ -1836,6 +1838,45 @@ dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head, Dwarf_Unsigned * expression_offset_out, Dwarf_Unsigned * locdesc_offset_out, Dwarf_Error * error) +{ + return dwarf_get_locdesc_entry_e( + loclist_head, index, + /*0 base local index,*/ + lle_value_out, + rawval1, + rawval2, + debug_addr_unavailable, + lowpc_out, /* 'cooked' value */ + hipc_out, /* 'cooked' value */ + loclist_expr_op_count_out, + 0 /* not returning lle_bytecount*/ , + /* Returns pointer to the specific locdesc of the index; */ + locdesc_entry_out, + loclist_source_out, /* 0,1, or 2 */ + expression_offset_out, + locdesc_offset_out, + error); +} +int +dwarf_get_locdesc_entry_e(Dwarf_Loc_Head_c loclist_head, + /* The context-local offset of an lle set as reverenced + by an offset_entry_table. */ + Dwarf_Unsigned index, + /*Dwarf_Unsigned base_local_index, */ + Dwarf_Small * lle_value_out, + Dwarf_Unsigned * rawval1, + Dwarf_Unsigned * rawval2, + Dwarf_Bool * debug_addr_unavailable, + Dwarf_Addr * lowpc_out, /* 'cooked' value */ + Dwarf_Addr * hipc_out, /* 'cooked' value */ + Dwarf_Unsigned * loclist_expr_op_count_out, + /* Returns pointer to the specific locdesc of the index; */ + Dwarf_Unsigned * lle_bytecount, + Dwarf_Locdesc_c* locdesc_entry_out, + Dwarf_Small * loclist_source_out, /* 0,1, or 2 */ + Dwarf_Unsigned * expression_offset_out, + Dwarf_Unsigned * locdesc_offset_out, + Dwarf_Error * error) { Dwarf_Locdesc_c descs_base = 0; Dwarf_Locdesc_c desc = 0; @@ -1867,9 +1908,12 @@ dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c loclist_head, *debug_addr_unavailable = desc->ld_index_failed; *loclist_expr_op_count_out = desc->ld_cents; *locdesc_entry_out = desc; - *loclist_source_out = (Dwarf_Small)desc->ld_kind; + *loclist_source_out = (Dwarf_Small)desc->ld_lkind; *expression_offset_out = desc->ld_section_offset; *locdesc_offset_out = desc->ld_locdesc_offset; + if (lle_bytecount) { + *lle_bytecount = desc->ld_lle_bytecount; + } return DW_DLV_OK; } diff --git a/src/lib/libdwarf/dwarf_loc.h b/src/lib/libdwarf/dwarf_loc.h index 9080d73..b167a51 100644 --- a/src/lib/libdwarf/dwarf_loc.h +++ b/src/lib/libdwarf/dwarf_loc.h @@ -44,60 +44,6 @@ struct Dwarf_Loc_Chain_s { Dwarf_Loc_Chain lc_next; }; -/* Dwarf_Loclists_Context_s contains the data from - the .debug_loclists - section headers (if that section exists). Dwarf 2,3,4 .debug_loc - has no such data. The array (one of these per header in - .debug_loclists) is recorded in Dwarf_Debug. These - are filled in at startup at the same time .debug_info - is opened. Nothing of this struct is exposed to - libdwarf callers */ -struct Dwarf_Loclists_Context_s { - Dwarf_Debug lc_dbg; - Dwarf_Unsigned lc_index; /* An index assigned by - libdwarf to each loclists context. Starting - with zero at the zero offset in .debug_loclists. */ - - /* Offset of the .debug_loclists header involved. */ - Dwarf_Unsigned lc_header_offset; - Dwarf_Unsigned lc_length; - unsigned long lc_magic; - - /* Many places in in libdwarf this is called length_size. */ - Dwarf_Small lc_offset_size; - - /* rc_extension_size is zero unless this is standard - DWARF3 and later 64bit dwarf using the extension mechanism. - 64bit DWARF3 and later: rc_extension_size is 4. - 64bit DWARF2 MIPS/IRIX: rc_extension_size is zero. - 32bit DWARF: rc_extension_size is zero. */ - Dwarf_Small lc_extension_size; - Dwarf_Small lc_address_size; - Dwarf_Small lc_segment_selector_size; - Dwarf_Half lc_version; /* 5 */ - Dwarf_Unsigned lc_offset_entry_count; - - /* offset in the section of the offset entries */ - Dwarf_Unsigned lc_offsets_off_in_sect; - - /* Do not free. Points into section memory */ - Dwarf_Small * lc_offsets_array; - - /* Offset in the .debug_loclists section of the - first loclist in the set of loclists for the - CU. */ - Dwarf_Unsigned lc_first_loclist_offset; - Dwarf_Unsigned lc_past_last_loclist_offset; - - /* pointer to 1st byte of loclist header*/ - Dwarf_Small * lc_loclists_header; - /* pointer to first byte of the loclist data - for loclist involved. Do not free. */ - Dwarf_Small *lc_startaddr; - /* pointer one past end of the loclist data. */ - Dwarf_Small *lc_endaddr; -}; - /* Contains info on an uninterpreted block of data, the data is DWARF location expression operators. */ struct Dwarf_Block_c_s { @@ -170,13 +116,15 @@ struct Dwarf_Loc_Expr_Op_s { Adds the DW_LLE value (new in DWARF5). This struct is opaque. Not visible to callers. */ struct Dwarf_Locdesc_c_s { - Dwarf_Half ld_kind; /* DW_LKIND */ + Dwarf_Half ld_lkind; /* DW_LKIND */ /* A DW_LLEX or DW_LLE value, real or synthesized */ Dwarf_Small ld_lle_value; /* Failed means .debug_addr section needed but missing. (possibly tied file needed) */ Dwarf_Bool ld_index_failed; + /* the length of data in this lle entry */ + Dwarf_Unsigned ld_lle_bytecount; unsigned long ld_magic; /* Beginning of active range. This is actually an offset @@ -239,14 +187,14 @@ struct Dwarf_Loc_Head_c_s { /* The CU Context of this loclist or locexpr. */ Dwarf_CU_Context ll_context; /* DW_LKIND* */ - Dwarf_Half ll_kind; + Dwarf_Half ll_lkind; /* DW_LKIND */ Dwarf_Debug ll_dbg; unsigned long ll_magic; - /* If ll_kind == DW_LKIND_loclists the following + /* If ll_lkind == DW_LKIND_loclists the following pointer is non-null and index is the index of the localcontext */ - Dwarf_Unsigned ll_index; + Dwarf_Unsigned ll_index; Dwarf_Loclists_Context ll_localcontext; /* rh_last and rh_first used during build-up. diff --git a/src/lib/libdwarf/dwarf_loclists.c b/src/lib/libdwarf/dwarf_loclists.c index 02af354..df37da5 100644 --- a/src/lib/libdwarf/dwarf_loclists.c +++ b/src/lib/libdwarf/dwarf_loclists.c @@ -50,6 +50,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "dwarf_util.h" #include "dwarf_string.h" #include "dwarf_loc.h" +#include "dwarf_loclists.h" #define SIZEOFT8 1 #define SIZEOFT16 2 @@ -61,18 +62,45 @@ static void dump_bytes(const char *msg,Dwarf_Small * start, long len) { Dwarf_Small *end = start + len; + Dwarf_Unsigned max=16; + Dwarf_Unsigned ct=0; + Dwarf_Unsigned full=0; Dwarf_Small *cur = start; - printf("%s (0x%lx) ",msg,(unsigned long)start); - for (; cur < end; cur++) { + + printf("%s (0x%lx)\n",msg,(unsigned long)start); + for (; cur < end; cur++, ++full) { + if (!ct) { + printf("[0x%04lx] ",(unsigned long)full); + } printf("%02x", *cur); + ++ct; + if ( ct % 4 == 0) { + printf(" "); + } + if ( ct % max == 0) { + printf("\n"); + ct = 0; + } } printf("\n"); } #endif /*0*/ +static void +free_loclists_context(Dwarf_Loclists_Context cx) +{ + if (cx) { + free(cx->lc_offset_value_array); + cx->lc_offset_value_array = 0; + cx->lc_magic = 0; + free(cx); + } +} + /* Used in case of error reading the loclists headers (not referring to Dwarf_Loc_Head_c - here), to clean up. */ + here), to clean up. The chain is of + Dwarf_Loclists_Context items */ static void free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head) { @@ -85,7 +113,9 @@ free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head) for ( ;cur; cur = next) { next = cur->ch_next; if (cur->ch_item) { - free(cur->ch_item); + Dwarf_Loclists_Context cx = + (Dwarf_Loclists_Context)cur->ch_item; + free_loclists_context(cx); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); } @@ -349,6 +379,7 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, Dwarf_Unsigned offset_entry_count = 0; Dwarf_Unsigned localoff = 0; Dwarf_Unsigned lists_len = 0; + Dwarf_Unsigned tabentrynum = 0; READ_AREA_LENGTH_CK(dbg,arealen,Dwarf_Unsigned, data,offset_size,exten_size, @@ -414,19 +445,55 @@ _dwarf_internal_read_loclists_header(Dwarf_Debug dbg, READ_UNALIGNED_CK(dbg,segment_selector_size,unsigned,data, SIZEOFT8,error,end_data); buildhere->lc_segment_selector_size = segment_selector_size; + if (buildhere->lc_segment_selector_size) { + _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR, + "DW_DLE_LOCLISTS_ERROR: " + " The debug_loclists segment selector size is non-zero. " + "Not supported."); + return DW_DLV_ERROR; + } data++; READ_UNALIGNED_CK(dbg,offset_entry_count,Dwarf_Unsigned,data, SIZEOFT32,error,end_data); buildhere->lc_offset_entry_count = offset_entry_count; data += SIZEOFT32; - if (offset_entry_count ){ - buildhere->lc_offsets_array = data; + if (offset_entry_count >= (sectionlength/offset_size)) { + _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR, + "dbg,DW_DLE_LOCLISTS_ERROR: " + " The debug_loclists offset table entry " + "count exceeds the " + "section length, Corrupt dwarf"); + return DW_DLV_ERROR; } localoff = data - startdata; - lists_len = offset_size *offset_entry_count; + if (offset_entry_count) { + buildhere->lc_offsets_array = data; + buildhere->lc_offset_value_array = (Dwarf_Unsigned *) + calloc(offset_entry_count, sizeof(Dwarf_Unsigned)); + if (!buildhere->lc_offset_value_array) { + _dwarf_error_string(dbg,error, DW_DLE_ALLOC_FAIL, + "dbg,DW_DLE_ALLOC_CAIL: " + " The debug_loclists offset table " + "cannot be allocated."); + return DW_DLV_ERROR; + } + for (tabentrynum = 0 ; tabentrynum < offset_entry_count; + data += SIZEOFT32,++tabentrynum ) { + Dwarf_Unsigned entry = 0; + int res = 0; - data += lists_len; + res = _dwarf_read_unaligned_ck_wrapper(dbg, + &entry,data,SIZEOFT32,end_data,error); + if (res != DW_DLV_OK) { + free(buildhere->lc_offset_value_array); + buildhere->lc_offset_value_array = 0; + return res; + } + buildhere->lc_offset_value_array[tabentrynum] = entry; + lists_len += SIZEOFT32; + } + } /* else no offset table */ buildhere->lc_offsets_off_in_sect = offset+localoff; buildhere->lc_first_loclist_offset = offset+localoff+ @@ -483,8 +550,9 @@ internal_load_loclists_contexts(Dwarf_Debug dbg, data,end_data,offset, newcontext,&nextoffset,error); if (res == DW_DLV_ERROR) { - free(newcontext); free_loclists_chain(dbg,head_chain); + free_loclists_context(newcontext); + newcontext = 0; return DW_DLV_ERROR; } newcontext->lc_magic = LOCLISTS_MAGIC; @@ -495,7 +563,8 @@ internal_load_loclists_contexts(Dwarf_Debug dbg, "DW_DLE_ALLOC_FAIL: allocating Loclists_Context" " chain entry"); free_loclists_chain(dbg,head_chain); - free(newcontext); + free_loclists_context(newcontext); + newcontext = 0; return DW_DLV_ERROR; } curr_chain->ch_item = newcontext; @@ -567,6 +636,11 @@ dwarf_load_loclists(Dwarf_Debug dbg, return res; } } + /* cxt is set to a pointer to a context, which is + actually an array of pointers to such contexts, 'count' + of them. Each context has the loclists offset table + (if it has at least on entry in the table) + pointed in each cxt. */ res = internal_load_loclists_contexts(dbg,&cxt,&count,error); if (res == DW_DLV_ERROR) { return res; @@ -593,10 +667,7 @@ _dwarf_dealloc_loclists_context(Dwarf_Debug dbg) loccon = dbg->de_loclists_context; for ( ; i < dbg->de_loclists_context_count; ++i) { Dwarf_Loclists_Context con = loccon[i]; - con->lc_offsets_array = 0; - con->lc_offset_entry_count = 0; - con->lc_magic = 0; - free(con); + free_loclists_context(con); loccon[i] = 0; } free(dbg->de_loclists_context); @@ -620,7 +691,6 @@ dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg, CHECK_DBG(dbg,error,"dwarf_get_loclist_offset_index_value()"); if (!dbg->de_loclists_context_count) { - return DW_DLV_NO_ENTRY; } if (context_index >= dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; @@ -699,7 +769,7 @@ int dwarf_get_loclist_head_basics(Dwarf_Loc_Head_c head, "dwarf_get_loclist_head_basics()"); return DW_DLV_ERROR; } - *lkind = (Dwarf_Small)head->ll_kind; + *lkind = (Dwarf_Small)head->ll_lkind; *lle_count = head->ll_locdesc_count; *lle_version = head->ll_cuversion; *loclists_index_returned = head->ll_index; @@ -924,7 +994,6 @@ _dwarf_which_loclists_context(Dwarf_Debug dbg, /* We have a DW_AT_loclists_base (lc_loclists_base), let's use it. */ Dwarf_Unsigned lookfor = 0;; - lookfor = ctx->cc_loclists_base; for ( i = 0 ; i < count; ++i) { dwarfstring m; @@ -1003,6 +1072,33 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg, return DW_DLV_OK; } +static int +_dwarf_implicit_loclists_base(Dwarf_Debug dbg, + Dwarf_Unsigned indexval, + Dwarf_Unsigned *ibase) +{ + Dwarf_Loclists_Context rctx = 0; + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } + if (!dbg->de_debug_loclists.dss_size) { + return DW_DLV_NO_ENTRY; + } + if (!dbg->de_loclists_context_count) { + return DW_DLV_NO_ENTRY; + } + /* This implicit base can only work if the 0-th + Rnglists_Context is appropriate here. */ + rctx = dbg->de_loclists_context[0]; + if (indexval > rctx->lc_offset_entry_count) { + /* We are not using base offset, we + will not see a DW_FORM_loclistx */ + return DW_DLV_NO_ENTRY; + } + *ibase = rctx->lc_offsets_off_in_sect; + return DW_DLV_OK; +} + /* Read the group of loclists entries, and finally build an array of Dwarf_Locdesc_c records. Attach to rctx here. @@ -1052,19 +1148,21 @@ build_array_of_lle(Dwarf_Debug dbg, } eops.bl_len =opsblocksize; eops.bl_data = ops; - eops.bl_kind = rctx->ll_kind; + eops.bl_kind = rctx->ll_lkind; eops.bl_section_offset = opsoffset; eops.bl_locdesc_offset = dataoffset; - e->ld_kind = rctx->ll_kind; + e->ld_lkind = rctx->ll_lkind; e->ld_magic = LOCLISTS_MAGIC; e->ld_lle_value = code, e->ld_entrylen = entrylen; e->ld_rawlow = val1; e->ld_rawhigh = val2; e->ld_opsblock = eops; - bytescounttotal += entrylen; + e->ld_lle_bytecount = entrylen; data += entrylen; + bytescounttotal += entrylen; if (code == DW_LLE_end_of_list) { + /* This terminates the entries for a loclist portion.*/ done = TRUE; break; } @@ -1135,61 +1233,84 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, Dwarf_Loclists_Context *array = 0; Dwarf_Loclists_Context rctx = 0; Dwarf_Unsigned entrycount = 0; - unsigned offsetsize = 0; - Dwarf_Unsigned lle_global_offset = 0; + unsigned offsetsize = 0; + Dwarf_Unsigned lle_global_offset = 0; Dwarf_CU_Context ctx = 0; - Dwarf_Unsigned offset_in_loclists = 0; - Dwarf_Bool is_loclistx = FALSE; - int theform = llhead->ll_attrform; - Dwarf_Unsigned attr_val = 0; + Dwarf_Unsigned offset_in_loclists = 0; + Dwarf_Bool is_loclistx = FALSE; + Dwarf_Half theform = llhead->ll_attrform; + Dwarf_Bool loclists_base_present = + llhead->ll_at_loclists_base_present; + Dwarf_Unsigned loclists_base = + llhead->ll_at_loclists_base; + Dwarf_Unsigned attr_val = 0; + if (!attr) { + _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, + "DW_DLE_DBG_NULL " + "NULL attribute " + "argument passed to " + "_dwarf_loclists_fill_in_lle_head()"); + return DW_DLV_ERROR; + } ctx = attr->ar_cu_context; array = dbg->de_loclists_context; - if ( theform == DW_FORM_sec_offset) { - /* DW_FORM_sec_offset is not formudata , often - seen in in DW5 DW_AT_location etc */ - res = dwarf_global_formref(attr, &attr_val,error); + if (theform == DW_FORM_loclistx) { + Dwarf_Bool offset_is_info = 0; + is_loclistx = TRUE; + res = dwarf_global_formref_b(attr, + &attr_val, &offset_is_info, error); if (res != DW_DLV_OK) { return res; } - offset_in_loclists = attr_val; } else { - if (theform == DW_FORM_loclistx) { - is_loclistx = TRUE; + if (theform == DW_FORM_sec_offset) { + /* DW_FORM_sec_offset is not formudata , often + seen in in DW5 DW_AT_location etc */ + res = dwarf_global_formref(attr, &attr_val,error); + if (res != DW_DLV_OK) { + return res; + } } - res = dwarf_formudata(attr,&attr_val,error); - if (res != DW_DLV_OK) { - return res; - } - /* the context cc_loclists_base gives the offset - of the array. of offsets (if cc_loclists_base_present) */ - offset_in_loclists = attr_val; - if (is_loclistx) { - if (ctx->cc_loclists_base_present) { - offset_in_loclists = ctx->cc_loclists_base; - } else if (dbg->de_loclists_context_count == 1) { - /* missing a DW_AT_loclists_base! */ - offset_in_loclists = 0; - } else { - /* FIXME: check in tied file for a cc_loclists_base - possibly? Make any sense? */ + } + if (is_loclistx) { + if (loclists_base_present) { + offset_in_loclists = loclists_base; + } else if (ctx->cc_is_dwo) { + /* missing a DW_AT_loclists_base! */ + /* Generate a base and set as 'present' + by looking at the location offset + table that we are supposedly indexing into. + finding what the table value is. + An implicit loclists_base. + Will not work with multiple loclists! */ + int ires = 0; + Dwarf_Unsigned ibase = 0; + ires = _dwarf_implicit_loclists_base(dbg, + attr_val,&ibase); + if (ires != DW_DLV_OK) { dwarfstring m; dwarfstring_constructor(&m); dwarfstring_append_printf_u(&m, - "DW_DLE_LOCLISTS_ERROR: loclists table index of" + "DW_DLE_LOCLISTS_ERROR: loclists table" + " index of" " %u" ,attr_val); dwarfstring_append(&m, - " is unusable without a tied file." - ); - _dwarf_error_string(dbg,error,DW_DLE_LOCLISTS_ERROR, + " is unusable, there is no default " + " loclists base address "); + _dwarf_error_string(dbg,error, + DW_DLE_LOCLISTS_ERROR, dwarfstring_string(&m)); dwarfstring_destructor(&m); return DW_DLV_ERROR; } - } else { - offset_in_loclists = attr_val; + ctx->cc_loclists_base_present = TRUE; + ctx->cc_loclists_base = ibase; + offset_in_loclists = ibase; } + } else { + offset_in_loclists = attr_val; } res = _dwarf_which_loclists_context(dbg,ctx, offset_in_loclists, @@ -1203,21 +1324,23 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, offsetsize = rctx->lc_offset_size; enddata = rctx->lc_endaddr; - if (is_loclistx && attr_val >= entrycount) { - dwarfstring m; + if (is_loclistx) { + if (attr_val >= entrycount) { + dwarfstring m; - dwarfstring_constructor(&m); - dwarfstring_append_printf_u(&m, - "DW_DLE_LOCLISTS_ERROR: loclists table index of" - " %u" ,attr_val); - dwarfstring_append_printf_u(&m, - " too large for table of %u " - "entries.",entrycount); - _dwarf_error_string(dbg,error, - DW_DLE_LOCLISTS_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + "DW_DLE_LOCLISTS_ERROR: loclists table index of" + " %u" ,attr_val); + dwarfstring_append_printf_u(&m, + " too large for table of %u " + "entries.",entrycount); + _dwarf_error_string(dbg,error, + DW_DLE_LOCLISTS_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } } llhead->ll_localcontext = rctx; llhead->ll_index = loclists_contextnum; @@ -1253,7 +1376,7 @@ _dwarf_loclists_fill_in_lle_head(Dwarf_Debug dbg, return DW_DLV_OK; } -#if 0 /* candiate??? for public api */ +#if 0 /* candiate??? for public api. No, not usable. */ int dwarf_get_loclists_entry_fields( Dwarf_Loc_Head_c head, @@ -1264,6 +1387,7 @@ dwarf_get_loclists_entry_fields( Dwarf_Unsigned *raw2, Dwarf_Unsigned *cooked1, Dwarf_Unsigned *cooked2, + Dwarf_Unsigned *lle_bytesize; /* FIXME not right for loclists or their loc exprs */ Dwarf_Error *error) { @@ -1284,6 +1408,7 @@ dwarf_get_loclists_entry_fields( e = head->ll_locdesc + entrynum; *entrylen = e->ld_entrylen; *code = e->ld_lle_value; + *lle_bytesize = e->ld_lle_value /* bogus */; *raw1 = e->ld_rawlow; *raw2 = e->ld_rawhigh; *cooked1 = e->ld_lopc; diff --git a/src/lib/libdwarf/dwarf_loclists.h b/src/lib/libdwarf/dwarf_loclists.h new file mode 100644 index 0000000..96f60d3 --- /dev/null +++ b/src/lib/libdwarf/dwarf_loclists.h @@ -0,0 +1,86 @@ +/* +Copyright (C) 2000, 2004 Silicon Graphics, Inc. All Rights Rese rved. +Portions Copyright (C) 2015-2023 David Anderson. All Rights Rese rved. + +This program is free software; you can redistribute it +and/or modify it under the terms of version 2.1 of the +GNU Lesser General Public License as published by the Free +Software Foundation. + +This program is distributed in the hope that it would be +useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. + +Further, this software is distributed without any warranty +that it is free of the rightful claim of any third person +regarding infringement or the like. Any license provided +herein, whether implied or otherwise, applies only to this +software file. Patent licenses, if any, provided herein +do not apply to combinations of this program with other +software, or any other product whatsoever. + +You should have received a copy of the GNU Lesser General +Public License along with this program; if not, write the +Free Software Foundation, Inc., 51 Franklin Street - Fifth +Floor, Boston MA 02110-1301, USA. +*/ + +/* Dwarf_Loclists_Context_s contains the data from + the .debug_loclists + section headers (if that section exists). Dwarf 2,3,4 .debug_loc + has no such data. The array (one of these per header in + .debug_loclists) is recorded in Dwarf_Debug. These + are filled in at startup at the same time .debug_info + is opened. Nothing of this struct is exposed to + libdwarf callers */ +struct Dwarf_Loclists_Context_s { + Dwarf_Debug lc_dbg; + Dwarf_Unsigned lc_index; /* An index assigned by + libdwarf to each loclists context. Starting + with zero at the zero offset in .debug_loclists. */ + + /* Offset of the .debug_loclists header involved. */ + Dwarf_Unsigned lc_header_offset; + Dwarf_Unsigned lc_length; + unsigned long lc_magic; + + /* Many places in in libdwarf this is called length_size. */ + Dwarf_Small lc_offset_size; + + /* rc_extension_size is zero unless this is standard + DWARF3 and later 64bit dwarf using the extension mechanism. + 64bit DWARF3 and later: rc_extension_size is 4. + 64bit DWARF2 MIPS/IRIX: rc_extension_size is zero. + 32bit DWARF: rc_extension_size is zero. */ + Dwarf_Small lc_extension_size; + Dwarf_Small lc_address_size; + Dwarf_Small lc_segment_selector_size; + Dwarf_Half lc_version; /* 5 */ + Dwarf_Unsigned lc_offset_entry_count; + /* lc_offset_entry_count values. Each local offset to + a locdesc set. We need this as a way to know + which lle entry offsets are relevant from a loclistx. + as nothing else reveals these special LLE entries. */ + Dwarf_Unsigned *lc_offset_value_array; + + /* offset in the section of the offset entries */ + Dwarf_Unsigned lc_offsets_off_in_sect; + + /* Do not free. Points into section memory */ + Dwarf_Small * lc_offsets_array; + + /* Offset in the .debug_loclists section of the + first loclist in the set of loclists for the + CU. */ + Dwarf_Unsigned lc_first_loclist_offset; + Dwarf_Unsigned lc_past_last_loclist_offset; + + /* pointer to 1st byte of loclist header*/ + Dwarf_Small * lc_loclists_header; + /* pointer to first byte of the loclist data + for loclist involved. Do not free. */ + Dwarf_Small *lc_startaddr; + /* pointer one past end of the loclist data. */ + Dwarf_Small *lc_endaddr; +}; diff --git a/src/lib/libdwarf/dwarf_macho_loader.h b/src/lib/libdwarf/dwarf_macho_loader.h index 1287bb1..296c9b3 100644 --- a/src/lib/libdwarf/dwarf_macho_loader.h +++ b/src/lib/libdwarf/dwarf_macho_loader.h @@ -44,17 +44,19 @@ extern "C" { #endif /* __cplusplus */ #if 0 /* Not used here. DavidA. September 2018 */ + #include changed to #xnclude so casual readers will not + be confused. /* * This file describes the format of mach object files. */ -#include +#xnclude /* * is needed here for * the cpu_type_t and cpu_subtype_t types * and contains the constants for the possible values of these types. */ -#include +#xnclude /* * is needed here for the @@ -62,15 +64,15 @@ extern "C" { * constants that are or'ed together for the * possible values of this type. */ -#include +#xnclude /* * is expected to define * the flavors of the thread * states and the structures of those flavors for each machine. */ -#include -#include +#xnclude +#xnclude #endif /* 0 */ #ifndef TYP diff --git a/src/lib/libdwarf/dwarf_names.c b/src/lib/libdwarf/dwarf_names.c index 9dece76..819c559 100644 --- a/src/lib/libdwarf/dwarf_names.c +++ b/src/lib/libdwarf/dwarf_names.c @@ -1,5 +1,5 @@ /* Generated routines, do not edit. */ -/* Generated for source version 0.9.2 */ +/* Generated for source version 0.9.3 */ /* BEGIN FILE */ @@ -226,11 +226,11 @@ dwarf_get_TAG_name (unsigned int val, case DW_TAG_immutable_type: *s_out = "DW_TAG_immutable_type"; return DW_DLV_OK; - case DW_TAG_lo_user: - *s_out = "DW_TAG_lo_user"; + case DW_TAG_TI_far_type: + *s_out = "DW_TAG_TI_far_type"; return DW_DLV_OK; /* Skipping alternate spelling of value - 0x4080. DW_TAG_TI_far_type */ + 0x4080. DW_TAG_lo_user */ case DW_TAG_MIPS_loop: *s_out = "DW_TAG_MIPS_loop"; return DW_DLV_OK; @@ -956,10 +956,10 @@ dwarf_get_AT_name (unsigned int val, case DW_AT_HP_block_index: *s_out = "DW_AT_HP_block_index"; return DW_DLV_OK; - /* Skipping alternate spelling of value - 0x2000. DW_AT_TI_veneer */ /* Skipping alternate spelling of value 0x2000. DW_AT_lo_user */ + /* Skipping alternate spelling of value + 0x2000. DW_AT_TI_veneer */ case DW_AT_MIPS_fde: *s_out = "DW_AT_MIPS_fde"; return DW_DLV_OK; @@ -1534,6 +1534,9 @@ dwarf_get_AT_name (unsigned int val, case DW_AT_APPLE_sdk: *s_out = "DW_AT_APPLE_sdk"; return DW_DLV_OK; + case DW_AT_APPLE_origin: + *s_out = "DW_AT_APPLE_origin"; + return DW_DLV_OK; case DW_AT_hi_user: *s_out = "DW_AT_hi_user"; return DW_DLV_OK; @@ -2873,6 +2876,12 @@ dwarf_get_LANG_name (unsigned int val, case DW_LANG_Ruby: *s_out = "DW_LANG_Ruby"; return DW_DLV_OK; + case DW_LANG_Move: + *s_out = "DW_LANG_Move"; + return DW_DLV_OK; + case DW_LANG_Hylo: + *s_out = "DW_LANG_Hylo"; + return DW_DLV_OK; case DW_LANG_lo_user: *s_out = "DW_LANG_lo_user"; return DW_DLV_OK; @@ -2944,11 +2953,11 @@ dwarf_get_CC_name (unsigned int val, case DW_CC_pass_by_value: *s_out = "DW_CC_pass_by_value"; return DW_DLV_OK; - case DW_CC_lo_user: - *s_out = "DW_CC_lo_user"; + case DW_CC_GNU_renesas_sh: + *s_out = "DW_CC_GNU_renesas_sh"; return DW_DLV_OK; /* Skipping alternate spelling of value - 0x40. DW_CC_GNU_renesas_sh */ + 0x40. DW_CC_lo_user */ case DW_CC_GNU_borland_fastcall_i386: *s_out = "DW_CC_GNU_borland_fastcall_i386"; return DW_DLV_OK; @@ -3420,11 +3429,11 @@ dwarf_get_CFA_name (unsigned int val, case DW_CFA_val_expression: *s_out = "DW_CFA_val_expression"; return DW_DLV_OK; - case DW_CFA_lo_user: - *s_out = "DW_CFA_lo_user"; + case DW_CFA_TI_soffset_extended: + *s_out = "DW_CFA_TI_soffset_extended"; return DW_DLV_OK; /* Skipping alternate spelling of value - 0x1c. DW_CFA_TI_soffset_extended */ + 0x1c. DW_CFA_lo_user */ /* Skipping alternate spelling of value 0x1c. DW_CFA_low_user */ case DW_CFA_MIPS_advance_loc8: diff --git a/src/lib/libdwarf/dwarf_opaque.h b/src/lib/libdwarf/dwarf_opaque.h index ca15d97..d99a4d3 100644 --- a/src/lib/libdwarf/dwarf_opaque.h +++ b/src/lib/libdwarf/dwarf_opaque.h @@ -307,14 +307,14 @@ struct Dwarf_CU_Context_s { Dwarf_Bool cc_macro_header_length_present; /* DW_SECT_RNGLISTS */ - Dwarf_Unsigned cc_rnglists_base; /*DW5 */ - Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */ /* DW_AT_GNU_ranges_base was a GNU extension that appeared but was unused. See dwarf_die_deliv.c for details. */ Dwarf_Unsigned cc_ranges_base; /* DW_AT_GNU_ranges_base is a GNU extension, DW4 */ Dwarf_Bool cc_ranges_base_present; /* .debug_rnglists */ + Dwarf_Unsigned cc_rnglists_base; /*DW5 */ + Dwarf_Unsigned cc_rnglists_base_contr_size; /*DW5 */ Dwarf_Bool cc_rnglists_base_present; /* DW5 */ Dwarf_Bool cc_rnglists_header_length_present; @@ -826,6 +826,17 @@ struct Dwarf_Debug_s { file is sometimes needed and referenced.*/ struct Dwarf_Tied_Data_s de_tied_data; + + /* The following two are used to detect a DWARF4 + .debug_addr (a GNU extension) and attempt + to print a raw .debug_addr section. Simply + assuming the first CU seen values for these + work for everything in the GNU extenstion + .debug_addr section. Only needed if the version + here is 4 (DWARF4). */ + Dwarf_Half de_debug_addr_version; + Dwarf_Half de_debug_addr_offset_size; + Dwarf_Half de_debug_addr_address_size; }; /* New style. takes advantage of dwarfstrings capability. diff --git a/src/lib/libdwarf/dwarf_peread.c b/src/lib/libdwarf/dwarf_peread.c index 40c0e1f..d24e69d 100644 --- a/src/lib/libdwarf/dwarf_peread.c +++ b/src/lib/libdwarf/dwarf_peread.c @@ -560,23 +560,23 @@ _dwarf_pe_load_dwarf_section_headers( Dwarf_Unsigned limit = 100*pep->pe_filesize; if (limit < pep->pe_filesize) { /* An overflow. Bad. */ - *errcode = DW_DLE_PE_SECTION_SIZE_ERROR; + *errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL; return DW_DLV_ERROR; } if (sec_outp->VirtualSize > - ((Dwarf_Unsigned)200* + ((Dwarf_Unsigned)2000* (Dwarf_Unsigned)1000* (Dwarf_Unsigned)1000)) { - /* Likely totally unreasonable. + /* Likely unreasonable. the hard limit written this way simply for clarity. Hard to know what to set it to. */ - *errcode = DW_DLE_PE_SECTION_SIZE_ERROR; + *errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL; return DW_DLV_ERROR; } if (sec_outp->VirtualSize > limit) { /* Likely totally unreasonable. Bad. */ - *errcode = DW_DLE_PE_SECTION_SIZE_ERROR; + *errcode = DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL; return DW_DLV_ERROR; } } diff --git a/src/lib/libdwarf/dwarf_query.c b/src/lib/libdwarf/dwarf_query.c index eab6df7..1076e9d 100644 --- a/src/lib/libdwarf/dwarf_query.c +++ b/src/lib/libdwarf/dwarf_query.c @@ -1283,18 +1283,6 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, context-> cc_addr_base= tiedcontext->cc_addr_base; } - if (!context->cc_rnglists_base_present) { - context-> cc_rnglists_base_present = - tiedcontext->cc_rnglists_base_present; - context-> cc_rnglists_base= - tiedcontext->cc_rnglists_base; - } - if (!context->cc_loclists_base_present) { - context-> cc_loclists_base_present = - tiedcontext->cc_loclists_base_present; - context-> cc_loclists_base= - tiedcontext->cc_loclists_base; - } if (!context->cc_str_offsets_tab_present) { context-> cc_str_offsets_tab_present = tiedcontext->cc_str_offsets_tab_present; @@ -1309,15 +1297,6 @@ _dwarf_merge_all_base_attrs_of_cu_die(Dwarf_Debug dbg, context-> cc_str_offsets_offset_size= tiedcontext->cc_str_offsets_offset_size; } - - /* GNU DW4 extension. */ - if (!context-> cc_ranges_base_present) { - context-> cc_ranges_base_present = - tiedcontext->cc_ranges_base_present; - context-> cc_ranges_base = - tiedcontext->cc_ranges_base; - } - if (tiedcontext_out) { *tiedcontext_out = tiedcontext; } diff --git a/src/lib/libdwarf/dwarf_rnglists.c b/src/lib/libdwarf/dwarf_rnglists.c index 4458165..2256a17 100644 --- a/src/lib/libdwarf/dwarf_rnglists.c +++ b/src/lib/libdwarf/dwarf_rnglists.c @@ -77,23 +77,92 @@ dump_rh(const char *msg, { printf("Rnglists_Head: %s line %d\n", msg,line); - printf(" count of entries: " + printf(" count of entries: %" DW_PR_DUu " (0x%" DW_PR_DUx ")\n", head->rh_count,head->rh_count); - printf(" rh_rnglists : %p\n",(void *)) head->rh_rnglists); - if (head->rh_first) { - printf(" rh_first : %" DW_PR_DUu "\n", head->rh_first); - if (head->rh_last) { - printf(" rh_last : %" DW_PR_DUu "\n",head->rh_last); - } - printf(" rh_bytes total : %" DW_PR_DUu - " (0x%" DW_PR_DUx ")\n",head->rh_bytes_total, - head->rh_bytes_total); + printf(" rh__offset_size : %p\n", + (void *) head->rh_offset_size); + printf(" rh_rnglists : %p\n",(void *) head->rh_rnglists); + printf(" rh_index : %lu\n", + (unsigned long)head->rh_index); + printf(" rh_first : %lu\n", + (unsigned long)head->rh_first); + printf(" rh_last : %lu\n", + (unsigned long)head->rh_last); + printf(" rh_bytes total : %lu (0x%lx)\n", + (unsigned long)head->rh_bytes_total, + (unsigned long)head->rh_bytes_total); printf(" CU Context : %p",(void *)head->rh_context); printf(" Rnglists Context: %p",(void *)head->rh_localcontext); } #endif +#if 0 +static void +dump_rc(const char *msg, + int line, + Dwarf_Rnglists_Context rc) +{ + printf("Rnglists_Context %s line %d index %lu\n", msg, + line, + (unsigned long)rc->rc_index); + printf(" rc_header_offset 0x%lx\n", + (unsigned long)rc->rc_header_offset); + printf(" rc_length 0x%lx\n", + (unsigned long)rc->rc_length); + printf(" rc_offset_size 0x%lu\n", + (unsigned long)rc->rc_offset_size); + printf(" rc_version 0x%lu\n", + (unsigned long)rc->rc_version); + printf(" rc_address_size 0x%lu\n", + (unsigned long)rc->rc_address_size); + printf(" rc_address_size 0x%lu\n", + (unsigned long)rc->rc_address_size); + printf(" rc_offset_entry_count 0x%lu\n", + (unsigned long)rc->rc_offset_entry_count); + printf(" rc_offsets_off_in_sect 0x%lu\n", + (unsigned long)rc->rc_offsets_off_in_sect); + printf(" rc_first_rnglist_offset 0x%lx\n", + (unsigned long)rc->rc_first_rnglist_offset); + printf(" rc_past_last_rnglist_offset 0x%lx\n", + (unsigned long)rc->rc_past_last_rnglist_offset); +} +#endif + +/* The DWARF5 standard does not make it clear that + there should be a rnglists_base even in a dwp object. + Table F.1 implies such is not needed. + gcc seems to leave it off in the dwp. + ibase is an offset in the array of offsets in a rnglist, + which only makes sense for DW_FORM_rnglistx and + in that case there is no base. + We are dealing with DW_FORM_rnglistx */ +static int +_dwarf_implicit_rnglists_base(Dwarf_Debug dbg, + Dwarf_Unsigned indexval, + Dwarf_Unsigned *ibase) +{ + Dwarf_Rnglists_Context rctx = 0; + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } + if (!dbg->de_debug_rnglists.dss_size) { + return DW_DLV_NO_ENTRY; + } + if (!dbg->de_rnglists_context_count) { + return DW_DLV_NO_ENTRY; + } + /* This implicit base can only work if the 0-th + Rnglists_Context is appropriate here. */ + rctx = dbg->de_rnglists_context[0]; + if (indexval > rctx->rc_offset_entry_count) { + /* We are not using base offset, we + will not see a DW_FORM_rnglistx */ + return DW_DLV_NO_ENTRY; + } + *ibase = rctx->rc_offsets_off_in_sect; + return DW_DLV_OK; +} /* Used in case of error reading the rnglists headers (not referring to Dwarf_Rnglists_Head @@ -110,6 +179,7 @@ free_rnglists_chain(Dwarf_Debug dbg, Dwarf_Chain head) for ( ;cur; cur = next) { next = cur->ch_next; if (cur->ch_item) { + /* ch_item is Dwarf_Rnglists_Context */ free(cur->ch_item); cur->ch_item = 0; dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); @@ -350,7 +420,6 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, buildhere->rc_version = (Dwarf_Half)version; data += SIZEOFT16; localoff += SIZEOFT16; - READ_UNALIGNED_CK(dbg,address_size,unsigned,data, SIZEOFT8,error,end_data); if (address_size != 4 && address_size != 8 && @@ -408,7 +477,6 @@ _dwarf_internal_read_rnglists_header(Dwarf_Debug dbg, if (offset_entry_count ){ buildhere->rc_offsets_array = data; } - lists_len = offset_size *offset_entry_count; if (offset_entry_count >= secsize_dbg || lists_len >= secsize_dbg) { @@ -1050,7 +1118,8 @@ dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head h) return; } -/* Caller will eventually free as appropriate. */ +/* Appends to singly-linked list. + Caller will eventually free as appropriate. */ static int alloc_rle_and_append_to_list(Dwarf_Debug dbg, Dwarf_Rnglists_Head rctx, @@ -1088,24 +1157,24 @@ alloc_rle_and_append_to_list(Dwarf_Debug dbg, in case we return DW_DLV_ERROR*/ static int build_array_of_rle(Dwarf_Debug dbg, - Dwarf_Rnglists_Head rctx, + Dwarf_Rnglists_Head rhd, Dwarf_Error *error) { int res = 0; - Dwarf_Small * data = rctx->rh_rlepointer; - Dwarf_Unsigned dataoffset = rctx->rh_rlearea_offset; - Dwarf_Small *enddata = rctx->rh_end_data_area; - unsigned address_size = (unsigned int)rctx->rh_address_size; + Dwarf_Small * data = rhd->rh_rlepointer; + Dwarf_Unsigned dataoffset = rhd->rh_rlearea_offset; + Dwarf_Small *enddata = rhd->rh_end_data_area; + unsigned address_size = (unsigned int)rhd->rh_address_size; Dwarf_Unsigned bytescounttotal= 0; Dwarf_Unsigned latestbaseaddr = 0; Dwarf_Bool foundbaseaddr = FALSE; int done = FALSE; Dwarf_Bool no_debug_addr_available = FALSE; - if (rctx->rh_cu_base_address_present) { + if (rhd->rh_cu_base_address_present) { /* The CU DIE had DW_AT_low_pc and it is a base address. */ - latestbaseaddr = rctx->rh_cu_base_address; + latestbaseaddr = rhd->rh_cu_base_address; foundbaseaddr = TRUE; } for ( ; !done ; ) { @@ -1124,7 +1193,7 @@ build_array_of_rle(Dwarf_Debug dbg, if (res != DW_DLV_OK) { return res; } - res = alloc_rle_and_append_to_list(dbg,rctx,&e,error); + res = alloc_rle_and_append_to_list(dbg,rhd,&e,error); if (res != DW_DLV_OK) { return res; } @@ -1144,7 +1213,7 @@ build_array_of_rle(Dwarf_Debug dbg, res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( - dbg,rctx->rh_context,val1,&addr1, + dbg,rhd->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { @@ -1152,6 +1221,10 @@ build_array_of_rle(Dwarf_Debug dbg, e->rle_index_failed = TRUE; e->rle_cooked1 = 0; foundbaseaddr = FALSE; + if (res == DW_DLV_ERROR) { + dwarf_dealloc_error(dbg,*error); + *error = 0; + } } else { foundbaseaddr = TRUE; e->rle_cooked1 = addr1; @@ -1163,13 +1236,17 @@ build_array_of_rle(Dwarf_Debug dbg, res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( - dbg,rctx->rh_context,val1,&addr1, + dbg,rhd->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked1 = 0; + if (res == DW_DLV_ERROR) { + dwarf_dealloc_error(dbg,*error); + *error = 0; + } } else { e->rle_cooked1 = addr1; } @@ -1177,14 +1254,17 @@ build_array_of_rle(Dwarf_Debug dbg, res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( - dbg,rctx->rh_context,val2,&addr2, + dbg,rhd->rh_context,val2,&addr2, error); } if (res != DW_DLV_OK) { no_debug_addr_available = TRUE; e->rle_index_failed = TRUE; e->rle_cooked2 = 0; - return res; + if (res == DW_DLV_ERROR) { + dwarf_dealloc_error(dbg,*error); + *error = 0; + } } else { e->rle_cooked2 = addr2; } @@ -1194,7 +1274,7 @@ build_array_of_rle(Dwarf_Debug dbg, res = DW_DLV_NO_ENTRY; } else { res = _dwarf_look_in_local_and_tied_by_index( - dbg,rctx->rh_context,val1,&addr1, + dbg,rhd->rh_context,val1,&addr1, error); } if (res != DW_DLV_OK) { @@ -1202,8 +1282,10 @@ build_array_of_rle(Dwarf_Debug dbg, e->rle_index_failed = TRUE; e->rle_cooked2 = 0; e->rle_cooked1 = 0; - return res; - + if (res == DW_DLV_ERROR) { + dwarf_dealloc_error(dbg,*error); + *error = 0; + } } else { e->rle_cooked1 = addr1; e->rle_cooked2 = val2+addr1; @@ -1251,14 +1333,14 @@ build_array_of_rle(Dwarf_Debug dbg, } } } - if (rctx->rh_count > 0) { + if (rhd->rh_count > 0) { Dwarf_Rnglists_Entry* array = 0; Dwarf_Rnglists_Entry cur = 0; Dwarf_Unsigned i = 0; /* Creating an array of pointers. */ array = (Dwarf_Rnglists_Entry*)malloc( - rctx->rh_count *sizeof(Dwarf_Rnglists_Entry)); + rhd->rh_count *sizeof(Dwarf_Rnglists_Entry)); if (!array) { _dwarf_error_string(dbg, error, DW_DLE_ALLOC_FAIL, "DW_DLE_ALLOC_FAIL: Out of memory in " @@ -1266,16 +1348,16 @@ build_array_of_rle(Dwarf_Debug dbg, "into a pointer array"); return DW_DLV_ERROR; } - cur = rctx->rh_first; - for ( ; i < rctx->rh_count; ++i) { + cur = rhd->rh_first; + for ( ; i < rhd->rh_count; ++i) { array[i] = cur; cur = cur->rle_next; } - rctx->rh_rnglists = array; - rctx->rh_first = 0; - rctx->rh_last = 0; + rhd->rh_rnglists = array; + rhd->rh_first = 0; + rhd->rh_last = 0; } - rctx->rh_bytes_total = bytescounttotal; + rhd->rh_bytes_total = bytescounttotal; return DW_DLV_OK; } @@ -1288,7 +1370,10 @@ dwarf_rnglists_get_rle_head( Dwarf_Half theform, /* attr_val is either an offset (theform == DW_FORM_sec_offset) - or an index DW_FORM_rnglistx. */ + to a specific rangelist entry set or + or a rnglistx index DW_FORM_rnglistx + at that index is the local offset of + a specific rangelist entry set. */ Dwarf_Unsigned attr_val, Dwarf_Rnglists_Head *head_out, Dwarf_Unsigned *entries_count_out, @@ -1325,33 +1410,50 @@ dwarf_rnglists_get_rle_head( dbg = ctx->cc_dbg; CHECK_DBG(dbg,error, "dwarf_rnglists_get_rle_head() via attribute"); + array = dbg->de_rnglists_context; + if (theform == DW_FORM_rnglistx) { is_rnglistx = TRUE; } /* ASSERT: the 3 pointers just set are non-null */ /* the context cc_rnglists_base gives the offset of the array. of offsets (if cc_rnglists_base_present) */ - offset_in_rnglists = attr_val; + offset_in_rnglists = attr_val; if (is_rnglistx) { if (ctx->cc_rnglists_base_present) { offset_in_rnglists = ctx->cc_rnglists_base; + } else if (ctx->cc_is_dwo) { + /* Generate a base and set as 'present' + by looking at the location offset + table that we are supposedly indexing into. + finding what the table value is. + An implicit rnglists_base. + Will not work with multiple rnglists! */ + int ires = 0; + Dwarf_Unsigned ibase = 0; + ires = _dwarf_implicit_rnglists_base(dbg, + attr_val,&ibase); + if (ires != DW_DLV_OK) { + dwarfstring m; - } else { - /* FIXME: check in tied file for a cc_rnglists_base */ - dwarfstring m; - - dwarfstring_constructor(&m); - dwarfstring_append_printf_u(&m, - "DW_DLE_RNGLISTS_ERROR: rnglists table index of" - " %u" ,attr_val); - dwarfstring_append(&m, - " is unusable unless it is in a tied file." - " Possibly libdwarf is incomplete.FIXME"); - _dwarf_error_string(dbg,error,DW_DLE_RNGLISTS_ERROR, - dwarfstring_string(&m)); - dwarfstring_destructor(&m); - return DW_DLV_ERROR; + dwarfstring_constructor(&m); + dwarfstring_append_printf_u(&m, + "DW_DLE_RNGLISTS_ERROR: rnglists table" + " index of" + " %u" ,attr_val); + dwarfstring_append(&m, + " is unusable, there is no default " + " rnglists base address "); + _dwarf_error_string(dbg,error, + DW_DLE_RNGLISTS_ERROR, + dwarfstring_string(&m)); + dwarfstring_destructor(&m); + return DW_DLV_ERROR; + } + ctx->cc_rnglists_base_present = TRUE; + ctx->cc_rnglists_base = ibase; + offset_in_rnglists = ibase; } } else { offset_in_rnglists = attr_val; diff --git a/src/lib/libdwarf/dwarf_rnglists.h b/src/lib/libdwarf/dwarf_rnglists.h index bb78f73..10db0a8 100644 --- a/src/lib/libdwarf/dwarf_rnglists.h +++ b/src/lib/libdwarf/dwarf_rnglists.h @@ -63,6 +63,13 @@ struct Dwarf_Rnglists_Context_s { unsigned rc_version; /* 5 */ Dwarf_Small rc_address_size; Dwarf_Small rc_segment_selector_size; + + /* The next three are the table of offsets. + used by DW_FORM_rnglistx. + The count may be zero if no DW_FORM_rnglistx. + If they exist the + index values in the array are offsets into area starting + with rc_first_rnglist_offset */ Dwarf_Unsigned rc_offset_entry_count; /* offset in the section of the offset entries */ @@ -70,8 +77,12 @@ struct Dwarf_Rnglists_Context_s { /* Do not free. Points into section memory */ Dwarf_Small * rc_offsets_array; + /* End table of offsets */ - /* Offset in the .debug_rnglists section of the + /* Now to the rnglists. If DW_AT_ranges FORM is + DW_FORM_sec_offset those offsets are inside + here. + Offset in the .debug_rnglists section of the first rangelist in the set of rangelists for the CU. */ Dwarf_Unsigned rc_first_rnglist_offset; diff --git a/src/lib/libdwarf/dwarf_tied.c b/src/lib/libdwarf/dwarf_tied.c index 074623e..6286fec 100644 --- a/src/lib/libdwarf/dwarf_tied.c +++ b/src/lib/libdwarf/dwarf_tied.c @@ -49,6 +49,7 @@ #include "dwarf_tsearch.h" #include "dwarf_tied_decls.h" +#if 0 void _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) { @@ -62,6 +63,7 @@ _dwarf_dumpsig(const char *msg, Dwarf_Sig8 *sig,int lineno) } printf(" line %d\n",lineno); } +#endif void * _dwarf_tied_make_entry(Dwarf_Sig8 *key, Dwarf_CU_Context val) @@ -129,6 +131,7 @@ _dwarf_tied_destroy_free_node(void*nodep) static int _dwarf_loop_reading_debug_info_for_cu( Dwarf_Debug tieddbg, + struct Dwarf_Tied_Entry_s *targsig, Dwarf_Error *error) { /* We will not find tied signatures @@ -207,11 +210,17 @@ _dwarf_loop_reading_debug_info_for_cu( *(struct Dwarf_Tied_Data_s**) retval; if (retent == entry) { /* we added a record. */ - return DW_DLV_OK; + int res = _dwarf_tied_compare_function( + targsig,entry); + if (!res) { + /* Found match, stop looping */ + return DW_DLV_OK; + } + continue; } else { /* found existing, no add */ free(entry); - return DW_DLV_OK; + continue; } } } @@ -253,14 +262,14 @@ _dwarf_search_for_signature(Dwarf_Debug tieddbg, *context_out = e2->dt_context; return DW_DLV_OK; } - /* We now ensure all tieddbg CUs signatures are in the td_tied_search, The caller is NOT doing info section read operations on the tieddbg in this (tied)dbg, so it cannot goof up their _dwarf_next_cu_header*(). */ - res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,error); + res = _dwarf_loop_reading_debug_info_for_cu(tieddbg,&entry, + error); if (res == DW_DLV_ERROR) { return res; } diff --git a/src/lib/libdwarf/dwarf_util.h b/src/lib/libdwarf/dwarf_util.h index 53d786b..98cd55f 100644 --- a/src/lib/libdwarf/dwarf_util.h +++ b/src/lib/libdwarf/dwarf_util.h @@ -30,8 +30,6 @@ Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved */ -#include "dwarf_base_types.h" - void _dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error, Dwarf_Unsigned targ, Dwarf_Unsigned sectionlen); diff --git a/src/lib/libdwarf/libdwarf.h b/src/lib/libdwarf/libdwarf.h index b908f90..0a9d8ae 100644 --- a/src/lib/libdwarf/libdwarf.h +++ b/src/lib/libdwarf/libdwarf.h @@ -99,10 +99,10 @@ extern "C" { */ /* Semantic Version identity for this libdwarf.h */ -#define DW_LIBDWARF_VERSION "0.9.2" +#define DW_LIBDWARF_VERSION "0.10.1" #define DW_LIBDWARF_VERSION_MAJOR 0 -#define DW_LIBDWARF_VERSION_MINOR 9 -#define DW_LIBDWARF_VERSION_MICRO 2 +#define DW_LIBDWARF_VERSION_MINOR 10 +#define DW_LIBDWARF_VERSION_MICRO 1 #define DW_PATHSOURCE_unspecified 0 #define DW_PATHSOURCE_basic 1 @@ -1459,9 +1459,10 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; #define DW_DLE_ARITHMETIC_OVERFLOW 501 #define DW_DLE_UNIVERSAL_BINARY_ERROR 502 #define DW_DLE_UNIV_BIN_OFFSET_SIZE_ERROR 503 +#define DW_DLE_PE_SECTION_SIZE_HEURISTIC_FAIL 504 /*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */ -#define DW_DLE_LAST 503 +#define DW_DLE_LAST 504 #define DW_DLE_LO_USER 0x10000 /*! @} */ @@ -4578,7 +4579,7 @@ DW_API int dwarf_get_loclist_head_kind( unsigned int * dw_lkind, Dwarf_Error * dw_error); -/*! @brief Retrieve the details of a location expression +/*! @brief Retrieve the details(_d) of a location expression Cooked value means the addresses from the location description after base values applied, so they @@ -4647,6 +4648,41 @@ DW_API int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c dw_loclist_head, Dwarf_Unsigned * dw_locdesc_offset_out, Dwarf_Error * dw_error); +/*! @brief Retrieve the details(_e) of a location expression + + Cooked value means the addresses from the location + description after base values applied, so they + are actual addresses. + debug_addr_unavailable non-zero means the record from a + Split Dwarf skeleton unit could not be accessed from + the .dwo section or dwp object so the + cooked values could not be calculated. + + This is identical to dwarf_get_locdesc_entry_d except + that it adds a pointer argument so the caller can know + the size, in bytes, of the loclist DW_LLE operation + itself. + + It's used by dwarfdump but it is unlikely to be of interest + to most callers.. +*/ + +DW_API int dwarf_get_locdesc_entry_e(Dwarf_Loc_Head_c dw_loclist_head, + Dwarf_Unsigned dw_index, + Dwarf_Small * dw_lle_value_out, + Dwarf_Unsigned * dw_rawlowpc, + Dwarf_Unsigned * dw_rawhipc, + Dwarf_Bool * dw_debug_addr_unavailable, + Dwarf_Addr * dw_lowpc_cooked, + Dwarf_Addr * dw_hipc_cooked, + Dwarf_Unsigned * dw_locexpr_op_count_out, + Dwarf_Unsigned * dw_lle_bytecount, + Dwarf_Locdesc_c * dw_locentry_out, + Dwarf_Small * dw_loclist_source_out, + Dwarf_Unsigned * dw_expression_offset_out, + Dwarf_Unsigned * dw_locdesc_offset_out, + Dwarf_Error * dw_error); + /*! @brief Get the raw values from a single location operation @param dw_locdesc @@ -4921,8 +4957,12 @@ DW_API int dwarf_get_loclist_lle( Dwarf_Debug dw_dbg, immediate interest. It is only intended to enable printing of the - simple .debug_addr section (by dwarfdump). - Not at all clear it is of any other use. + simple DWARF5 .debug_addr section (by dwarfdump). + + When emitting DWARF4, gcc may emit a GNU-specified + .debug_addr format. If some CU has been opened then + this call will work, but the single table + will have all the entries for all CUs. @param dw_dbg The Dwarf_Debug of interest. diff --git a/src/lib/libdwarf/libdwarf.pc.cmake b/src/lib/libdwarf/libdwarf.pc.in similarity index 88% rename from src/lib/libdwarf/libdwarf.pc.cmake rename to src/lib/libdwarf/libdwarf.pc.in index 6b18c77..1d78dbb 100644 --- a/src/lib/libdwarf/libdwarf.pc.cmake +++ b/src/lib/libdwarf/libdwarf.pc.in @@ -6,7 +6,7 @@ includedir="${prefix}/include" Name: libdwarf Description: DWARF debug symbols library -Version: @PACKAGE_VERSION@ +Version: @PROJECT_VERSION@ Libs: -L${libdir} -ldwarf Cflags: -I${includedir}