From 71090c680b4c943448ba87a0f1f864f174e4edda Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:02:33 -0600 Subject: [PATCH] Pull v0.9.0 from upstream --- CMakeLists.txt | 284 ++++---------- cmake/FindZSTD.cmake | 2 +- cmake/config.h.cmake | 26 +- patches/CMakeLists.patch | 239 ------------ pull.sh | 3 +- src/lib/libdwarf/CMakeLists.txt | 63 ++- src/lib/libdwarf/dwarf_abbrev.c | 14 +- src/lib/libdwarf/dwarf_alloc.c | 14 +- src/lib/libdwarf/dwarf_arange.c | 8 +- src/lib/libdwarf/dwarf_crc32.c | 7 +- src/lib/libdwarf/dwarf_debug_sup.c | 3 +- src/lib/libdwarf/dwarf_debugaddr.c | 1 + src/lib/libdwarf/dwarf_debuglink.c | 28 +- src/lib/libdwarf/dwarf_debugnames.c | 10 +- src/lib/libdwarf/dwarf_die_deliv.c | 355 ++++++++++------- src/lib/libdwarf/dwarf_dsc.c | 5 +- src/lib/libdwarf/dwarf_elf_load_headers.c | 6 + src/lib/libdwarf/dwarf_elfread.c | 2 + src/lib/libdwarf/dwarf_elfread.h | 2 + src/lib/libdwarf/dwarf_error.c | 4 +- src/lib/libdwarf/dwarf_find_sigref.c | 3 +- src/lib/libdwarf/dwarf_form.c | 5 +- src/lib/libdwarf/dwarf_frame.c | 80 ++-- src/lib/libdwarf/dwarf_gdbindex.c | 11 +- src/lib/libdwarf/dwarf_generic_init.c | 34 +- src/lib/libdwarf/dwarf_global.c | 61 ++- src/lib/libdwarf/dwarf_gnu_index.c | 13 +- src/lib/libdwarf/dwarf_groups.c | 13 +- src/lib/libdwarf/dwarf_harmless.c | 40 +- src/lib/libdwarf/dwarf_init_finish.c | 166 +++++--- src/lib/libdwarf/dwarf_line.c | 12 +- src/lib/libdwarf/dwarf_line.h | 2 +- src/lib/libdwarf/dwarf_loc.c | 28 +- src/lib/libdwarf/dwarf_loclists.c | 41 +- src/lib/libdwarf/dwarf_machoread.c | 27 +- src/lib/libdwarf/dwarf_machoread.h | 2 + src/lib/libdwarf/dwarf_macro.c | 2 +- src/lib/libdwarf/dwarf_macro5.c | 2 +- src/lib/libdwarf/dwarf_object_detector.c | 33 +- src/lib/libdwarf/dwarf_opaque.h | 29 +- src/lib/libdwarf/dwarf_peread.c | 19 +- src/lib/libdwarf/dwarf_peread.h | 4 +- src/lib/libdwarf/dwarf_query.c | 66 +++- src/lib/libdwarf/dwarf_ranges.c | 5 +- src/lib/libdwarf/dwarf_rnglists.c | 49 +-- src/lib/libdwarf/dwarf_str_offsets.c | 5 +- src/lib/libdwarf/dwarf_stringsection.c | 8 +- src/lib/libdwarf/dwarf_tied.c | 1 + src/lib/libdwarf/dwarf_util.c | 14 +- src/lib/libdwarf/dwarf_util.h | 22 ++ src/lib/libdwarf/dwarf_xu_index.c | 32 +- src/lib/libdwarf/libdwarf.h | 450 ++++++++++++++++++++-- src/lib/libdwarf/meson.build | 91 ++++- 53 files changed, 1346 insertions(+), 1100 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50ce24c..f444af2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,16 +2,37 @@ cmake_minimum_required(VERSION 3.5) project(libdwarf C CXX) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -include_directories( ${PROJECT_BINARY_DIR} ) +# libdwarf +option(BUILD_NON_SHARED "build archive library libdwarf[p].a" TRUE) +option(BUILD_SHARED + "build shared library libdwarf[p].so and use it" FALSE) + +# This adds compiler option -Wall (gcc compiler warnings) +option(WALL "Add -Wall" FALSE) +option(LIBDWARF_STATIC "add -DLIBDWARF_STATIC" FALSE) + +option(BUILD_DWARFDUMP "Build dwarfdump (default is YES)" TRUE) + +option(BUILD_DWARFGEN "Build dwarfgen (default is NO)" FALSE) +message(STATUS "Building dwarfgen ... ${BUILD_DWARFGEN}") + +option(BUILD_DWARFEXAMPLE "Build dwarfexample (default is NO)" FALSE) +message(STATUS "Building dwarfexample... ${BUILD_DWARFEXAMPLE}") + +option(DO_TESTING "Do certain api tests (default is NO)" FALSE) +message(STATUS "Building api tests ... ${DOTESTS}") +### end what was configure.cmake + +option(PIC_ALWAYS "Build libdwarf with position-independent code for both static and shared (default is NO)" FALSE) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +include_directories( ${PROJECT_BINARY_DIR} ) # used to compile on MSVC upto 2013 where snprintf is not available macro(msvc_posix target) if(MSVC AND ("${MSVC_VERSION}" LESS 1900)) # under VS 2015 - target_compile_definitions(${target} PUBLIC + target_compile_definitions(${target} PUBLIC snprintf=_snprintf) endif() endmacro() @@ -36,7 +57,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if (LIBDWARF_CRT STREQUAL "MT") message(STATUS "Using MT runtime by compile flag replacement") # taken from the CMake FAQ - foreach(flag_v + foreach(flag_v CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO @@ -87,12 +108,6 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON) # would probably do this anyway). set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) -enable_testing() - -# always include project's folder to includes -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) - ### begin what was configure.cmake # cmake macros include(TestBigEndian) @@ -102,7 +117,7 @@ include(CheckCSourceRuns) include(CheckSymbolExists) ### Version also appears in configure.ac set(VERSION 0.9.0) -set(PACKAGE_VERSION "\"${VERSION}\"") +set(PACKAGE_VERSION "\"${VERSION}\"") set(PACKAGE_NAME "libdwarf" ) set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"") string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" ) @@ -114,181 +129,68 @@ if (${isBigEndian}) set ( WORDS_BIGENDIAN 1 ) endif() -# check_include_file( "sys/types.h" HAVE_SYS_TYPES_H) // Only used by dwarfgen -# check_include_file( "sys/stat.h" HAVE_SYS_STAT_H ) // Only used by dwarfgen -# check_include_file( "inttypes.h" HAVE_INTTYPES_H ) // Unused -# check_include_file( "memory.h" HAVE_MEMORY_H ) // Unused -# check_include_file( "strings.h" HAVE_STRINGS_H ) // Unused +check_include_file( "sys/types.h" HAVE_SYS_TYPES_H) +check_include_file( "sys/stat.h" HAVE_SYS_STAT_H ) check_include_file( "stdint.h" HAVE_STDINT_H ) check_include_file( "unistd.h" HAVE_UNISTD_H ) -# check_include_file( "sgidefs.h" HAVE_SGIDEFS_H ) // Unused check_include_file( "stdafx.h" HAVE_STDAFX_H ) -check_include_file( "fcntl.h" HAVE_FCNTL_H ) +check_include_file( "fcntl.h" HAVE_FCNTL_H ) ### cmake provides no way to guarantee uint32_t present. ### configure does guarantee that. -# HAVE_UINTPTR_T: Unused -# uintptr_t: Unused -# HAVE_INTPTR_T: Unused -# if(HAVE_STDINT_H) -# check_c_source_compiles(" -# #include -# int main() -# { -# uintptr_t i; i = 12; -# return (int)i; -# }" HAVE_UINTPTR_T) -# check_c_source_compiles(" -# #include -# int main() -# { -# intptr_t i; i = 12; -# return (int)i; -# }" HAVE_INTPTR_T) -# endif() -# if (HAVE_UINTPTR_T) -# message(STATUS "HAVE_UINTPTR_T 1: uintptr_t defined in stdint.h... YES") -# else() -# message(STATUS "uintptr_t defined in stdint.h... NO") -# set(uintptr_t "unsigned long long int" ) -# message(STATUS "Setting #define uintptr_t " ${uintptr_t}) -# endif() -# if (uintptr_t) -# message(STATUS "uintptr_t value considered YES ") -# else() -# message(STATUS "uintptr_t value considered NO ") -# endif() -# if (HAVE_INTPTR_T) -# message(STATUS "HAVE_INTPTR_T 1: intptr_t defined in stdint.h... YES") -# else() -# message(STATUS "intptr_t defined in stdint.h... NO") -# set(uintptr_t "long long int" ) -# message(STATUS "Setting #define intptr_t " ${intptr_t}) -# endif() -# if (intptr_t) -# message(STATUS "intptr_t value considered YES ") -# else() -# message(STATUS "intptr_t value considered NO ") -# endif() - -# Unused -# check_c_source_compiles(" -# static unsigned foo( unsigned x, -# __attribute__ ((unused)) int y) -# { -# unsigned x2 = x + 1; -# return x2; -# } - -# int main(void) { -# unsigned y = 0; -# y = foo(12,y); -# return 0; -# }" HAVE_UNUSED_ATTRIBUTE) -# message(STATUS "Checking compiler supports __attribute__ unused... ${HAVE_UNUSED_ATTRIBUTE}") - -# Redundant -# check_c_source_compiles([=[ -# #include "stdafx.h" -# int main() -# { -# int p; p = 27; -# return 0; -# }]=] HAVE_STDAFX_H) -#message(STATUS "Checking have windows stdafx.h... ${HAVE_STDAFX_H}") - -set(CMAKE_REQUIRED_LIBRARIES z) -check_c_source_compiles( [=[ - #include "zlib.h" +if(HAVE_STDINT_H) + check_c_source_compiles(" + #include int main() { - Bytef dest[100]; - uLongf destlen = 100; - Bytef *src = 0; - uLong srclen = 3; - int res = uncompress(dest,&destlen,src,srclen); - if (res == Z_OK) { - /* ALL IS WELL */ - } - return 0; - } ]=] HAVE_ZLIB ) -check_c_source_compiles( [=[ - #include "zlib.h" + uintptr_t i; i = 12; + return (int)i; + }" HAVE_UINTPTR_T) + check_c_source_compiles(" + #include int main() { - Bytef dest[100]; - uLongf destlen = 100; - Bytef *src = 0; - uLong srclen = 3; - int res = uncompress(dest,&destlen,src,srclen); - if (res == Z_OK) { - /* ALL IS WELL */ - } - return 0; - } ]=] HAVE_ZLIB_H ) -set(CMAKE_REQUIRED_LIBRARIES) -if (HAVE_ZLIB) - # For linking in libz - set(DW_FZLIB "z") + intptr_t i; i = 12; + return (int)i; + }" HAVE_INTPTR_T) +endif() +if (HAVE_UINTPTR_T) + message(STATUS "HAVE_UINTPTR_T 1: uintptr_t defined in stdint.h... YES") +else() + message(STATUS "uintptr_t defined in stdint.h... NO") + set(uintptr_t "unsigned long long int" ) + message(STATUS "Setting #define uintptr_t " ${uintptr_t}) +endif() +if (uintptr_t) + message(STATUS "uintptr_t value considered YES ") +else() + message(STATUS "uintptr_t value considered NO ") +endif() +if (HAVE_INTPTR_T) + message(STATUS "HAVE_INTPTR_T 1: intptr_t defined in stdint.h... YES") +else() + message(STATUS "intptr_t defined in stdint.h... NO") + set(intptr_t "long long int" ) + message(STATUS "Setting #define intptr_t " ${intptr_t}) +endif() +if (intptr_t) + message(STATUS "intptr_t value considered YES ") +else() + message(STATUS "intptr_t value considered NO ") endif() -set(CMAKE_REQUIRED_LIBRARIES zstd ) -check_c_source_compiles( [=[ - #include "zstd.h" - int main() - { - char * dest[100]; - size_t destlen = 100; - char *src = 0; - size_t srclen = 3; - size_t res = ZSTD_decompress(dest,destlen,src,srclen); - if (res == destlen) { - /* ALL IS WELL */ - } - return 0; - } ]=] HAVE_ZSTD ) -check_c_source_compiles( [=[ - #include "zstd.h" - int main() - { - char * dest[100]; - size_t destlen = 100; - char *src = 0; - size_t srclen = 3; - size_t res = ZSTD_decompress(dest,destlen,src,srclen); - if (res == destlen) { - /* ALL IS WELL */ - } - return 0; - } ]=] HAVE_ZSTD_H ) -set(CMAKE_REQUIRED_LIBRARIES) -if (HAVE_ZSTD) - # For linking in libzstd - set(DW_FZSTD "zstd") +# Zlib and ZSTD need to be found otherwise disable it +find_package(ZLIB) +find_package(ZSTD) +if (ZLIB_FOUND AND ZSTD_FOUND ) + set(HAVE_ZLIB TRUE) + set(HAVE_ZLIB_H TRUE) + set(HAVE_ZSTD TRUE) + set(HAVE_ZSTD_H TRUE) endif() - -# Unused -# check_c_source_compiles([=[ -# #include -# int main() -# { -# intptr_t p; -# p = 27; -# return 0; -# }]=] HAVE_INTPTR_T) - message(STATUS "CMAKE_SIZEOF_VOID_P ... " ${CMAKE_SIZEOF_VOID_P} ) -# libdwarf -option(BUILD_NON_SHARED "build archive library libdwarf[p].a" TRUE) -option(BUILD_SHARED - "build shared library libdwarf[p].so and use it" FALSE) - -# This adds compiler option -Wall (gcc compiler warnings) -option(WALL "Add -Wall" FALSE) -option(LIBDWARF_STATIC "add -DLIBDWARF_STATIC" FALSE) - # DW_FWALLXX are gnu C++ options. if (WALL) set(DW_FWALLXX -Wall -Wextra -Wno-unused-private-field -Wpointer-arith -Wmissing-declarations -Wcomment -Wformat -Wpedantic -Wuninitialized -Wshadow -Wno-long-long -Werror) @@ -304,40 +206,14 @@ endif() # unset(DW_LIBDWARF_STATIC) #endif() -option(BUILD_DWARFDUMP "Build dwarfdump (default is YES)" FALSE) - -option(BUILD_DWARFGEN "Build dwarfgen (default is NO)" FALSE) -message(STATUS "Building dwarfgen ... ${BUILD_DWARFGEN}") - -option(BUILD_DWARFEXAMPLE "Build dwarfexample (default is NO)" FALSE) -message(STATUS "Building dwarfexample... ${BUILD_DWARFEXAMPLE}") - -option(DO_TESTING "Do certain api tests (default is NO)" FALSE) -message(STATUS "Building api tests ... ${DOTESTS}") -### end what was configure.cmake - -option(PIC_ALWAYS "Build libdwarf with position-independent code for both static and shared (default is NO)" FALSE) - configure_file(cmake/config.h.cmake config.h) if(BUILD_NON_SHARED) - set(DW_LIBDWARF_STATIC -DLIBDWARF_STATIC) - set(BUILD_SHARED_LIBS NO) - set(DWARF_TARGETS dwarf-static) - set(DWARF_TYPES STATIC) - set(dwarf-target dwarf-static) - set(DWARFP_TARGETS dwarfp-static) - set(DWARFP_TYPES STATIC) - set(dwarfp-target dwarfp-static) + set(DW_LIBDWARF_STATIC -DLIBDWARF_STATIC) + set(BUILD_SHARED_LIBS NO) else() - unset(DW_LIBDWARF_STATIC) - set(BUILD_SHARED_LIBS YES) - set(DWARF_TARGETS dwarf-shared) - set(DWARF_TYPES SHARED) - set(dwarf-target dwarf-shared) - set(DWARFP_TARGETS dwarfp-shared) - set(DWARFP_TYPES SHARED) - set(dwarfp-target dwarfp-shared) + unset(DW_LIBDWARF_STATIC) + set(BUILD_SHARED_LIBS YES) endif() add_subdirectory(src/lib/libdwarf) @@ -351,13 +227,13 @@ if ( BUILD_DWARFEXAMPLE ) endif() if ( BUILD_DWARFGEN ) - set(LIBDWARF_INCLUDE_DIR ../libdwarf) - add_subdirectory(src/lib/libdwarfp) - add_subdirectory(src/bin/dwarfgen) + add_subdirectory(src/lib/libdwarfp) + add_subdirectory(src/bin/dwarfgen) endif() if (DO_TESTING) -add_subdirectory(test) + enable_testing() + add_subdirectory(test) endif() message(STATUS "Install prefix ... ${CMAKE_INSTALL_PREFIX}" ) diff --git a/cmake/FindZSTD.cmake b/cmake/FindZSTD.cmake index 8dd53bf..6feac63 100644 --- a/cmake/FindZSTD.cmake +++ b/cmake/FindZSTD.cmake @@ -58,6 +58,6 @@ find_package_handle_standard_args(ZSTD REQUIRED_VARS ZSTD_LIBRARIES ZSTD_INCLUDE if (ZSTD_FOUND) if (NOT TARGET ZSTD::ZSTD) add_library(ZSTD::ZSTD UNKNOWN IMPORTED) - set_target_properties(ZSTD::ZSTD PROPERTIES IMPORTED_LOCATION "${ZSTD_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${ZSTD_INCLUDE_DIRS}") + set_target_properties(ZSTD::ZSTD PROPERTIES IMPORTED_LOCATION "${ZSTD_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${ZSTD_INCLUDE_DIR}") endif () endif () diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake index c672c41..021d3ab 100644 --- a/cmake/config.h.cmake +++ b/cmake/config.h.cmake @@ -10,41 +10,24 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_FCNTL_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MALLOC_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - /* Set to 1 if big endian . */ #cmakedefine WORDS_BIGENDIAN 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SGIDEFS_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H 1 -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H 1 -/* Define to HAVE_UINTPTR_T 1 if the system has the type `uintptr_t'. */ -#cmakedefine HAVE_UINTPTR_T 1 -/* Define to 1 if the system has the type `intptr_t'. */ -#cmakedefine HAVE_INTPTR_T - /* Define to the uintptr_t to the type of an unsigned integer type wide enough to hold a pointer @@ -55,15 +38,18 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H 1 -/* Set to 1 if __attribute__ ((unused)) is available. */ -#cmakedefine HAVE_UNUSED_ATTRIBUTE 1 - /* Set to 1 if zlib decompression is available. */ #cmakedefine HAVE_ZLIB 1 /* Define to 1 if you have the header file. */ #cmakedefine HAVE_ZLIB_H 1 +/* Set to 1 if zstd decompression is available. */ +#cmakedefine HAVE_ZSTD 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ZSTD_H 1 + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #cmakedefine LT_OBJDIR 1 diff --git a/patches/CMakeLists.patch b/patches/CMakeLists.patch index 4941446..e69de29 100644 --- a/patches/CMakeLists.patch +++ b/patches/CMakeLists.patch @@ -1,239 +0,0 @@ ---- CMakeLists.txt 2023-11-13 10:57:07.278246800 -0500 -+++ CMakeListsUpdated.txt 2023-11-13 11:11:35.551623300 -0500 -@@ -11,7 +11,7 @@ - macro(msvc_posix target) - if(MSVC AND ("${MSVC_VERSION}" LESS 1900)) - # under VS 2015 -- target_compile_definitions(${target} PUBLIC -+ target_compile_definitions(${target} PUBLIC - snprintf=_snprintf) - endif() - endmacro() -@@ -36,7 +36,7 @@ - if (LIBDWARF_CRT STREQUAL "MT") - message(STATUS "Using MT runtime by compile flag replacement") - # taken from the CMake FAQ -- foreach(flag_v -+ foreach(flag_v - CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG - CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL - CMAKE_C_FLAGS_RELWITHDEBINFO -@@ -102,7 +102,7 @@ - include(CheckSymbolExists) - ### Version also appears in configure.ac - set(VERSION 0.9.0) --set(PACKAGE_VERSION "\"${VERSION}\"") -+set(PACKAGE_VERSION "\"${VERSION}\"") - set(PACKAGE_NAME "libdwarf" ) - set(PACKAGE_STRING "\"${PACKAGE_NAME} ${VERSION}\"") - string(REGEX REPLACE "[\"]" "" tarname1 "${PACKAGE_STRING}" ) -@@ -114,83 +114,87 @@ - set ( WORDS_BIGENDIAN 1 ) - endif() - --check_include_file( "sys/types.h" HAVE_SYS_TYPES_H) --check_include_file( "sys/stat.h" HAVE_SYS_STAT_H ) --check_include_file( "inttypes.h" HAVE_INTTYPES_H ) --check_include_file( "memory.h" HAVE_MEMORY_H ) --check_include_file( "strings.h" HAVE_STRINGS_H ) -+# check_include_file( "sys/types.h" HAVE_SYS_TYPES_H) // Only used by dwarfgen -+# check_include_file( "sys/stat.h" HAVE_SYS_STAT_H ) // Only used by dwarfgen -+# check_include_file( "inttypes.h" HAVE_INTTYPES_H ) // Unused -+# check_include_file( "memory.h" HAVE_MEMORY_H ) // Unused -+# check_include_file( "strings.h" HAVE_STRINGS_H ) // Unused - check_include_file( "stdint.h" HAVE_STDINT_H ) - check_include_file( "unistd.h" HAVE_UNISTD_H ) --check_include_file( "sgidefs.h" HAVE_SGIDEFS_H ) -+# check_include_file( "sgidefs.h" HAVE_SGIDEFS_H ) // Unused - check_include_file( "stdafx.h" HAVE_STDAFX_H ) --check_include_file( "fcntl.h" HAVE_FCNTL_H ) -+check_include_file( "fcntl.h" HAVE_FCNTL_H ) - - ### cmake provides no way to guarantee uint32_t present. - ### configure does guarantee that. --if(HAVE_STDINT_H) -- check_c_source_compiles(" -- #include -- int main() -- { -- uintptr_t i; i = 12; -- return (int)i; -- }" HAVE_UINTPTR_T) -- check_c_source_compiles(" -- #include -- int main() -- { -- intptr_t i; i = 12; -- return (int)i; -- }" HAVE_INTPTR_T) --endif() --if (HAVE_UINTPTR_T) -- message(STATUS "HAVE_UINTPTR_T 1: uintptr_t defined in stdint.h... YES") --else() -- message(STATUS "uintptr_t defined in stdint.h... NO") -- set(uintptr_t "unsigned long long int" ) -- message(STATUS "Setting #define uintptr_t " ${uintptr_t}) --endif() --if (uintptr_t) -- message(STATUS "uintptr_t value considered YES ") --else() -- message(STATUS "uintptr_t value considered NO ") --endif() --if (HAVE_INTPTR_T) -- message(STATUS "HAVE_INTPTR_T 1: intptr_t defined in stdint.h... YES") --else() -- message(STATUS "intptr_t defined in stdint.h... NO") -- set(uintptr_t "long long int" ) -- message(STATUS "Setting #define intptr_t " ${intptr_t}) --endif() --if (intptr_t) -- message(STATUS "intptr_t value considered YES ") --else() -- message(STATUS "intptr_t value considered NO ") --endif() -- -- --check_c_source_compiles(" -- static unsigned foo( unsigned x, -- __attribute__ ((unused)) int y) -- { -- unsigned x2 = x + 1; -- return x2; -- } -- -- int main(void) { -- unsigned y = 0; -- y = foo(12,y); -- return 0; -- }" HAVE_UNUSED_ATTRIBUTE) --message(STATUS "Checking compiler supports __attribute__ unused... ${HAVE_UNUSED_ATTRIBUTE}") -- --check_c_source_compiles([=[ -- #include "stdafx.h" -- int main() -- { -- int p; p = 27; -- return 0; -- }]=] HAVE_STDAFX_H) -+# HAVE_UINTPTR_T: Unused -+# uintptr_t: Unused -+# HAVE_INTPTR_T: Unused -+# if(HAVE_STDINT_H) -+# check_c_source_compiles(" -+# #include -+# int main() -+# { -+# uintptr_t i; i = 12; -+# return (int)i; -+# }" HAVE_UINTPTR_T) -+# check_c_source_compiles(" -+# #include -+# int main() -+# { -+# intptr_t i; i = 12; -+# return (int)i; -+# }" HAVE_INTPTR_T) -+# endif() -+# if (HAVE_UINTPTR_T) -+# message(STATUS "HAVE_UINTPTR_T 1: uintptr_t defined in stdint.h... YES") -+# else() -+# message(STATUS "uintptr_t defined in stdint.h... NO") -+# set(uintptr_t "unsigned long long int" ) -+# message(STATUS "Setting #define uintptr_t " ${uintptr_t}) -+# endif() -+# if (uintptr_t) -+# message(STATUS "uintptr_t value considered YES ") -+# else() -+# message(STATUS "uintptr_t value considered NO ") -+# endif() -+# if (HAVE_INTPTR_T) -+# message(STATUS "HAVE_INTPTR_T 1: intptr_t defined in stdint.h... YES") -+# else() -+# message(STATUS "intptr_t defined in stdint.h... NO") -+# set(uintptr_t "long long int" ) -+# message(STATUS "Setting #define intptr_t " ${intptr_t}) -+# endif() -+# if (intptr_t) -+# message(STATUS "intptr_t value considered YES ") -+# else() -+# message(STATUS "intptr_t value considered NO ") -+# endif() -+ -+# Unused -+# check_c_source_compiles(" -+# static unsigned foo( unsigned x, -+# __attribute__ ((unused)) int y) -+# { -+# unsigned x2 = x + 1; -+# return x2; -+# } -+ -+# int main(void) { -+# unsigned y = 0; -+# y = foo(12,y); -+# return 0; -+# }" HAVE_UNUSED_ATTRIBUTE) -+# message(STATUS "Checking compiler supports __attribute__ unused... ${HAVE_UNUSED_ATTRIBUTE}") -+ -+# Redundant -+# check_c_source_compiles([=[ -+# #include "stdafx.h" -+# int main() -+# { -+# int p; p = 27; -+# return 0; -+# }]=] HAVE_STDAFX_H) - #message(STATUS "Checking have windows stdafx.h... ${HAVE_STDAFX_H}") - - set(CMAKE_REQUIRED_LIBRARIES z) -@@ -223,7 +227,7 @@ - return 0; - } ]=] HAVE_ZLIB_H ) - set(CMAKE_REQUIRED_LIBRARIES) --if (HAVE_ZLIB) -+if (HAVE_ZLIB) - # For linking in libz - set(DW_FZLIB "z") - endif() -@@ -264,21 +268,21 @@ - endif() - - -- --check_c_source_compiles([=[ --#include --int main() --{ -- intptr_t p; -- p = 27; -- return 0; --}]=] HAVE_INTPTR_T) -+# Unused -+# check_c_source_compiles([=[ -+# #include -+# int main() -+# { -+# intptr_t p; -+# p = 27; -+# return 0; -+# }]=] HAVE_INTPTR_T) - - message(STATUS "CMAKE_SIZEOF_VOID_P ... " ${CMAKE_SIZEOF_VOID_P} ) - --# libdwarf -+# libdwarf - option(BUILD_NON_SHARED "build archive library libdwarf[p].a" TRUE) --option(BUILD_SHARED -+option(BUILD_SHARED - "build shared library libdwarf[p].so and use it" FALSE) - - # This adds compiler option -Wall (gcc compiler warnings) -@@ -300,7 +304,7 @@ - # unset(DW_LIBDWARF_STATIC) - #endif() - --option(BUILD_DWARFDUMP "Build dwarfdump (default is YES)" TRUE) -+option(BUILD_DWARFDUMP "Build dwarfdump (default is YES)" FALSE) - - option(BUILD_DWARFGEN "Build dwarfgen (default is NO)" FALSE) - message(STATUS "Building dwarfgen ... ${BUILD_DWARFGEN}") diff --git a/pull.sh b/pull.sh index 52f2f88..8c96996 100644 --- a/pull.sh +++ b/pull.sh @@ -5,7 +5,8 @@ rm -rfv cmake src CMakeLists.txt COPYING echo "Fetching" git clone https://github.com/davea42/libdwarf-code.git cd libdwarf-code -git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0 +#git checkout "6216e185863f41d6f19ab850caabfff7326020d7" # v0.8.0 +git checkout "8b0bd09d8c77d45a68cb1bb00a54186a92b683d9" # v0.9.0 cd .. echo "Copying files" mkdir -p src/lib diff --git a/src/lib/libdwarf/CMakeLists.txt b/src/lib/libdwarf/CMakeLists.txt index 9d3eab0..4ad5c4f 100644 --- a/src/lib/libdwarf/CMakeLists.txt +++ b/src/lib/libdwarf/CMakeLists.txt @@ -91,50 +91,34 @@ endif() include(GNUInstallDirs) -list(LENGTH DWARF_TARGETS targetCount) -math(EXPR targetCount "${targetCount} - 1") -list(APPEND DWARF_LIBS ${LIBELF_LIBRARIES}) -if (DW_FZLIB) - list(APPEND DWARF_LIBS z) -endif() -if (DW_FZSTD) - list(APPEND DWARF_LIBS zstd) -endif() -foreach(i RANGE ${targetCount}) - list(GET DWARF_TARGETS ${i} target) - list(GET DWARF_TYPES ${i} type) - add_library(${target} ${type} ${SOURCES} ${HEADERS} - ${GENNAMES_OUTPUT} ${CONFIGURATION_FILES}) - add_library(libdwarf::${target} ALIAS ${target}) - - set_folder(${target} src/lib/libdwarf) - target_compile_options(${target} PRIVATE ${COMPILER_FLAGS} - ${DW_FWALL}) - msvc_posix(${target}) - - target_compile_definitions(${target} PUBLIC ${DEFS}) - - target_include_directories( - ${target} - PUBLIC +if(BUILD_SHARED) + add_library(dwarf SHARED ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) + add_library(libdwarf::dwarf-shared ALIAS dwarf) +else() + add_library(dwarf STATIC ${SOURCES} ${HEADERS} ${CONFIGURATION_FILES}) + add_library(libdwarf::dwarf-static ALIAS dwarf) +endif() +set_folder(dwarf src/lib/libdwarf) +target_compile_options(dwarf PRIVATE ${COMPILER_FLAGS} ${DW_FWALL}) +msvc_posix(dwarf) +target_compile_definitions(dwarf PUBLIC ${DEFS}) +target_include_directories(dwarf PUBLIC $ $ ) +if(ZLIB_FOUND AND ZSTD_FOUND) + target_link_libraries(dwarf PRIVATE ZLIB::ZLIB ZSTD::ZSTD ) +endif() - target_link_libraries(${target} PUBLIC ${DW_FZLIB} ${DW_FZSTD} ) - - set_target_properties(${target} PROPERTIES OUTPUT_NAME dwarf) +set(SUFFIX $<$:64>) +set(LIBDIR lib${SUFFIX}) +set(BINDIR bin${SUFFIX}) - set(SUFFIX $<$:64>) - set(LIBDIR lib${SUFFIX}) - set(BINDIR bin${SUFFIX}) - - install(TARGETS ${target} - RUNTIME DESTINATION ${BINDIR} - LIBRARY DESTINATION ${LIBDIR} - ARCHIVE DESTINATION ${LIBDIR}) -endforeach() +install(TARGETS dwarf + RUNTIME DESTINATION ${BINDIR} + LIBRARY DESTINATION ${LIBDIR} + ARCHIVE DESTINATION ${LIBDIR}) configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY ) @@ -142,8 +126,7 @@ configure_file(libdwarf.pc.cmake libdwarf.pc @ONLY ) # another CMakeLists.txt to make install work properly # for cmake before cmake 3.13. This also works # for newer cmake. -add_custom_target(dd DEPENDS ${DWARF_TARGETS} dwarfdump) -install(TARGETS ${DWARF_TARGETS} EXPORT libdwarfTargets +install(TARGETS dwarf EXPORT libdwarfTargets ARCHIVE DESTINATION lib LIBRARY DESTINATION lib INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") diff --git a/src/lib/libdwarf/dwarf_abbrev.c b/src/lib/libdwarf/dwarf_abbrev.c index 360db8b..d675dae 100644 --- a/src/lib/libdwarf/dwarf_abbrev.c +++ b/src/lib/libdwarf/dwarf_abbrev.c @@ -39,6 +39,8 @@ #include "libdwarf_private.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" +#include "libdwarf_private.h" +#include "dwarf_util.h" #include "dwarf_abbrev.h" #include "dwarf_alloc.h" #include "dwarf_error.h" @@ -168,15 +170,7 @@ dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned abbrev_implicit_const_count_out = 0; int res = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: " - "calling dwarf_get_abbrev " - "either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } - + CHECK_DBG(dbg,error,"dwarf_get_abbrev()"); if (dbg->de_debug_abbrev.dss_data == 0) { /* Loads abbrev section (and .debug_info as we do those together). */ @@ -372,7 +366,7 @@ dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, } dbg = abbrev->dab_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: " "calling dwarf_get_abbrev_entry_b() " diff --git a/src/lib/libdwarf/dwarf_alloc.c b/src/lib/libdwarf/dwarf_alloc.c index cb5642f..9ef9b16 100644 --- a/src/lib/libdwarf/dwarf_alloc.c +++ b/src/lib/libdwarf/dwarf_alloc.c @@ -584,7 +584,7 @@ _dwarf_get_alloc(Dwarf_Debug dbg, unsigned int type = alloc_type; short action = 0; - if (dbg == NULL) { + if (IS_INVALID_DBG(dbg)) { #if DEBUG_ALLOC printf("libdwarfdetector ALLOC dbg null " "ret NULL type 0x%x size %lu line %d %s\n", @@ -748,7 +748,7 @@ dwarf_dealloc_die( Dwarf_Die die) return; } dbg = context->cc_dbg; - if (!dbg ||dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { return; } dwarf_dealloc(dbg,die,DW_DLA_DIE); @@ -813,7 +813,7 @@ dwarf_dealloc(Dwarf_Debug dbg, #endif /* DEBUG_ALLOC*/ return; } - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { /* App error, or an app that failed in a dwarf_init*() or dwarf_elf_init*() call. @@ -994,7 +994,7 @@ _dwarf_get_debug(Dwarf_Unsigned filesize) Dwarf_Debug dbg; dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s)); - if (dbg == NULL) { + if (!dbg) { return NULL; } memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); @@ -1069,11 +1069,7 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg) { unsigned g = 0; - if (dbg == NULL) { - _dwarf_free_static_errlist(); - return DW_DLV_NO_ENTRY; - } - if (dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_free_static_errlist(); return DW_DLV_NO_ENTRY; } diff --git a/src/lib/libdwarf/dwarf_arange.c b/src/lib/libdwarf/dwarf_arange.c index 5e49ba5..5f06c1f 100644 --- a/src/lib/libdwarf/dwarf_arange.c +++ b/src/lib/libdwarf/dwarf_arange.c @@ -416,11 +416,7 @@ dwarf_get_aranges(Dwarf_Debug dbg, /* ***** BEGIN CODE ***** */ - if (dbg == NULL) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } - + CHECK_DBG(dbg,error,"dwarf_get_aranges()"); res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error); if (res != DW_DLV_OK) { return res; @@ -500,7 +496,7 @@ _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, if (error != NULL) *error = NULL; - if (dbg == NULL) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } diff --git a/src/lib/libdwarf/dwarf_crc32.c b/src/lib/libdwarf/dwarf_crc32.c index 9aea05a..2caa154 100644 --- a/src/lib/libdwarf/dwarf_crc32.c +++ b/src/lib/libdwarf/dwarf_crc32.c @@ -45,6 +45,7 @@ #include "libdwarf.h" #include "libdwarf_private.h" #include "dwarf_base_types.h" +#include "dwarf_util.h" #include "dwarf_opaque.h" #include "dwarf_error.h" @@ -75,11 +76,7 @@ dwarf_crc32 (Dwarf_Debug dbg,unsigned char *crcbuf, unsigned int init = 0; int fd = -1; - if (!dbg) { - _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: Bad call to dwarf_crc32"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_crc32()"); if (!crcbuf) { return DW_DLV_NO_ENTRY; } diff --git a/src/lib/libdwarf/dwarf_debug_sup.c b/src/lib/libdwarf/dwarf_debug_sup.c index 18086f1..55ddc03 100644 --- a/src/lib/libdwarf/dwarf_debug_sup.c +++ b/src/lib/libdwarf/dwarf_debug_sup.c @@ -56,7 +56,7 @@ static void get_sup_fields(Dwarf_Debug dbg, struct Dwarf_Section_s **sec_out) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return; } *sec_out = &dbg->de_debug_sup; @@ -97,6 +97,7 @@ dwarf_get_debug_sup(Dwarf_Debug dbg, Dwarf_Small *enddata = 0; Dwarf_Unsigned size = 0; + CHECK_DBG(dbg,error,"dwarf_get_debug_sup()"); res = load_sup(dbg,error); if (res != DW_DLV_OK) { return res; diff --git a/src/lib/libdwarf/dwarf_debugaddr.c b/src/lib/libdwarf/dwarf_debugaddr.c index 0f4c46a..61f15a5 100644 --- a/src/lib/libdwarf/dwarf_debugaddr.c +++ b/src/lib/libdwarf/dwarf_debugaddr.c @@ -105,6 +105,7 @@ dwarf_debug_addr_table(Dwarf_Debug dbg, /* we will instantiate this below */ Dwarf_Debug_Addr_Table newad = 0; + CHECK_DBG(dbg,error,"dwarf_debug_addr_table()"); res = _dwarf_load_section(dbg, &dbg->de_debug_addr,error); if (res == DW_DLV_NO_ENTRY) { return res; diff --git a/src/lib/libdwarf/dwarf_debuglink.c b/src/lib/libdwarf/dwarf_debuglink.c index 708cd7c..9d896bb 100644 --- a/src/lib/libdwarf/dwarf_debuglink.c +++ b/src/lib/libdwarf/dwarf_debuglink.c @@ -939,7 +939,17 @@ _dwarf_extract_buildid(Dwarf_Debug dbg, and are only valid while that dbg is open. debuglink_path_returned. crc_returned, buildid_owner_name_returned, - buildid_returned, */ + buildid_returned, + + Caller must initialize the passed-in pointers + debuglink_fullpath_returned + and paths_returned to zero, and other arguments + to zero or sensible values before calling. + + If the dbg was set up via dwarf_init_b(fd... ) + then dbg->de_path will be 0, a null pointer + which makes some of this less than useful. +*/ int dwarf_gnu_debuglink(Dwarf_Debug dbg, char ** debuglink_path_returned, /* do not free*/ @@ -951,7 +961,7 @@ dwarf_gnu_debuglink(Dwarf_Debug dbg, char ** buildid_owner_name_returned, unsigned char ** buildid_returned, unsigned * buildid_length_returned, - char *** paths_returned, + char *** paths_returned, /* caller frees */ unsigned * paths_count_returned, Dwarf_Error* error) { @@ -962,6 +972,7 @@ dwarf_gnu_debuglink(Dwarf_Debug dbg, struct Dwarf_Section_s * pdebuglink = 0; struct Dwarf_Section_s * pbuildid = 0; + CHECK_DBG(dbg,error,"dwarf_gnu_debuglink()"); if (dbg->de_gnu_debuglink.dss_size) { pdebuglink = &dbg->de_gnu_debuglink; res = _dwarf_load_section(dbg, pdebuglink,error); @@ -978,9 +989,14 @@ dwarf_gnu_debuglink(Dwarf_Debug dbg, } if (!pdebuglink && !pbuildid) { - *debuglink_fullpath_returned = strdup(dbg->de_path); - *debuglink_fullpath_length_returned = + if (dbg->de_path) { + *debuglink_fullpath_returned = strdup(dbg->de_path); + *debuglink_fullpath_length_returned = (unsigned)strlen(dbg->de_path); + } else { + *debuglink_fullpath_returned = 0; + *debuglink_fullpath_length_returned = 0; + } return DW_DLV_OK; } @@ -1011,7 +1027,8 @@ dwarf_gnu_debuglink(Dwarf_Debug dbg, } } dwarfstring_constructor(&debuglink_fullpath); - pathname = (char *)dbg->de_path; + pathname = dbg->de_path?(char *)dbg->de_path: + ""; if (pathname && paths_returned) { /* Caller wants paths created and returned. */ res = _dwarf_construct_linkedto_path( @@ -1059,6 +1076,7 @@ dwarf_add_debuglink_global_path(Dwarf_Debug dbg, char **glpaths = 0; char *path1 = 0; + CHECK_DBG(dbg,error,"dwarf_add_debuglink_global_path()"); glpath_count_in = dbg->de_gnu_global_path_count; glpath_count_out = glpath_count_in+1; glpaths = (char **)malloc(sizeof(char *)* diff --git a/src/lib/libdwarf/dwarf_debugnames.c b/src/lib/libdwarf/dwarf_debugnames.c index 081d3d1..a547aa2 100644 --- a/src/lib/libdwarf/dwarf_debugnames.c +++ b/src/lib/libdwarf/dwarf_debugnames.c @@ -779,13 +779,7 @@ dwarf_dnames_header(Dwarf_Debug dbg, Dwarf_Small *curptr = 0; int res = 0; - if (!dbg) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: Dwarf_Debug argument in " - "dwarf_dnames_header() " - "call is NULL"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_dnames_header()"); res = _dwarf_load_section(dbg, &dbg->de_debug_names, error); if (res != DW_DLV_OK) { return res; @@ -1497,7 +1491,7 @@ dwarf_dnames_name(Dwarf_Dnames_Head dn, return DW_DLV_ERROR; } dbg = dn->dn_dbg; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: " "a call to dwarf_dnames_name() " diff --git a/src/lib/libdwarf/dwarf_die_deliv.c b/src/lib/libdwarf/dwarf_die_deliv.c index cba0ae6..67967d4 100644 --- a/src/lib/libdwarf/dwarf_die_deliv.c +++ b/src/lib/libdwarf/dwarf_die_deliv.c @@ -570,10 +570,15 @@ fill_in_dwp_offsets_if_present(Dwarf_Debug dbg, return DW_DLV_OK; } +/* If returning DW_DLV_OK this will + push the cudie pointer back up through + local_cudie_return if local_cudie_return + is non-null. */ static int finish_cu_context_via_cudie_inner( Dwarf_Debug dbg, Dwarf_CU_Context cu_context, + Dwarf_Die *local_cudie_return, Dwarf_Error *error) { /* DW4: Look for DW_AT_dwo_id and @@ -587,7 +592,8 @@ finish_cu_context_via_cudie_inner( /* Must call the internal siblingof so we do not depend on the dbg...de_cu_context - used by and for dwarf_cu_header_* calls. */ + used by and for dwarf_cu_header_* calls. + Safe because we know the correct cu_context. */ resdwo = _dwarf_siblingof_internal(dbg,NULL, cu_context, cu_context->cc_is_info, @@ -601,8 +607,11 @@ finish_cu_context_via_cudie_inner( error); if (resdwob == DW_DLV_NO_ENTRY) { /* The CU die has no children */ - dwarf_dealloc_die(cudie); - cudie = 0; + if (local_cudie_return) { + *local_cudie_return = cudie; + } else { + dwarf_dealloc_die(cudie); + } cu_context->cc_cu_die_has_children = FALSE; return DW_DLV_OK; } @@ -616,7 +625,11 @@ finish_cu_context_via_cudie_inner( if (resdwob == DW_DLV_OK) { cu_context->cc_cu_die_tag = cutag; } - dwarf_dealloc_die(cudie); + if (local_cudie_return) { + *local_cudie_return = cudie; + } else { + dwarf_dealloc_die(cudie); + } return resdwob; } if (resdwo == DW_DLV_NO_ENTRY) { @@ -994,6 +1007,43 @@ dwarf_next_cu_header_d(Dwarf_Debug dbg, res = _dwarf_next_cu_header_internal(dbg, is_info, + NULL, + cu_header_length, + version_stamp, + abbrev_offset, + address_size, + offset_size, + extension_size, + signature, + &has_signature, + typeoffset, + next_cu_offset, + header_cu_type, + error); + return res; +} +int +dwarf_next_cu_header_e(Dwarf_Debug dbg, + Dwarf_Bool is_info, + Dwarf_Die * cu_die_out, + Dwarf_Unsigned * cu_header_length, + Dwarf_Half * version_stamp, + Dwarf_Unsigned * abbrev_offset, + Dwarf_Half * address_size, + Dwarf_Half * offset_size, + Dwarf_Half * extension_size, + Dwarf_Sig8 * signature, + Dwarf_Unsigned * typeoffset, + Dwarf_Unsigned * next_cu_offset, + Dwarf_Half * header_cu_type, + Dwarf_Error * error) +{ + Dwarf_Bool has_signature = FALSE; + int res = 0; + + res = _dwarf_next_cu_header_internal(dbg, + is_info, + cu_die_out, cu_header_length, version_stamp, abbrev_offset, @@ -1429,10 +1479,14 @@ assign_correct_unit_type(Dwarf_CU_Context cu_context) } } +/* If local_cudie_return non-null, and returning DW_DLV_OK, + then we return a valid CU_DIE through + local_cudie_return. */ static int finish_up_cu_context_from_cudie(Dwarf_Debug dbg, Dwarf_Unsigned offset, Dwarf_CU_Context cu_context, + Dwarf_Die *cudie_return, Dwarf_Error *error) { int version = cu_context->cc_version_stamp; @@ -1471,8 +1525,7 @@ finish_up_cu_context_from_cudie(Dwarf_Debug dbg, and even DW3 and DW4 and some non-std DW2 */ { res = finish_cu_context_via_cudie_inner(dbg, - cu_context, - error); + cu_context,cudie_return, error); if (res == DW_DLV_ERROR) { return res; } @@ -1582,6 +1635,9 @@ _dwarf_calculate_next_cu_context_offset(Dwarf_CU_Context cu_context) return next_cu_offset; } +/* If local_cudie_return non-null, and returning DW_DLV_OK, + then we return a valid CU_DIE through + local_cudie_return. */ int _dwarf_create_a_new_cu_context_record_on_list( Dwarf_Debug dbg, @@ -1590,6 +1646,7 @@ _dwarf_create_a_new_cu_context_record_on_list( Dwarf_Unsigned section_size, Dwarf_Unsigned new_cu_offset, Dwarf_CU_Context *context_out, + Dwarf_Die *cudie_return, Dwarf_Error *error) { int res = 0; @@ -1610,7 +1667,7 @@ _dwarf_create_a_new_cu_context_record_on_list( /* The called func does not dealloc cu_context in case of error, so we do it here. */ res = finish_up_cu_context_from_cudie(dbg,new_cu_offset, - cu_context,error); + cu_context,cudie_return,error); if (res == DW_DLV_ERROR) { local_dealloc_cu_context(dbg,cu_context); return res; @@ -1693,6 +1750,7 @@ _dwarf_load_die_containing_section(Dwarf_Debug dbg, int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, + Dwarf_Die *cu_die_out, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, @@ -1713,6 +1771,7 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, { /* Offset for current and new CU. */ Dwarf_Unsigned new_offset = 0; + Dwarf_Die local_cudie = 0; /* CU Context for current CU. */ Dwarf_CU_Context cu_context = 0; @@ -1724,13 +1783,7 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, /* ***** BEGIN CODE ***** */ - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: calling dwarf_next_cuheader_d() " - "Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_next_cuheader_[d,e]()"); if (is_info) { dis =&dbg->de_info_reading; dataptr = dbg->de_debug_info.dss_data; @@ -1748,73 +1801,6 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, return res; } } -#if 0 - /* Get offset into .debug_info of next CU. - If dbg has no context, - this has to be the first one. */ - if (!dis->de_cu_context) { - Dwarf_Small *dataptr = is_info? - dbg->de_debug_info.dss_data: - dbg->de_debug_types.dss_data; - new_offset = 0; - if (!dataptr) { - Dwarf_Error err2= 0; - int resd = is_info? - _dwarf_load_debug_info(dbg, &err2): - _dwarf_load_debug_types(dbg,&err2); - - if (resd != DW_DLV_OK) { - if (reloc_incomplete(resd,err2)) { - /* We will assume all is ok, though it is not. - Relocation errors need not be fatal. */ - char msg_buf[300]; - char *dwerrmsg = 0; - char *msgprefix = - "Relocations did not complete successfully, " - "but we are " " ignoring error: "; - size_t totallen = 0; - size_t prefixlen = 0; - - dwerrmsg = dwarf_errmsg(err2); - prefixlen = strlen(msgprefix); - totallen = prefixlen + strlen(dwerrmsg); - if ( totallen >= sizeof(msg_buf)) { - /* Impossible unless something corrupted. - Provide a shorter dwerrmsg*/ - const char * m= - "Error:corrupted dwarf message table!"); - _dwarf_safe_strcpy(msg_buf, - sizeof(msg_buf), - m,strlen(m)); - } else { - _dwarf_safe_strcpy,strcpy(msg_buf, - sizeof(msg_buf),msgprefix, - prefixlen); - _dwarf_safe_strcpy(msg_buf+prefixlen, - sizeof(msg_buf)-prefixlen, - dwerrmsg,strlen(dwerrmsg)); - } - dwarf_insert_harmless_error(dbg,msg_buf); - /* Fall thru to use the newly loaded section. - even though it might not be adequately - relocated. */ - if (resd == DW_DLV_ERROR) { - dwarf_dealloc_error(dbg,err2); - err2 = 0; - } - } else { - if (error) { - *error = err2; - err2 = 0; - } - /* There is nothing here, or - what is here is damaged. */ - return resd; - } - } - } - } -#endif /*0*/ if (!dis->de_cu_context) { /* We are leaving new_offset zero. We are at the start of a section. */ @@ -1847,16 +1833,21 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, if (!cu_context) { res = _dwarf_create_a_new_cu_context_record_on_list( dbg,dis,is_info,section_size,new_offset, - &cu_context,error); + &cu_context,&local_cudie,error); if (res != DW_DLV_OK) { + if (local_cudie) { + dwarf_dealloc_die(local_cudie); + } return res; } } /* Next assignment is what makes - _dwarf_next_cu_header*() + _dwarf_next_cu_header_d() with no offset presented work to march through all the CUs in order. Other places - creating a cu_context do not set de_cu_context. */ + creating a cu_context do not set de_cu_context. + if callers use dwarf_next_cu_header_e() this + is unimportant but not harmful. */ dis->de_cu_context = cu_context; if (cu_header_length) { *cu_header_length = cu_context->cc_length; @@ -1915,6 +1906,24 @@ _dwarf_next_cu_header_internal(Dwarf_Debug dbg, *error = 0; } } + if (cu_die_out) { + if (!local_cudie) { + /* This is safe since we know the + correct cu_context */ + res = _dwarf_siblingof_internal(dbg,NULL, + cu_context, is_info,&local_cudie,error); + if (res != DW_DLV_OK) { + return res; + } + *cu_die_out = local_cudie; + } else { + *cu_die_out = local_cudie; + } + } else { + if (local_cudie) { + dwarf_dealloc_die(local_cudie); + } + } return DW_DLV_OK; } @@ -1964,14 +1973,7 @@ dwarf_die_from_hash_signature(Dwarf_Debug dbg, Dwarf_Bool is_type_unit = FALSE; int sres = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: calling dwarf_die_from_hash_signature()" - "Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } - + CHECK_DBG(dbg,error,"dwarf_die_from_hash_signature()"); sres = _dwarf_load_debug_info(dbg,error); if (sres == DW_DLV_ERROR) { return sres; @@ -2480,22 +2482,100 @@ is_cu_tag(int t) we must be informed!. */ int dwarf_siblingof_b(Dwarf_Debug dbg, - Dwarf_Die die, - Dwarf_Bool is_info, + Dwarf_Die die, + Dwarf_Bool is_info, + Dwarf_Die *caller_ret_die, + Dwarf_Error *error) +{ + int res = 0; + Dwarf_CU_Context context = 0; + + CHECK_DBG(dbg,error,"dwarf_siblingof_b()"); + if (die) { + CHECK_DIE(die,DW_DLV_ERROR); + context = die->di_cu_context; + /* Ignore is_info passed-in, we have the correct + value in cu_context. */ + is_info = die->di_cu_context->cc_is_info; + } else { + /* This is the pre-0.9.0 way, and is assuming + that the 'dis' has the correct cu context. + Which might not be true if a caller + used dwarf_next_cu_header_d() twice in a + row before calling dwarf_siblingof_b(). + Use dwarf_next_cu_header_e() instead of + dwarf_next_cu_header_d() */ + context = is_info? dbg->de_info_reading.de_cu_context: + dbg->de_types_reading.de_cu_context; + } + res = _dwarf_siblingof_internal(dbg,die, + context, is_info,caller_ret_die,error); + return res; +} + +int +dwarf_siblingof_c(Dwarf_Die die, Dwarf_Die * caller_ret_die, Dwarf_Error * error) { int res = 0; - Dwarf_Debug_InfoTypes dis = 0; - - dis = is_info? &dbg->de_info_reading: - &dbg->de_types_reading; + Dwarf_Debug dbg = 0; + Dwarf_Bool is_info = FALSE; + CHECK_DIE(die,DW_DLV_ERROR); + dbg = die->di_cu_context->cc_dbg; + is_info = die->di_cu_context->cc_is_info; res = _dwarf_siblingof_internal(dbg,die, - die?die->di_cu_context:dis->de_cu_context, - is_info,caller_ret_die,error); + die->di_cu_context, is_info, + caller_ret_die,error); return res; } +static int +dw_start_load_root_die(Dwarf_Debug dbg, + Dwarf_CU_Context context, + Dwarf_Bool is_info, + Dwarf_Small *dataptr, + Dwarf_Byte_Ptr *die_info_ptr, + Dwarf_Byte_Ptr *die_info_end, + Dwarf_Error *error) +{ + /* Find root die of cu */ + /* die_info_end is untouched here, need not be set in this + branch. */ + Dwarf_Off off2 = 0; + Dwarf_Unsigned headerlen = 0; + Dwarf_Byte_Ptr cu_info_start = 0; + int cres = 0; + + /* If we've not loaded debug_info + context will be NULL. */ + if (!context) { + local_dealloc_cu_context(dbg,context); + _dwarf_error_string(dbg,error, + DW_DLE_DBG_NO_CU_CONTEXT, + "DW_DLE_DBG_NO_CU_CONTEXT:" + " Setting up a new CU failed loading root die"); + return DW_DLV_ERROR; + } + off2 = context->cc_debug_offset; + cu_info_start = dataptr + off2; + cres = _dwarf_length_of_cu_header(dbg, off2,is_info, + &headerlen,error); + if (cres != DW_DLV_OK) { + return cres; + } + *die_info_ptr = cu_info_start + headerlen; + *die_info_end = _dwarf_calculate_info_section_end_ptr(context); + + /* Recording the CU die pointer so we can later access + for special FORMs relating to .debug_str_offsets + and .debug_addr */ + context->cc_cu_die_offset_present = TRUE; + context->cc_cu_die_global_sec_offset = off2 + headerlen; + + return DW_DLV_OK; +} + static int _dwarf_siblingof_internal(Dwarf_Debug dbg, Dwarf_Die die, @@ -2517,7 +2597,7 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, /* Since die may be NULL, we rely on the input argument. */ Dwarf_Small *dataptr = 0; - if (dbg == NULL) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error(NULL, error, DW_DLE_DBG_NULL); return DW_DLV_ERROR; } @@ -2526,35 +2606,12 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, if (!dataptr) { return DW_DLV_NO_ENTRY; } - if (die == NULL) { - /* Find root die of cu */ - /* die_info_end is untouched here, need not be set in this - branch. */ - Dwarf_Off off2 = 0; - Dwarf_Unsigned headerlen = 0; - int cres = 0; - - /* If we've not loaded debug_info - context will be NULL. */ - if (!context) { - local_dealloc_cu_context(dbg,context); - return DW_DLV_ERROR; + if (!die) { + dieres = dw_start_load_root_die(dbg,context,is_info, + dataptr,&die_info_ptr,&die_info_end,error); + if (dieres != DW_DLV_OK) { + return dieres; } - off2 = context->cc_debug_offset; - cu_info_start = dataptr + off2; - cres = _dwarf_length_of_cu_header(dbg, off2,is_info, - &headerlen,error); - if (cres != DW_DLV_OK) { - return cres; - } - die_info_ptr = cu_info_start + headerlen; - die_info_end = _dwarf_calculate_info_section_end_ptr(context); - - /* Recording the CU die pointer so we can later access - for special FORMs relating to .debug_str_offsets - and .debug_addr */ - context->cc_cu_die_offset_present = TRUE; - context->cc_cu_die_global_sec_offset = off2 + headerlen; } else { /* Find sibling die. */ Dwarf_Bool has_child = false; @@ -2718,6 +2775,11 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, return DW_DLV_NO_ENTRY; } if ((*die_info_ptr) == 0) { + /* We are not at the end of the section, but a + valid DIE will not start with a zero byte. + We will just assume it is a padding byte and is + not an error. An error report will appear + later if actually reading DIEs*/ return DW_DLV_NO_ENTRY; } ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); @@ -2730,7 +2792,6 @@ _dwarf_siblingof_internal(Dwarf_Debug dbg, ret_die->di_debug_ptr = die_info_ptr; ret_die->di_cu_context = die == NULL ? context : die->di_cu_context; - dieres = _dwarf_leb128_uword_wrapper(dbg, &die_info_ptr,die_info_end,&utmp,error); if (dieres == DW_DLV_ERROR) { @@ -2987,12 +3048,7 @@ dwarf_offdie_b(Dwarf_Debug dbg, Dwarf_Unsigned highest_code = 0; struct Dwarf_Section_s * secdp = 0; - if (dbg == NULL) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: " - "in call to dwarf_offdie_b()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_offdie_b()"); if (is_info) { dis =&dbg->de_info_reading; secdp = &dbg->de_debug_info; @@ -3021,9 +3077,12 @@ dwarf_offdie_b(Dwarf_Debug dbg, a fresh section setup. */ section_size = secdp->dss_size; do { + /* We do not want this to return cu_die as + we only want the last one to create DIE, + and that will be done just below. */ lres = _dwarf_create_a_new_cu_context_record_on_list( dbg, dis,is_info,section_size,new_cu_offset, - &cu_context,error); + &cu_context,NULL,error); if (lres != DW_DLV_OK) { return lres; } @@ -3158,10 +3217,17 @@ dwarf_get_real_section_name(Dwarf_Debug dbg, Dwarf_Error *error) { unsigned i = 0; - char tbuf[100]; - size_t std_sec_name_len = strlen(std_section_name); + char tbuf[100] = {0}; + size_t std_sec_name_len = 0; - tbuf[0] = 0; + CHECK_DBG(dbg,error,"dwarf_get_real_section_name()"); + if (!std_section_name || 0 == std_section_name[0]) { + _dwarf_error_string(dbg,error,DW_DLE_SECTION_NAME_BIG, + "DW_DLE_SECTION_NAME_BIG: Actually the " + "section name is empty, not big."); + return DW_DLV_ERROR; + } + std_sec_name_len = strlen(std_section_name); /* std_section_name never has the .dwo on the end, so allow for that and allow one (arbitrarily) more. */ if ((std_sec_name_len + 5) < sizeof(tbuf)) { @@ -3171,10 +3237,6 @@ dwarf_get_real_section_name(Dwarf_Debug dbg, sizeof(tbuf)-std_sec_name_len, ".dwo",4); } - if (dbg == NULL) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } for (i=0; i < dbg->de_debug_sections_total_entries; i++) { struct Dwarf_dbg_sect_s *sdata = &dbg->de_debug_sections[i]; struct Dwarf_Section_s *section = sdata->ds_secdata; @@ -3228,10 +3290,7 @@ dwarf_get_die_section_name(Dwarf_Debug dbg, { struct Dwarf_Section_s *sec = 0; - if (dbg == NULL) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_die_section_name()"); if (is_info) { sec = &dbg->de_debug_info; } else { diff --git a/src/lib/libdwarf/dwarf_dsc.c b/src/lib/libdwarf/dwarf_dsc.c index 286c77b..cbd12ed 100644 --- a/src/lib/libdwarf/dwarf_dsc.c +++ b/src/lib/libdwarf/dwarf_dsc.c @@ -175,10 +175,7 @@ int dwarf_discr_list(Dwarf_Debug dbg, Dwarf_Small * dscblockp = 0; Dwarf_Unsigned dscblocklen = 0; - if (!dbg){ - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); \ - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_discr_list()"); if (blocklen == 0) { return DW_DLV_NO_ENTRY; } diff --git a/src/lib/libdwarf/dwarf_elf_load_headers.c b/src/lib/libdwarf/dwarf_elf_load_headers.c index 6c1cdfe..97273e0 100644 --- a/src/lib/libdwarf/dwarf_elf_load_headers.c +++ b/src/lib/libdwarf/dwarf_elf_load_headers.c @@ -1786,7 +1786,10 @@ elf_load_elf_header32( res = generic_ehdr_from_32(ep,ehdr,&ehdr32,errcode); if (res != DW_DLV_OK) { free(ehdr); + return res; } + ep->f_machine = ehdr->ge_machine; + ep->f_flags = ehdr->ge_flags; return res; } static int @@ -1812,7 +1815,10 @@ elf_load_elf_header64( res = generic_ehdr_from_64(ep,ehdr,&ehdr64,errcode); if (res != DW_DLV_OK) { free(ehdr); + return res; } + ep->f_machine = ehdr->ge_machine; + ep->f_flags = ehdr->ge_flags; return res; } diff --git a/src/lib/libdwarf/dwarf_elfread.c b/src/lib/libdwarf/dwarf_elfread.c index a5c3101..6ed6730 100644 --- a/src/lib/libdwarf/dwarf_elfread.c +++ b/src/lib/libdwarf/dwarf_elfread.c @@ -618,6 +618,8 @@ _dwarf_elf_nlsetup(int fd, } intfc = binary_interface->ai_object; intfc->f_path = strdup(true_path); + (*dbg)->de_obj_machine = intfc->f_machine; + (*dbg)->de_obj_flags = intfc->f_flags; return res; } diff --git a/src/lib/libdwarf/dwarf_elfread.h b/src/lib/libdwarf/dwarf_elfread.h index fa25d56..a7eb04c 100644 --- a/src/lib/libdwarf/dwarf_elfread.h +++ b/src/lib/libdwarf/dwarf_elfread.h @@ -186,10 +186,12 @@ typedef struct elf_filedata_s { int f_is_64bit; unsigned f_endian; Dwarf_Unsigned f_filesize; + Dwarf_Unsigned f_flags; /* Elf size, not DWARF. 32 or 64 */ Dwarf_Small f_offsetsize; Dwarf_Small f_pointersize; int f_ftype; + int f_path_source; Dwarf_Unsigned f_max_secdata_offset; Dwarf_Unsigned f_max_progdata_offset; diff --git a/src/lib/libdwarf/dwarf_error.c b/src/lib/libdwarf/dwarf_error.c index c961de6..e497066 100644 --- a/src/lib/libdwarf/dwarf_error.c +++ b/src/lib/libdwarf/dwarf_error.c @@ -42,6 +42,7 @@ #include "libdwarf_private.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" +#include "dwarf_util.h" #include "dwarf_alloc.h" #include "dwarf_string.h" #include "dwarf_error.h" @@ -84,7 +85,8 @@ dwarf_error_creation(Dwarf_Debug dbg, char *errmsg) { dwarfstring m; - if (!dbg) { + + if (IS_INVALID_DBG(dbg)) { return; } dwarfstring_constructor(&m); diff --git a/src/lib/libdwarf/dwarf_find_sigref.c b/src/lib/libdwarf/dwarf_find_sigref.c index 45e5739..aea5568 100644 --- a/src/lib/libdwarf/dwarf_find_sigref.c +++ b/src/lib/libdwarf/dwarf_find_sigref.c @@ -146,7 +146,7 @@ _dwarf_find_CU_Context_given_sig(Dwarf_Debug dbg, #endif /*0*/ lres = _dwarf_create_a_new_cu_context_record_on_list( dbg, dis,is_info,section_size,new_cu_offset, - &cu_context,error); + &cu_context,NULL,error); if (lres == DW_DLV_ERROR) { return lres; } @@ -183,6 +183,7 @@ dwarf_find_die_given_sig8(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; + CHECK_DBG(dbg,error,"dwarf_find_die_given_sig8()"); res = _dwarf_internal_find_die_given_sig8( dbg,0,ref,die_out,is_info,error); return res; diff --git a/src/lib/libdwarf/dwarf_form.c b/src/lib/libdwarf/dwarf_form.c index 6093147..1ac028d 100644 --- a/src/lib/libdwarf/dwarf_form.c +++ b/src/lib/libdwarf/dwarf_form.c @@ -119,7 +119,7 @@ get_attr_dbg(Dwarf_Debug *dbg_out, return DW_DLV_ERROR; } dbg = cup->cc_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_ATTR_DBG_NULL, "DW_DLE_ATTR_DBG_NULL: Stale or null Dwarf_Debug" "in a Dwarf_CU_Context" ); @@ -210,6 +210,7 @@ dwarf_uncompress_integer_block_a(Dwarf_Debug dbg, Dwarf_Byte_Ptr endptr = (Dwarf_Byte_Ptr)input_block+ input_length_in_bytes; + CHECK_DBG(dbg,error,"dwarf_uncompress_integer_block_a()"); output_length_in_units = 0; remain = (Dwarf_Signed)input_length_in_bytes; ptr = input_block; @@ -1321,7 +1322,7 @@ dwarf_formflag(Dwarf_Attribute attr, return DW_DLV_ERROR; } dbg = cu_context->cc_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_ATTR_DBG_NULL, "DW_DLE_ATTR_DBG_NULL: dwarf_formflag() attribute" " passed in has NULL or stale Dwarf_Debug pointer"); diff --git a/src/lib/libdwarf/dwarf_frame.c b/src/lib/libdwarf/dwarf_frame.c index 042b498..e1bd26f 100644 --- a/src/lib/libdwarf/dwarf_frame.c +++ b/src/lib/libdwarf/dwarf_frame.c @@ -59,6 +59,7 @@ /* Dwarf_Unsigned is always 64 bits */ #define INVALIDUNSIGNED(x) ((x) & (((Dwarf_Unsigned)1) << 63)) +/* Simply assumes error is a Dwarf_Error * in its context */ #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \ do { \ if ((fde) == NULL) { \ @@ -66,16 +67,13 @@ return DW_DLV_ERROR; \ } \ (dbg)= (fde)->fd_dbg; \ - if ((dbg) == NULL) { \ + if (IS_INVALID_DBG((dbg))) { \ _dwarf_error_string(NULL, error, DW_DLE_FDE_DBG_NULL,\ "DW_DLE_FDE_DBG_NULL: An fde contains a stale "\ "Dwarf_Debug "); \ return DW_DLV_ERROR; \ } \ - if ((dbg)->de_magic != DBG_IS_VALID) { \ - _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\ - return DW_DLV_ERROR; \ - } } while (0) + } while (0) #define MIN(a,b) (((a) < (b))? (a):(b)) @@ -182,6 +180,8 @@ dwarf_get_frame_section_name(Dwarf_Debug dbg, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; + + CHECK_DBG(dbg,error,"dwarf_get_frame_section_name()"); if (error != NULL) { *error = NULL; } @@ -200,6 +200,8 @@ dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg, Dwarf_Error *error) { struct Dwarf_Section_s *sec = 0; + + CHECK_DBG(dbg,error,"dwarf_get_frame_section_name_eh_gnu()"); if (error != NULL) { *error = NULL; } @@ -1978,12 +1980,8 @@ dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Error * error) { int res = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + + CHECK_DBG(dbg,error,"dwarf_get_fde_list_eh()"); res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error); if (res != DW_DLV_OK) { @@ -2018,13 +2016,7 @@ dwarf_get_fde_list(Dwarf_Debug dbg, { int res = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: dwarf_get_fde_list: " - "Either null Dwarf_Debug or it is" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_fde_list()"); res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error); if (res != DW_DLV_OK) { return res; @@ -2074,13 +2066,7 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg, struct cie_fde_prefix_s prefix; struct cie_fde_prefix_s prefix_c; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: in dwarf_get_fde_for_die(): " - "Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_fde_for_die()"); if (!die ) { _dwarf_error_string(NULL, error, DW_DLE_DIE_NULL, "DW_DLE_DIE_NUL: in dwarf_get_fde_for_die(): " @@ -2254,11 +2240,7 @@ dwarf_get_fde_range(Dwarf_Fde fde, } dbg = fde->fd_dbg; - if (dbg == NULL) { - _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); - return DW_DLV_ERROR; - } - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_FDE_DBG_NULL, "DW_DLE_FDE_DBG_NULL: Either null or it contains" "a stale Dwarf_Debug pointer"); @@ -2298,7 +2280,7 @@ dwarf_get_fde_exception_info(Dwarf_Fde fde, Dwarf_Debug dbg; dbg = fde->fd_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_FDE_DBG_NULL, "DW_DLE_FDE_DBG_NULL: Either null or it contains" "a stale Dwarf_Debug pointer"); @@ -2335,7 +2317,7 @@ dwarf_get_cie_info_b(Dwarf_Cie cie, return DW_DLV_ERROR; } dbg = cie->ci_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_CIE_DBG_NULL, "DW_DLE_CIE_DBG_NULL: Either null or it contains" "a stale Dwarf_Debug pointer"); @@ -2388,7 +2370,7 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, } dbg = fde->fd_dbg; - if (dbg == NULL) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); return DW_DLV_ERROR; } @@ -2472,10 +2454,12 @@ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, } int -dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, +dwarf_get_fde_info_for_all_regs3_b(Dwarf_Fde fde, Dwarf_Addr pc_requested, Dwarf_Regtable3 * reg_table, Dwarf_Addr * row_pc, + Dwarf_Bool * has_more_rows, + Dwarf_Addr * subsequent_pc, Dwarf_Error * error) { @@ -2522,7 +2506,7 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, dbg->de_frame_cfa_col_number, - NULL,NULL, + has_more_rows,subsequent_pc, error); if (res != DW_DLV_OK) { free(reg_table_i.rt3_rules); @@ -2587,6 +2571,19 @@ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, return DW_DLV_OK; } +int +dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, + Dwarf_Addr pc_requested, + Dwarf_Regtable3 * reg_table, + Dwarf_Addr * row_pc, + Dwarf_Error * error) +{ + int res = dwarf_get_fde_info_for_all_regs3_b(fde,pc_requested, + reg_table,row_pc,NULL,NULL,error); + + return res; +} + /* Table_column DW_FRAME_CFA_COL is not meaningful. Use dwarf_get_fde_info_for_cfa_reg3_b() to get the CFA. Call dwarf_set_frame_cfa_value() to set the correct column @@ -2659,7 +2656,7 @@ dwarf_get_fde_info_for_reg3_c(Dwarf_Fde fde, int res = DW_DLV_ERROR; Dwarf_Debug dbg = 0; - int table_real_data_size = 0; + Dwarf_Unsigned table_real_data_size = 0; FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg); @@ -2835,7 +2832,7 @@ dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, return DW_DLV_ERROR; } dbg = inFde->fd_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_FDE_DBG_NULL, "DW_DLE_FDE_DBG_NULL: Either null or it contains" "a stale Dwarf_Debug pointer"); @@ -3100,7 +3097,6 @@ dwarf_get_frame_instruction_a(Dwarf_Frame_Instr_Head head, The dwarf_ version is preferred over the obsolete _dwarf version. _dwarf version kept for compatibility. */ -/* ARGSUSED 4 */ int _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, Dwarf_Off * fde_off, Dwarf_Off * cie_off, @@ -3109,7 +3105,6 @@ _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, return dwarf_fde_section_offset(dbg,in_fde,fde_off, cie_off,error); } -/* ARGSUSED 4 */ int dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, Dwarf_Off * fde_off, Dwarf_Off * cie_off, @@ -3118,6 +3113,7 @@ dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, char *start = 0; char *loc = 0; + CHECK_DBG(dbg,error,"dwarf_fde_section_offset()"); if (!in_fde) { _dwarf_error(dbg, error, DW_DLE_FDE_NULL); return DW_DLV_ERROR; @@ -3135,14 +3131,13 @@ dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, The dwarf_ version is preferred over the obsolete _dwarf version. _dwarf version kept for compatibility. */ -/* ARGSUSED 4 */ int _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, Dwarf_Off * cie_off, Dwarf_Error * error) { return dwarf_cie_section_offset(dbg,in_cie,cie_off,error); } -/* ARGSUSED 4 */ + int dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, Dwarf_Off * cie_off, Dwarf_Error * error) @@ -3150,6 +3145,7 @@ dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, char *start = 0; char *loc = 0; + CHECK_DBG(dbg,error,"dwarf_cie_section_offset()"); if (!in_cie) { _dwarf_error(dbg, error, DW_DLE_CIE_NULL); return DW_DLV_ERROR; @@ -3405,7 +3401,7 @@ _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame) { struct Dwarf_Frame_s *fp = frame; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return DW_DLV_ERROR; } return init_reg_rules_alloc(dbg,fp, diff --git a/src/lib/libdwarf/dwarf_gdbindex.c b/src/lib/libdwarf/dwarf_gdbindex.c index 46b0566..10be55a 100644 --- a/src/lib/libdwarf/dwarf_gdbindex.c +++ b/src/lib/libdwarf/dwarf_gdbindex.c @@ -183,14 +183,7 @@ dwarf_gdbindex_header(Dwarf_Debug dbg, Dwarf_Small *startdata = 0; Dwarf_Unsigned version_in = 0; - if (!dbg) { - _dwarf_error_string(NULL, error, - DW_DLE_GDB_INDEX_INDEX_ERROR, - "DW_DLE_GDB_INDEX_INDEX_ERROR:" - " passed in NULL Dwarf_Debut to" - " dwarf_gdbindex_header"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_gdbindex_header()"); if (!dbg->de_debug_gdbindex.dss_size) { return DW_DLV_NO_ENTRY; } @@ -805,7 +798,7 @@ dwarf_gdbindex_string_by_offset(Dwarf_Gdbindex gdbindexptr, return DW_DLV_ERROR; } dbg = gdbindexptr->gi_dbg; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { emit_no_value_msg(NULL,DW_DLE_GDB_INDEX_INDEX_ERROR, "DW_DLE_GDB_INDEX_INDEX_ERROR: " "The gdbindex Dwarf_Debug in" diff --git a/src/lib/libdwarf/dwarf_generic_init.c b/src/lib/libdwarf/dwarf_generic_init.c index 1a24aef..f321d4e 100644 --- a/src/lib/libdwarf/dwarf_generic_init.c +++ b/src/lib/libdwarf/dwarf_generic_init.c @@ -85,6 +85,7 @@ dwarf_init_path_dl(path true_path and globals, dbg1 #include "libdwarf.h" #include "libdwarf_private.h" #include "dwarf_base_types.h" +#include "dwarf_util.h" #include "dwarf_opaque.h" #include "dwarf_alloc.h" #include "dwarf_error.h" @@ -223,6 +224,27 @@ dwarf_init_path_dl(const char *path, dl_path_count,path_source,error); return res; } + +#if 0 +/* for debugging */ +static void +dump_header_fields(const char *w,Dwarf_Debug dbg) +{ + printf("dadebug dumping certain fields of %s\n",w); + printf("ftype : %d\n",dbg->de_ftype); + printf("machine : %llu\n",dbg->de_obj_machine); + printf("flags : 0x%llx\n",dbg->de_obj_flags); + printf("pointer size : %u\n",dbg->de_pointer_size); + printf("big_endian? : %u\n",dbg->de_big_endian_object); + printf("ubcount : %u\n",dbg->de_universalbinary_count); + printf("ubindex : %u\n",dbg->de_universalbinary_index); + printf("ub offset : %llu\n",dbg->de_obj_ub_offset); + printf("path source : %u\n",dbg->de_path_source); + printf("comdat group# : %u\n",dbg->de_groupnumber); + exit(0); +} +#endif + int dwarf_init_path_dl_a(const char *path, char * true_path_out_buffer, @@ -343,6 +365,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); + dbg->de_ftype = ftype; *ret_dbg = dbg; return res; } @@ -359,6 +382,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); + dbg->de_ftype = ftype; *ret_dbg = dbg; return res; } @@ -373,6 +397,7 @@ dwarf_init_path_dl_a(const char *path, } final_common_settings(dbg,file_path,fd, lpath_source,path_source,error); + dbg->de_ftype = ftype; *ret_dbg = dbg; return res; } @@ -479,7 +504,7 @@ dwarf_init_b(int fd, int dwarf_finish(Dwarf_Debug dbg) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { _dwarf_free_static_errlist(); return DW_DLV_OK; } @@ -536,9 +561,8 @@ dwarf_set_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug tieddbg, Dwarf_Error*error) { - if (!dbg) { - DWARF_DBG_ERROR(NULL, DW_DLE_DBG_NULL, DW_DLV_ERROR); - } + CHECK_DBG(dbg,error,"dwarf_set_tied_dbg()"); + dbg->de_tied_data.td_tied_object = tieddbg; if (tieddbg) { tieddbg->de_tied_data.td_is_tied_object = TRUE; @@ -551,7 +575,7 @@ int dwarf_get_tied_dbg(Dwarf_Debug dbg, Dwarf_Debug *tieddbg_out, Dwarf_Error*error) { - (void)error; + CHECK_DBG(dbg,error,"dwarf_get_tied_dbg()"); *tieddbg_out = dbg->de_tied_data.td_tied_object; return DW_DLV_OK; } diff --git a/src/lib/libdwarf/dwarf_global.c b/src/lib/libdwarf/dwarf_global.c index 1c1c66f..b559740 100644 --- a/src/lib/libdwarf/dwarf_global.c +++ b/src/lib/libdwarf/dwarf_global.c @@ -647,7 +647,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, a few lines above. */ Dwarf_Unsigned context_count = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: " "calling for pubnames-like data Dwarf_Debug " @@ -714,6 +714,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return DW_DLV_ERROR; } @@ -726,6 +727,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return mres; } @@ -745,6 +747,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return DW_DLV_ERROR; } @@ -778,6 +781,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return DW_DLV_ERROR; } @@ -789,6 +793,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return mres; } @@ -801,6 +806,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } _dwarf_error(dbg, error, version_err_num); return DW_DLV_ERROR; @@ -817,6 +823,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return DW_DLV_ERROR; } @@ -830,6 +837,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return mres; } @@ -850,6 +858,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return mres; } @@ -861,6 +870,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; @@ -878,6 +888,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } return mres; } @@ -890,6 +901,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, *out_phead_chain = 0; if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } _dwarf_error(dbg, error, length_err_num); return DW_DLV_ERROR; @@ -927,6 +939,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return res; } @@ -935,7 +948,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, /* The section is empty. Nowhere to record pubnames_context); */ dwarf_dealloc(dbg,pubnames_context,context_DLA_code); - pubnames_context = 0; + /* pubnames_context = 0; reset at top of loop */ continue; } } @@ -958,6 +971,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return res; } @@ -983,6 +997,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return res; } @@ -1000,6 +1015,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } return DW_DLV_ERROR; } @@ -1014,6 +1030,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context, context_DLA_code); + pubnames_context = 0; } dealloc_globals_chain(dbg,*out_phead_chain); *out_phead_chain = 0; @@ -1045,6 +1062,7 @@ _dwarf_internal_get_pubnames_like(Dwarf_Debug dbg, _dwarf_error(dbg, error, length_err_num); if (!pubnames_context_on_list) { dwarf_dealloc(dbg,pubnames_context,context_DLA_code); + pubnames_context = 0; } dealloc_globals_chain(dbg,*out_phead_chain); *out_phead_chain = 0; @@ -1136,6 +1154,7 @@ dwarf_globals_by_type(Dwarf_Debug dbg, segfault! */ *contents = 0; *ret_count = 0; + CHECK_DBG(dbg,error,"dwarf_globals_by_type()"); switch(requested_section){ case DW_GL_GLOBALS: section = &dbg->de_debug_pubnames; @@ -1237,6 +1256,8 @@ dwarf_get_globals(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; + + CHECK_DBG(dbg,error,"dwarf_get_globals()"); res = dwarf_globals_by_type(dbg, DW_GL_GLOBALS,ret_globals,return_count,error); return res; @@ -1254,6 +1275,7 @@ dwarf_get_pubtypes(Dwarf_Debug dbg, Dwarf_Error *error) { int res = 0; + CHECK_DBG(dbg,error,"dwarf_get_pubtypes()"); res = dwarf_globals_by_type(dbg, DW_GL_PUBTYPES,types,return_count,error); return res; @@ -1280,6 +1302,9 @@ _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, struct Dwarf_Global_Context_s *glcp = 0; struct Dwarf_Global_Context_s *lastglcp = 0; + if (IS_INVALID_DBG(dbg)) { + return; + } if (!dwgl) { return; } @@ -1363,7 +1388,9 @@ dwarf_global_cu_offset(Dwarf_Global global, } con = global->gl_context; if (con == NULL) { - _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + _dwarf_error_string(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL, + "DW_DLE_GLOBAL_CONTEXT_NULL in call of " + "dwarf_global_cu_offset()"); return DW_DLV_ERROR; } *cu_header_offset = con->pu_offset_of_cu_header; @@ -1422,7 +1449,9 @@ dwarf_global_name_offsets(Dwarf_Global global, con = global->gl_context; if (con == NULL) { - _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); + _dwarf_error_string(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL, + "DW_DLE_GLOBAL_CONTEXT_NULL in call of " + "dwarf_global_name_offsets()"); return DW_DLV_ERROR; } @@ -1437,12 +1466,7 @@ dwarf_global_name_offsets(Dwarf_Global global, with 2 million pubnames entries. */ #define MIN_CU_HDR_SIZE 10 dbg = con->pu_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_global_name_offsets()"); /* Cannot refer to debug_types, see p141 of DWARF4 Standard */ if (dbg->de_debug_info.dss_size && @@ -1544,14 +1568,7 @@ dwarf_get_globals_header(Dwarf_Global global, return DW_DLV_ERROR; } dbg = con->pu_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: " - "calling dwarf_get_globals_header() " - "either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_globals_header()"); if (category) { *category = con->pu_global_category; } @@ -1609,7 +1626,7 @@ dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, Dwarf_Off headerlen = 0; int cres = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: " "calling dwarf_get_cu_die_offset_given" @@ -1652,9 +1669,11 @@ dwarf_CU_dieoffset_given_die(Dwarf_Die die, return DW_DLV_OK; } -int dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag) +/* Just sets a flag in dbg record if it can. */ +int +dwarf_return_empty_pubnames(Dwarf_Debug dbg, int flag) { - if (dbg == NULL) { + if (IS_INVALID_DBG(dbg)) { return DW_DLV_OK; } if (flag && flag != 1) { diff --git a/src/lib/libdwarf/dwarf_gnu_index.c b/src/lib/libdwarf/dwarf_gnu_index.c index 4c29b36..03ba228 100644 --- a/src/lib/libdwarf/dwarf_gnu_index.c +++ b/src/lib/libdwarf/dwarf_gnu_index.c @@ -138,7 +138,7 @@ get_pubxx_fields(Dwarf_Debug dbg, int *errnum_out, const char **errstr_out) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return; } if (for_gnu_pubnames) { @@ -569,12 +569,7 @@ dwarf_get_gnu_index_head(Dwarf_Debug dbg, struct Dwarf_Gnu_IBlock_s *iblock_array = 0; int res = 0; - if (!dbg) { - _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: in " - "dwarf_get_gnu_index_head"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_gnu_index_head()"); res = load_pub_section(dbg,for_gnu_pubnames,error); if (res != DW_DLV_OK) { return res; @@ -661,12 +656,12 @@ _dwarf_free_gnu_index_head_content(Dwarf_Gnu_Index_Head head) void dwarf_gnu_index_dealloc(Dwarf_Gnu_Index_Head head) { - Dwarf_Debug dbg; + Dwarf_Debug dbg = 0; if (!head) { return; } dbg = head->gi_dbg; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return; } _dwarf_free_gnu_index_head_content(head); diff --git a/src/lib/libdwarf/dwarf_groups.c b/src/lib/libdwarf/dwarf_groups.c index ff2737c..2e33e12 100644 --- a/src/lib/libdwarf/dwarf_groups.c +++ b/src/lib/libdwarf/dwarf_groups.c @@ -44,6 +44,7 @@ #include "libdwarf_private.h" #include "dwarf_base_types.h" #include "dwarf_opaque.h" +#include "dwarf_util.h" #include "dwarf_error.h" #include "dwarf_tsearch.h" @@ -186,16 +187,18 @@ _dwarf_section_get_target_group_from_map(Dwarf_Debug dbg, /* New May 2017. So users can find out what groups (dwo or COMDAT) are in the object and how much to allocate so one can get the group-section map data. */ -int dwarf_sec_group_sizes(Dwarf_Debug dbg, +int +dwarf_sec_group_sizes(Dwarf_Debug dbg, Dwarf_Unsigned * section_count_out, Dwarf_Unsigned * group_count_out, Dwarf_Unsigned * selected_group_out, Dwarf_Unsigned * map_entry_count_out, Dwarf_Error * error) { - struct Dwarf_Group_Data_s *grp = &dbg->de_groupnumbers; + struct Dwarf_Group_Data_s *grp = 0; - (void)error; + CHECK_DBG(dbg,error,"dwarf_sec_group_sizes()"); + grp = &dbg->de_groupnumbers; *section_count_out = grp->gd_number_of_sections; *group_count_out = grp->gd_number_of_groups; *selected_group_out = dbg->de_groupnumber; @@ -258,7 +261,8 @@ map_sort_compar(const void*l, const void*r) values and this function fills in the array entries. Output ordered by group number and section number. */ -int dwarf_sec_group_map(Dwarf_Debug dbg, +int +dwarf_sec_group_map(Dwarf_Debug dbg, Dwarf_Unsigned map_entry_count, Dwarf_Unsigned * group_numbers_array, Dwarf_Unsigned * sec_numbers_array, @@ -268,6 +272,7 @@ int dwarf_sec_group_map(Dwarf_Debug dbg, Dwarf_Unsigned i = 0; struct Dwarf_Group_Data_s *grp = 0; + CHECK_DBG(dbg,error,"dwarf_sec_group_map()"); if (temp_map_data) { _dwarf_error(dbg,error,DW_DLE_GROUP_INTERNAL_ERROR); return DW_DLV_ERROR; diff --git a/src/lib/libdwarf/dwarf_harmless.c b/src/lib/libdwarf/dwarf_harmless.c index 803e9a8..69079f0 100644 --- a/src/lib/libdwarf/dwarf_harmless.c +++ b/src/lib/libdwarf/dwarf_harmless.c @@ -67,6 +67,7 @@ #include "dwarf_base_types.h" #include "dwarf_safe_strcpy.h" #include "dwarf_opaque.h" +#include "dwarf_util.h" #include "dwarf_frame.h" #include "dwarf_harmless.h" @@ -76,12 +77,19 @@ /* The pointers returned here through errmsg_ptrs_array become invalidated by any call to libdwarf. Any call. */ -int dwarf_get_harmless_error_list(Dwarf_Debug dbg, +int +dwarf_get_harmless_error_list(Dwarf_Debug dbg, unsigned count, const char ** errmsg_ptrs_array, unsigned * errs_count) { - struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; + + struct Dwarf_Harmless_s *dhp = 0; + + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } + dhp = &dbg->de_harmless_errors; if (!dhp->dh_errors) { dhp->dh_errs_count = 0; return DW_DLV_NO_ENTRY; @@ -120,13 +128,20 @@ int dwarf_get_harmless_error_list(Dwarf_Debug dbg, /* Insertion made public is only for testing the harmless error code, it is not necessarily useful for libdwarf client code aside from code testing libdwarf. */ -void dwarf_insert_harmless_error(Dwarf_Debug dbg, +void +dwarf_insert_harmless_error(Dwarf_Debug dbg, char *newerror) { - struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; + struct Dwarf_Harmless_s *dhp = 0; unsigned next = 0; - unsigned cur = dhp->dh_next_to_use; - char *msgspace; + unsigned cur = 0; + char *msgspace = 0; + + if (IS_INVALID_DBG(dbg)) { + return; + } + dhp = &dbg->de_harmless_errors; + cur = dhp->dh_next_to_use; if (!dhp->dh_errors) { dhp->dh_errs_count++; return; @@ -155,11 +170,18 @@ void dwarf_insert_harmless_error(Dwarf_Debug dbg, Remember the maxcount we record is 1 > the user count, so we adjust it so it looks like the user count. */ -unsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, +unsigned +dwarf_set_harmless_error_list_size(Dwarf_Debug dbg, unsigned maxcount ) { - struct Dwarf_Harmless_s *dhp = &dbg->de_harmless_errors; - unsigned prevcount = dhp->dh_maxcount; + struct Dwarf_Harmless_s *dhp = 0; + unsigned prevcount = 0; + + if (IS_INVALID_DBG(dbg)) { + return 0; + } + dhp = &dbg->de_harmless_errors; + prevcount = dhp->dh_maxcount; if (maxcount != 0) { ++maxcount; if (maxcount != dhp->dh_maxcount) { diff --git a/src/lib/libdwarf/dwarf_init_finish.c b/src/lib/libdwarf/dwarf_init_finish.c index 86ea80a..5976da8 100644 --- a/src/lib/libdwarf/dwarf_init_finish.c +++ b/src/lib/libdwarf/dwarf_init_finish.c @@ -1,7 +1,7 @@ /* Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved. - Portions Copyright (C) 2009-2022 David Anderson. All Rights Reserved. + Portions Copyright (C) 2009-2023 David Anderson. All Rights Reserved. Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved. This program is free software; you can redistribute it @@ -53,10 +53,8 @@ #include "dwarf_secname_ck.h" #include "dwarf_setup_sections.h" -#ifdef HAVE_ZLIB_H +#if defined(HAVE_ZLIB_H) && defined(HAVE_ZSTD_H) #include "zlib.h" -#endif -#ifdef HAVE_ZSTD_H #include "zstd.h" #endif @@ -713,7 +711,6 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) dbg->de_assume_string_in_bounds = _dwarf_assume_string_in_bounds; /* First make an arbitrary assumption. */ - dbg->de_same_endian = 1; dbg->de_copy_word = _dwarf_memcpy_noswap_bytes; obj = dbg->de_obj_file; endianness = obj->ai_methods->om_get_byte_order(obj->ai_object); @@ -721,14 +718,12 @@ _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error) #ifdef WORDS_BIGENDIAN dbg->de_big_endian_object = 1; if (endianness == DW_END_little) { - dbg->de_same_endian = 0; dbg->de_big_endian_object = 0; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } #else /* little endian */ dbg->de_big_endian_object = 0; if (endianness == DW_END_big ) { - dbg->de_same_endian = 0; dbg->de_big_endian_object = 1; dbg->de_copy_word = _dwarf_memcpy_swap_bytes; } @@ -1029,7 +1024,7 @@ dwarf_object_init_b(Dwarf_Obj_Access_Interface_a* obj, Filesize is to set up a sensible default hash tree size. */ dbg = _dwarf_get_debug(filesize); - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); } dbg->de_errhand = errhand; @@ -1129,7 +1124,7 @@ int dwarf_object_finish(Dwarf_Debug dbg) { int res = 0; - + /* do not use CHECK_DBG */ _dwarf_harmless_cleanout(&dbg->de_harmless_errors); res = _dwarf_free_all_of_one_debug(dbg); /* see dwarf_error.h dwarf_error.c Relevant @@ -1138,7 +1133,7 @@ dwarf_object_finish(Dwarf_Debug dbg) return res; } -#if defined(HAVE_ZLIB) || defined(HAVE_ZSTD) +#if defined(HAVE_ZLIB) && defined(HAVE_ZSTD) /* case 1: The input stream is assumed to contain the four letters @@ -1253,7 +1248,6 @@ do_decompress(Dwarf_Debug dbg, " The compressed section is not properly formatted"); return DW_DLV_ERROR; } -#ifdef HAVE_ZLIB if (!zstdcompress) { /* According to zlib.net zlib essentially never expands the data when compressing. There is no statement @@ -1297,16 +1291,6 @@ do_decompress(Dwarf_Debug dbg, return DW_DLV_ERROR; } } -#else /* !HAVE_ZLIB */ - if (!zstdcompress) { - _dwarf_error_string(dbg, error, - DW_DLE_ZDEBUG_REQUIRES_ZLIB, - "DW_DLE_ZDEBUG_REQUIRES_ZLIB: " - " zlib is missing, cannot decomreess a zlib section"); - return DW_DLV_ERROR; - } -#endif /* HAVE_ZLIB */ -#ifdef HAVE_ZSTD if (zstdcompress) { /* According to zlib.net zlib essentially never expands the data when compressing. There is no statement @@ -1350,15 +1334,6 @@ do_decompress(Dwarf_Debug dbg, return DW_DLV_ERROR; } } -#else /* !HAVE_ZSTD */ - if (zstdcompress) { - _dwarf_error_string(dbg, error, - DW_DLE_ZDEBUG_REQUIRES_ZLIB, - "DW_DLE_ZDEBUG_REQUIRES_ZLIB: " - " zstd is missing, cannot decomreess a libzstd section"); - return DW_DLV_ERROR; - } -#endif /* HAVE_ZSTD */ if ((src +srclen) > endsection) { _dwarf_error_string(dbg, error, DW_DLE_ZLIB_SECTION_SHORT, @@ -1379,7 +1354,6 @@ do_decompress(Dwarf_Debug dbg, return DW_DLV_ERROR; } /* uncompress is a zlib function. */ -#ifdef HAVE_ZLIB if (!zstdcompress) { int res = 0; uLongf dlen = destlen; @@ -1398,8 +1372,6 @@ do_decompress(Dwarf_Debug dbg, DW_DLV_ERROR); } } -#endif /* HAVE_ZLIB */ -#ifdef HAVE_ZSTD if (zstdcompress) { size_t zsize = ZSTD_decompress(dest,destlen,src,srclen); @@ -1412,7 +1384,6 @@ do_decompress(Dwarf_Debug dbg, return DW_DLV_ERROR; } } -#endif /* HAVE_ZSTD */ /* Z_OK */ section->dss_data = dest; section->dss_size = destlen; @@ -1420,7 +1391,7 @@ do_decompress(Dwarf_Debug dbg, section->dss_did_decompress = TRUE; return DW_DLV_OK; } -#endif /* HAVE_ZLIB || HAVE_ZSTD */ +#endif /* HAVE_ZLIB && HAVE_ZSTD */ /* Load the ELF section with the specified index and set its dss_data pointer to the memory where it was loaded. */ @@ -1488,19 +1459,19 @@ _dwarf_load_section(Dwarf_Debug dbg, DWARF_DBG_ERROR(dbg, DW_DLE_COMPRESSED_EMPTY_SECTION, DW_DLV_ERROR); } -#if defined(HAVE_ZLIB) || defined(HAVE_ZSTD) +#if defined(HAVE_ZLIB) && defined(HAVE_ZSTD) res = do_decompress(dbg,section,error); if (res != DW_DLV_OK) { return res; } -#else +#else /* !defined(HAVE_ZLIB) && defined(HAVE_ZSTD) */ _dwarf_error_string(dbg, error, DW_DLE_ZDEBUG_REQUIRES_ZLIB, "DW_DLE_ZDEBUG_REQUIRES_ZLIB: " " zlib and zstd are missing, cannot" " decompress section."); return DW_DLV_ERROR; -#endif +#endif /* defined(HAVE_ZLIB) && defined(HAVE_ZSTD) */ section->dss_did_decompress = TRUE; } if (_dwarf_apply_relocs == 0) { @@ -1552,6 +1523,9 @@ dwarf_get_section_max_offsets_d(Dwarf_Debug dbg, Dwarf_Unsigned * debug_loclists_size, Dwarf_Unsigned * debug_rnglists_size) { + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } if (debug_info_size) { *debug_info_size = dbg->de_debug_info.dss_size; } @@ -1623,26 +1597,46 @@ dwarf_get_section_info_by_name(Dwarf_Debug dbg, Dwarf_Addr *section_addr, Dwarf_Unsigned *section_size, Dwarf_Error * error) +{ + return dwarf_get_section_info_by_name_a(dbg, + section_name, + section_addr, + section_size, + 0,0, + error); +} +int +dwarf_get_section_info_by_name_a(Dwarf_Debug dbg, + const char *section_name, + Dwarf_Addr *section_addr, + Dwarf_Unsigned *section_size, + Dwarf_Unsigned *section_flags, + Dwarf_Unsigned *section_offset, + Dwarf_Error * error) { struct Dwarf_Obj_Access_Interface_a_s * obj = 0; Dwarf_Unsigned section_count = 0; Dwarf_Unsigned section_index = 0; struct Dwarf_Obj_Access_Section_a_s doas; - *section_addr = 0; - *section_size = 0; - - if (!dbg) { - _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL: null dbg passed to " - "dwarf_get_section_info_by_name"); - return DW_DLV_ERROR; + CHECK_DBG(dbg,error,"dwarf_get_section_info_by_name_a()"); + if (section_addr) { + *section_addr = 0; + } + if (section_size) { + *section_size = 0; + } + if (section_flags) { + *section_flags = 0; + } + if (section_offset) { + *section_offset = 0; } if (!section_name) { _dwarf_error_string(dbg,error,DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: null section_name pointer " "passed to " - "dwarf_get_section_info_by_name"); + "dwarf_get_section_info_by_name_a"); return DW_DLV_ERROR; } if (!section_name[0]) { @@ -1674,8 +1668,18 @@ dwarf_get_section_info_by_name(Dwarf_Debug dbg, continue; } if (!strcmp(section_name,doas.as_name)) { - *section_addr = doas.as_addr; - *section_size = doas.as_size; + if (section_addr) { + *section_addr = doas.as_addr; + } + if (section_size) { + *section_size = doas.as_size; + } + if (section_flags) { + *section_flags = doas.as_flags; + } + if (section_offset) { + *section_offset = doas.as_offset; + } return DW_DLV_OK; } } @@ -1691,10 +1695,41 @@ dwarf_get_section_info_by_index(Dwarf_Debug dbg, Dwarf_Unsigned *section_size, Dwarf_Error * error) { - *section_addr = 0; - *section_size = 0; - *section_name = NULL; + return dwarf_get_section_info_by_index_a(dbg, + section_index, + section_name, + section_addr, + section_size, + 0,0, + error); +} +int +dwarf_get_section_info_by_index_a(Dwarf_Debug dbg, + int section_index, + const char **section_name, + Dwarf_Addr *section_addr, + Dwarf_Unsigned *section_size, + Dwarf_Unsigned *section_flags, + Dwarf_Unsigned *section_offset, + Dwarf_Error * error) +{ + CHECK_DBG(dbg,error,"dwarf_get_section_info_by_index_a()"); + if (section_addr) { + *section_addr = 0; + } + if (section_size) { + *section_size = 0; + } + if (section_name) { + *section_name = 0; + } + if (section_flags) { + *section_flags = 0; + } + if (section_offset) { + *section_offset = 0; + } /* Check if we have a valid section index */ if (section_index >= 0 && section_index < dwarf_get_section_count(dbg)) { @@ -1712,9 +1747,21 @@ dwarf_get_section_info_by_index(Dwarf_Debug dbg, DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR); } - *section_addr = doas.as_addr; - *section_size = doas.as_size; - *section_name = doas.as_name; + if (section_addr) { + *section_addr = doas.as_addr; + } + if (section_size) { + *section_size = doas.as_size; + } + if (section_name) { + *section_name = doas.as_name; + } + if (section_flags) { + *section_flags = doas.as_flags; + } + if (section_offset) { + *section_offset = doas.as_offset; + } return DW_DLV_OK; } return DW_DLV_NO_ENTRY; @@ -1724,8 +1771,13 @@ dwarf_get_section_info_by_index(Dwarf_Debug dbg, int dwarf_get_section_count(Dwarf_Debug dbg) { - struct Dwarf_Obj_Access_Interface_a_s * obj = dbg->de_obj_file; - if (NULL == obj) { + struct Dwarf_Obj_Access_Interface_a_s * obj = 0; + + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } + obj = dbg->de_obj_file; + if (!obj) { /* -1 */ return DW_DLV_NO_ENTRY; } diff --git a/src/lib/libdwarf/dwarf_line.c b/src/lib/libdwarf/dwarf_line.c index 3d4f6d3..c0c9b93 100644 --- a/src/lib/libdwarf/dwarf_line.c +++ b/src/lib/libdwarf/dwarf_line.c @@ -1084,6 +1084,7 @@ dwarf_get_ranges_section_name(Dwarf_Debug dbg, if (error != NULL) { *error = NULL; } + CHECK_DBG(dbg,error,"dwarf_get_ranges_section_name()"); sec = &dbg->de_debug_ranges; if (sec->dss_size == 0) { /* We don't have such a section at all. */ @@ -1099,6 +1100,8 @@ dwarf_get_aranges_section_name(Dwarf_Debug dbg, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; + + CHECK_DBG(dbg,error,"dwarf_get_aranges_section_name()"); if (error != NULL) { *error = NULL; } @@ -1116,6 +1119,8 @@ dwarf_get_line_section_name(Dwarf_Debug dbg, Dwarf_Error * error) { struct Dwarf_Section_s *sec = 0; + + CHECK_DBG(dbg,error,"dwarf_get_line_section_name)"); if (error != NULL) { *error = NULL; } @@ -1160,11 +1165,11 @@ dwarf_get_string_section_name(Dwarf_Debug dbg, { struct Dwarf_Section_s *sec = 0; + CHECK_DBG(dbg,error,"dwarf_get_string_section_name()"); /* ***** BEGIN CODE ***** */ if (error != NULL) { *error = NULL; } - sec = &dbg->de_debug_str; if (sec->dss_size == 0) { /* We don't have such a section at all. */ @@ -2540,9 +2545,10 @@ _dwarf_update_chain_list( Dwarf_Chain chain_line, } void -_dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count) +_dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head, + Dwarf_Unsigned count) { - int i = 0; + Dwarf_Unsigned i = 0; Dwarf_Chain curr_chain = head; for (i = 0; i < count; i++) { Dwarf_Chain t = curr_chain; diff --git a/src/lib/libdwarf/dwarf_line.h b/src/lib/libdwarf/dwarf_line.h index 7fa8a9a..5056451 100644 --- a/src/lib/libdwarf/dwarf_line.h +++ b/src/lib/libdwarf/dwarf_line.h @@ -479,7 +479,7 @@ void _dwarf_report_bad_lnct( Dwarf_Debug dbg, void _dwarf_update_chain_list( Dwarf_Chain chain_line, Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain); void _dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head, - int count); + Dwarf_Unsigned count); int _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m); void _dwarf_line_context_destructor(void *m); diff --git a/src/lib/libdwarf/dwarf_loc.c b/src/lib/libdwarf/dwarf_loc.c index d2b3201..a77a500 100644 --- a/src/lib/libdwarf/dwarf_loc.c +++ b/src/lib/libdwarf/dwarf_loc.c @@ -65,7 +65,7 @@ _dwarf_locdesc_c_constructor(Dwarf_Debug dbg, void *locd) { Dwarf_Locdesc_c ldp = (Dwarf_Locdesc_c)locd; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return DW_DLV_ERROR; } ldp->ld_lle_value = DW_LLE_VALUE_BOGUS; @@ -344,13 +344,7 @@ _dwarf_setup_loc(Dwarf_Attribute attr, *cucontext_ret = attr->ar_cu_context; dbg = attr->ar_cu_context->cc_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_ATTR_DBG_NULL, - "DW_DLE_ATTR_DBG_NULL The Attribute passed to " - "dwarf_get_loclist_c() " - "points to an invalid Dwarf_Debug"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"_dwarf_get_loclist_lle_count()"); *dbg_ret = dbg; blkres = dwarf_whatform(attr, &form, error); if (blkres != DW_DLV_OK) { @@ -1611,14 +1605,7 @@ dwarf_get_loclist_c(Dwarf_Attribute attr, return DW_DLV_ERROR; } dbg = attr->ar_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL Dwarf_Debug, improper Dwarf_Attribute " - "argument passed to " - "dwarf_get_loclist_c()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_loclist_c()"); /* ***** BEGIN CODE ***** */ setup_res = _dwarf_setup_loc(attr, &dbg,&cucontext, &form, error); @@ -1764,14 +1751,7 @@ dwarf_loclist_from_expr_c(Dwarf_Debug dbg, Dwarf_Small version_stamp = dwarf_version; int res = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL or bad Dwarf_Debug " - "argument passed to " - "dwarf_loclist_from_expr_c()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_loclist_from_expr_c()"); llhead = (Dwarf_Loc_Head_c)_dwarf_get_alloc(dbg, DW_DLA_LOC_HEAD_C, 1); if (!llhead) { diff --git a/src/lib/libdwarf/dwarf_loclists.c b/src/lib/libdwarf/dwarf_loclists.c index c6061cb..c8d2c70 100644 --- a/src/lib/libdwarf/dwarf_loclists.c +++ b/src/lib/libdwarf/dwarf_loclists.c @@ -78,7 +78,7 @@ free_loclists_chain(Dwarf_Debug dbg, Dwarf_Chain head) Dwarf_Chain cur = head; Dwarf_Chain next = 0; - if (!head || !dbg) { + if (!head || IS_INVALID_DBG(dbg)) { return; } for ( ;cur; cur = next) { @@ -511,14 +511,7 @@ dwarf_load_loclists(Dwarf_Debug dbg, Dwarf_Loclists_Context *cxt = 0; Dwarf_Unsigned count = 0; - if (!dbg) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL Dwarf_Debug " - "argument passed to " - "dwarf_load_loclists()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_load_loclists()"); if (dbg->de_loclists_context) { if (loclists_count) { *loclists_count = dbg->de_loclists_context_count; @@ -587,15 +580,7 @@ dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg, Dwarf_Small *offsetptr = 0; Dwarf_Unsigned targetoffset = 0; - if (!dbg) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL Dwarf_Debug " - "argument passed to " - "dwarf_get_loclist_offset_index_value()"); - return DW_DLV_ERROR; - } - + CHECK_DBG(dbg,error,"dwarf_get_loclist_offset_index_value()"); if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } @@ -728,14 +713,7 @@ dwarf_get_loclist_context_basics(Dwarf_Debug dbg, { Dwarf_Loclists_Context con = 0; - if (!dbg) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL Dwarf_Debug " - "argument passed to " - "dwarf_get_loclist_context_basics()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_loclist_context_basics()"); if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } @@ -815,14 +793,7 @@ int dwarf_get_loclist_lle(Dwarf_Debug dbg, int res = 0; unsigned address_size = 0; - if (!dbg) { - _dwarf_error_string(dbg, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL Dwarf_Debug " - "argument passed to " - "dwarf_get_loclist_lle()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_loclist_lle()"); if (!dbg->de_loclists_context_count) { return DW_DLV_NO_ENTRY; } @@ -1318,7 +1289,7 @@ dwarf_dealloc_loc_head_c(Dwarf_Loc_Head_c head) return; } dbg = head->ll_dbg; - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return; } if (head->ll_first) { diff --git a/src/lib/libdwarf/dwarf_machoread.c b/src/lib/libdwarf/dwarf_machoread.c index 4633500..d41d481 100644 --- a/src/lib/libdwarf/dwarf_machoread.c +++ b/src/lib/libdwarf/dwarf_machoread.c @@ -193,14 +193,14 @@ static int macho_get_section_info (void *obj, struct generic_macho_section *sp = 0; sp = macho->mo_dwarf_sections + section_index; - return_section->as_name = sp->dwarfsectname; - return_section->as_type = 0; - return_section->as_flags = 0; - return_section->as_addr = 0; - return_section->as_offset = 0; - return_section->as_size = sp->size; - return_section->as_link = 0; - return_section->as_info = 0; + return_section->as_name = sp->dwarfsectname; + return_section->as_type = 0; + return_section->as_flags = sp->flags; + return_section->as_addr = sp->addr; + return_section->as_offset = sp->offset; + return_section->as_size = sp->size; + return_section->as_link = 0; + return_section->as_info = 0; return_section->as_addralign = 0; return_section->as_entrysize = 0; return DW_DLV_OK; @@ -342,7 +342,8 @@ load_macho_header32(dwarf_macho_object_access_internals_t *mfp, *errcode = DW_DLE_MACHO_CORRUPT_HEADER; return DW_DLV_ERROR; } - + mfp->mo_machine = mfp->mo_header.cputype; + mfp->mo_flags = mfp->mo_header.flags; mfp->mo_command_start_offset = sizeof(mh32); return DW_DLV_OK; } @@ -383,6 +384,8 @@ load_macho_header64(dwarf_macho_object_access_internals_t *mfp, *errcode = DW_DLE_MACHO_CORRUPT_HEADER; return DW_DLV_ERROR; } + mfp->mo_machine = mfp->mo_header.cputype; + mfp->mo_flags = mfp->mo_header.flags; mfp->mo_command_start_offset = sizeof(mh64); return DW_DLV_OK; } @@ -887,6 +890,8 @@ _dwarf_macho_setup(int fd, } intfc = binary_interface->ai_object; intfc->mo_path = strdup(true_path); + (*dbg)->de_obj_flags = intfc->mo_flags; + (*dbg)->de_obj_machine = intfc->mo_machine; (*dbg)->de_universalbinary_index = universalnumber; (*dbg)->de_universalbinary_count = universalbinary_count; return res; @@ -1069,6 +1074,10 @@ _dwarf_macho_object_access_internals_init( break; } } + if (sp->dwarfsectname[0] == 0) { + /* if not matched, keep the apple section name */ + sp->dwarfsectname = sp->sectname; + } } return DW_DLV_OK; } diff --git a/src/lib/libdwarf/dwarf_machoread.h b/src/lib/libdwarf/dwarf_machoread.h index 6d9627f..8fc6eda 100644 --- a/src/lib/libdwarf/dwarf_machoread.h +++ b/src/lib/libdwarf/dwarf_machoread.h @@ -120,6 +120,8 @@ typedef struct dwarf_macho_filedata_s { int mo_fd; int mo_destruct_close_fd; /*aka: lib owns fd */ Dwarf_Unsigned mo_filesize; + Dwarf_Unsigned mo_machine; + Dwarf_Unsigned mo_flags; Dwarf_Unsigned mo_inner_offset; /* for universal inner */ Dwarf_Small mo_offsetsize; /* 32 or 64 section data */ Dwarf_Small mo_pointersize; diff --git a/src/lib/libdwarf/dwarf_macro.c b/src/lib/libdwarf/dwarf_macro.c index c4ad8c6..9cae470 100644 --- a/src/lib/libdwarf/dwarf_macro.c +++ b/src/lib/libdwarf/dwarf_macro.c @@ -223,7 +223,7 @@ dwarf_get_macro_details(Dwarf_Debug dbg, unsigned long count = 0; unsigned long max_count = (unsigned long) maximum_count; _dwarf_reset_index_macro_stack(&msdata); - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, "DW_DLE_DBG_NULL: Either null or it contains" "a stale Dwarf_Debug pointer"); diff --git a/src/lib/libdwarf/dwarf_macro5.c b/src/lib/libdwarf/dwarf_macro5.c index 5fb035c..75e5ffb 100644 --- a/src/lib/libdwarf/dwarf_macro5.c +++ b/src/lib/libdwarf/dwarf_macro5.c @@ -1596,7 +1596,7 @@ int dwarf_get_macro_section_name(Dwarf_Debug dbg, { struct Dwarf_Section_s *sec = 0; - (void)error; + CHECK_DBG(dbg,error,"dwarf_get_macro_section_name()"); sec = &dbg->de_debug_macro; if (sec->dss_size == 0) { /* We don't have such a section at all. */ diff --git a/src/lib/libdwarf/dwarf_object_detector.c b/src/lib/libdwarf/dwarf_object_detector.c index 16dd70d..af546e6 100644 --- a/src/lib/libdwarf/dwarf_object_detector.c +++ b/src/lib/libdwarf/dwarf_object_detector.c @@ -115,6 +115,22 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* A flag not public to users. */ static int _dwarf_global_debuglink_crc_suppress; +#if 0 +/* debugging only */ +static void +dump_bytes(char * msg,Dwarf_Small * start, long len) +{ + Dwarf_Small *end = start + len; + Dwarf_Small *cur = start; + + printf("%s ",msg); + for (; cur < end; cur++) { + printf("%02x ", *cur); + } + printf("\n"); +} +#endif + int dwarf_suppress_debuglink_crc(int dw_suppress) { @@ -709,6 +725,9 @@ match_buildid( return TRUE; } +/* we need the crc byte order to match that + of the object file so a comparison works. + Here we fix up when there is a mismatch */ static int _dwarf_debuglink_finder_newpath( char * path_in, @@ -718,7 +737,8 @@ _dwarf_debuglink_finder_newpath( dwarfstring *m, int * fd_out) { - unsigned char lcrc[4]; + unsigned char lcrc[4] = {0,0,0,0}; + unsigned char newcrc[4] = {0,0,0,0}; char *debuglinkpath = 0; /* must be freed */ unsigned char *crc = 0; char *debuglinkfullpath = 0; @@ -771,7 +791,6 @@ _dwarf_debuglink_finder_newpath( free(paths); paths = 0; - memset(&lcrc[0],0,sizeof(lcrc)); if (!_dwarf_get_suppress_debuglink_crc() &&crc_in && !crc) { int res1 = 0; @@ -787,7 +806,8 @@ _dwarf_debuglink_finder_newpath( return DW_DLV_NO_ENTRY; } if (res1 == DW_DLV_OK) { - crc = &lcrc[0]; + dbg->de_copy_word((void *)newcrc,(void *)lcrc,4); + crc=&newcrc[0]; } } free(debuglinkfullpath); @@ -851,7 +871,8 @@ _dwarf_debuglink_finder_internal( DW_GROUPNUMBER_ANY, 0,0, &dbg, &error); if (res == DW_DLV_ERROR) { - *errcode = dwarf_errno(error); + /* error codes all >=0 && < 2000 */ + *errcode = (int)dwarf_errno(error); dwarf_dealloc_error(dbg,error); error = 0; return res; @@ -867,7 +888,7 @@ _dwarf_debuglink_finder_internal( lpath, &error); if (res != DW_DLV_OK){ if (res == DW_DLV_ERROR) { - *errcode = dwarf_errno(error); + *errcode = (int)dwarf_errno(error); dwarf_dealloc_error(dbg,error); error = 0; } @@ -882,7 +903,7 @@ _dwarf_debuglink_finder_internal( &buildid, &buildid_length, &paths, &paths_count, &error); if (res == DW_DLV_ERROR) { - *errcode = dwarf_errno(error); + *errcode = (int)dwarf_errno(error); dwarf_dealloc_error(dbg,error); dwarf_finish(dbg); return DW_DLV_NO_ENTRY; diff --git a/src/lib/libdwarf/dwarf_opaque.h b/src/lib/libdwarf/dwarf_opaque.h index 9bd8c55..41641b7 100644 --- a/src/lib/libdwarf/dwarf_opaque.h +++ b/src/lib/libdwarf/dwarf_opaque.h @@ -594,9 +594,10 @@ struct Dwarf_Debug_s { under de_obj_file. */ int de_fd; char de_owns_fd; + Dwarf_Small de_ftype; /* DW_FTYPE_PE, ... */ char de_in_tdestroy; /* for de_alloc_tree DW202309-001 */ /* DW_PATHSOURCE_BASIC or MACOS or DEBUGLINK */ - unsigned char de_path_source; + Dwarf_Small de_path_source; /* de_path is only set automatically if dwarf_init_path() was used to initialize things. Used with the .gnu_debuglink section. */ @@ -627,8 +628,26 @@ struct Dwarf_Debug_s { leave this zero. */ Dwarf_Unsigned de_filesize; + /* The value is what the object file encodes for + the machine, In an Elf Header, for example, its value + comes from the e_machine field. + MACOS provides a cputype field. + PE provides IMAGE_FILE_HEADER.Machine. + Inspect de_ftype using the value of + de_obj_machine or the following de_obj_* fields. */ + Dwarf_Unsigned de_obj_machine; + /* For DW_FTYPE_APPLEUNIVERSAL this is the + offset of an executable object in the multi-executable + file. For all other de_ftype values this has + value zero. */ + Dwarf_Unsigned de_obj_ub_offset; + /* The flags field from an Elf or Macos header + or the Charactersics field from a PE header. */ + Dwarf_Unsigned de_obj_flags; + /* number of bytes in a pointer of the target in various .debug_ - sections. 4 in 32bit, 8 in MIPS 64, ia64. */ + sections. 4 in 32bit, 8 in MIPS 64, ia64. + This is taken from object file headers. */ Dwarf_Small de_pointer_size; /* set at creation of a Dwarf_Debug to say if form_string @@ -738,8 +757,8 @@ struct Dwarf_Debug_s { Dwarf_Xu_Index_Header de_cu_hashindex_data; Dwarf_Xu_Index_Header de_tu_hashindex_data; - void (*de_copy_word) (void *, const void *, unsigned long); - unsigned char de_same_endian; + void (*de_copy_word) (void *dw_targ, const void *dw_src, + unsigned long dw_len); unsigned char de_elf_must_close; /* If non-zero, then it was dwarf_init (not dwarf_elf_init) so must elf_end() */ @@ -902,6 +921,7 @@ int _dwarf_create_a_new_cu_context_record_on_list( Dwarf_Unsigned section_size, Dwarf_Unsigned new_cu_offset, Dwarf_CU_Context *context_out, + Dwarf_Die *cu_die_out, Dwarf_Error *error); Dwarf_Unsigned _dwarf_calculate_next_cu_context_offset( Dwarf_CU_Context cu_context); @@ -949,6 +969,7 @@ int _dwarf_section_in_group_by_name(Dwarf_Debug dbg, int _dwarf_next_cu_header_internal(Dwarf_Debug dbg, Dwarf_Bool is_info, + Dwarf_Die * cu_die_out, Dwarf_Unsigned * cu_header_length, Dwarf_Half * version_stamp, Dwarf_Unsigned * abbrev_offset, diff --git a/src/lib/libdwarf/dwarf_peread.c b/src/lib/libdwarf/dwarf_peread.c index 6b6adec..e8d7f7a 100644 --- a/src/lib/libdwarf/dwarf_peread.c +++ b/src/lib/libdwarf/dwarf_peread.c @@ -241,10 +241,10 @@ pe_get_section_info (void *obj, sp = pep->pe_sectionptr + section_index; return_section->as_name = sp->dwarfsectname; return_section->as_type = 0; - return_section->as_flags = 0; + return_section->as_flags = sp->Characteristics; return_section->as_addr = pep->pe_OptionalHeader.ImageBase + sp->VirtualAddress; - return_section->as_offset = 0; + return_section->as_offset = sp->PointerToRawData; /* SizeOfRawData can be rounded or truncated, use VirtualSize for the real analog of Elf section size. */ @@ -400,6 +400,9 @@ pe_load_section (void *obj, Dwarf_Unsigned section_index, *return_data = sp->loaded_data; return DW_DLV_OK; } + if (sp->section_irrelevant_to_dwarf) { + return DW_DLV_NO_ENTRY; + } if (!sp->VirtualSize) { return DW_DLV_NO_ENTRY; } @@ -577,10 +580,11 @@ _dwarf_pe_load_dwarf_section_headers( filesect.SizeOfRawData); irrelevant = is_irrelevant_section(sec_outp->dwarfsectname, sec_outp->VirtualSize); + sec_outp->section_irrelevant_to_dwarf = irrelevant; if (irrelevant) { - sec_outp->VirtualSize = 0; - sec_outp->SizeOfRawData = 0; - }else{ + continue; + } + { /* A Heuristic, allowing large virtual size but not unlimited as we will malloc it later, as Virtualsize. */ @@ -740,7 +744,8 @@ _dwarf_load_pe_sections( ifh.SizeOfOptionalHeader); ASNAR(word_swap,pep->pe_FileHeader.Characteristics, ifh.Characteristics); - + pep->pe_machine = pep->pe_FileHeader.Machine; + pep->pe_flags = pep->pe_FileHeader.Characteristics; pep->pe_optional_header_offset = pep->pe_nt_header_offset+ sizeof(ifh); if (pep->pe_offsetsize == 32) { @@ -879,6 +884,8 @@ _dwarf_pe_setup(int fd, return res; } pep = binary_interface->ai_object; + (*dbg)->de_obj_flags = pep->pe_flags; + (*dbg)->de_obj_machine = pep->pe_machine; pep->pe_path = strdup(true_path); return res; } diff --git a/src/lib/libdwarf/dwarf_peread.h b/src/lib/libdwarf/dwarf_peread.h index 71d94dc..67bdf6f 100644 --- a/src/lib/libdwarf/dwarf_peread.h +++ b/src/lib/libdwarf/dwarf_peread.h @@ -107,6 +107,7 @@ struct dwarf_pe_generic_image_section_header Dwarf_Unsigned NumberOfLinenumbers; Dwarf_Unsigned Characteristics; Dwarf_Small * loaded_data; /* must be freed. */ + Dwarf_Bool section_irrelevant_to_dwarf; }; #define DWARF_PE_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b @@ -123,11 +124,12 @@ typedef struct pe_filedata_s { int pe_destruct_close_fd; /*aka: lib owns fd */ int pe_is_64bit; Dwarf_Unsigned pe_filesize; + Dwarf_Unsigned pe_flags; + Dwarf_Unsigned pe_machine; Dwarf_Small pe_offsetsize; /* 32 or 64 section data */ Dwarf_Small pe_pointersize; int pe_ftype; unsigned pe_endian; - /*Dwarf_Small pe_machine; */ void (*pe_copy_word) (void *, const void *, unsigned long); Dwarf_Unsigned pe_nt_header_offset; Dwarf_Unsigned pe_optional_header_offset; diff --git a/src/lib/libdwarf/dwarf_query.c b/src/lib/libdwarf/dwarf_query.c index cbf2d09..e659cff 100644 --- a/src/lib/libdwarf/dwarf_query.c +++ b/src/lib/libdwarf/dwarf_query.c @@ -58,10 +58,7 @@ int dwarf_get_offset_size(Dwarf_Debug dbg, Dwarf_Half * offset_size, Dwarf_Error * error) { - if (dbg == 0) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_offset_size()"); *offset_size = dbg->de_length_size; return DW_DLV_OK; } @@ -96,10 +93,7 @@ dwarf_get_address_size(Dwarf_Debug dbg, { Dwarf_Half address_size = 0; - if (dbg == 0) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_address_size()"); address_size = dbg->de_pointer_size; *ret_addr_size = address_size; return DW_DLV_OK; @@ -250,9 +244,9 @@ dwarf_offset_list(Dwarf_Debug dbg, Dwarf_Chain_2 head_chain = 0; Dwarf_Chain_2 *plast = &head_chain; + CHECK_DBG(dbg,error,"dwarf_offset_list()"); *offbuf = NULL; *offcnt = 0; - res = dwarf_offdie_b(dbg,offset,is_info,&die,error); if (DW_DLV_OK != res) { return res; @@ -298,7 +292,7 @@ dwarf_offset_list(Dwarf_Debug dbg, } /* Move to next sibling next sibling */ sib_die = 0; - res = dwarf_siblingof_b(dbg,cur_die,is_info,&sib_die,error); + res = dwarf_siblingof_c(cur_die,&sib_die,error); if (cur_die != die) { dwarf_dealloc(dbg,cur_die,DW_DLA_DIE); } @@ -2113,7 +2107,7 @@ dwarf_get_universalbinary_count( Dwarf_Unsigned *current_index, Dwarf_Unsigned *available_count) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return DW_DLV_NO_ENTRY; } if (!dbg->de_universalbinary_count ) { @@ -2127,3 +2121,53 @@ dwarf_get_universalbinary_count( } return DW_DLV_OK; } + +/* Never returns DW_DLV_ERROR */ +int +dwarf_machine_architecture(Dwarf_Debug dbg, + Dwarf_Small *dw_ftype, + Dwarf_Small *dw_obj_pointersize, + Dwarf_Bool *dw_obj_is_big_endian, + Dwarf_Unsigned *dw_obj_machine, + Dwarf_Unsigned *dw_obj_flags, + Dwarf_Small *dw_path_source, + Dwarf_Unsigned *dw_ub_offset, + Dwarf_Unsigned *dw_ub_count, + Dwarf_Unsigned *dw_ub_index, + Dwarf_Unsigned *dw_comdat_groupnumber) +{ + if (IS_INVALID_DBG(dbg)) { + return DW_DLV_NO_ENTRY; + } + if (dw_ftype) { + *dw_ftype = dbg->de_ftype; + } + if (dw_obj_pointersize) { + *dw_obj_pointersize = dbg->de_pointer_size; + } + if (dw_obj_is_big_endian) { + *dw_obj_is_big_endian = dbg->de_big_endian_object; + } + if (dw_obj_machine) { + *dw_obj_machine = dbg->de_obj_machine; + } + if (dw_obj_flags) { + *dw_obj_flags = dbg->de_obj_flags; + } + if (dw_path_source) { + *dw_path_source = dbg->de_path_source; + } + if (dw_ub_offset) { + *dw_ub_offset = dbg->de_obj_ub_offset; + } + if (dw_ub_count) { + *dw_ub_count = dbg->de_universalbinary_count; + } + if (dw_ub_index) { + *dw_ub_index = dbg->de_universalbinary_index; + } + if (dw_comdat_groupnumber) { + *dw_comdat_groupnumber = dbg->de_groupnumber; + } + return DW_DLV_OK; +} diff --git a/src/lib/libdwarf/dwarf_ranges.c b/src/lib/libdwarf/dwarf_ranges.c index 4c65f73..d186de6 100644 --- a/src/lib/libdwarf/dwarf_ranges.c +++ b/src/lib/libdwarf/dwarf_ranges.c @@ -135,10 +135,7 @@ int dwarf_get_ranges_b(Dwarf_Debug dbg, Dwarf_Bool rangeslocal = TRUE; (void)offset_size; - if (!dbg) { - _dwarf_error(NULL, error, DW_DLE_DBG_NULL); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_ranges_b()"); address_size = localdbg->de_pointer_size; /* default */ if (die) { /* If we wind up using the tied file the die_version diff --git a/src/lib/libdwarf/dwarf_rnglists.c b/src/lib/libdwarf/dwarf_rnglists.c index 07b367e..8917d5f 100644 --- a/src/lib/libdwarf/dwarf_rnglists.c +++ b/src/lib/libdwarf/dwarf_rnglists.c @@ -540,14 +540,7 @@ int dwarf_load_rnglists( Dwarf_Rnglists_Context *cxt = 0; Dwarf_Unsigned count = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL" - "NULL or invalid Dwarf_Debug " - "argument passed to " - "dwarf_load_rnglists()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_load_rnglists"); if (dbg->de_rnglists_context) { if (rnglists_count) { *rnglists_count = dbg->de_rnglists_context_count; @@ -585,7 +578,7 @@ _dwarf_dealloc_rnglists_context(Dwarf_Debug dbg) Dwarf_Unsigned i = 0; Dwarf_Rnglists_Context * rngcon = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { + if (IS_INVALID_DBG(dbg)) { return; } if (!dbg->de_rnglists_context) { @@ -621,14 +614,7 @@ dwarf_get_rnglist_offset_index_value( Dwarf_Unsigned targetoffset = 0; Dwarf_Unsigned localoffset = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL " - "NULL or invalid dbg " - "argument passed to " - "dwarf_get_rnglist_offset_index_value()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_rnglist_offset_index_value()"); if (!dbg->de_rnglists_context) { return DW_DLV_NO_ENTRY; } @@ -767,14 +753,8 @@ int dwarf_get_rnglist_context_basics( Dwarf_Error *error) { Dwarf_Rnglists_Context con = 0; - if (!dbg) { - _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL " - "NULL dbg " - "argument passed to " - "dwarf_get_rnglist_context_basics()"); - return DW_DLV_ERROR; - } + + CHECK_DBG(dbg,error,"dwarf_get_rnglist_context_basics()"); if (!dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; } @@ -853,14 +833,7 @@ int dwarf_get_rnglist_rle( unsigned address_size = 0; Dwarf_Unsigned secsize = 0; - if (!dbg) { - _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL " - "NULL dbg " - "argument passed to " - "dwarf_get_rnglist_rle()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_rnglist_rle()"); secsize = dbg->de_debug_rnglists.dss_size; if (!dbg->de_rnglists_context_count) { return DW_DLV_NO_ENTRY; @@ -1311,14 +1284,8 @@ dwarf_rnglists_get_rle_head( memset(&shead,0,sizeof(shead)); ctx = attr->ar_cu_context; dbg = ctx->cc_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error,DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL " - "NULL or invalid dbg " - "argument passed to " - "dwarf_rnglists_get_rle_head()"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error, + "dwarf_rnglists_get_rle_head() via attribute"); array = dbg->de_rnglists_context; if (theform == DW_FORM_rnglistx) { is_rnglistx = TRUE; diff --git a/src/lib/libdwarf/dwarf_str_offsets.c b/src/lib/libdwarf/dwarf_str_offsets.c index fafb14f..c23b4fb 100644 --- a/src/lib/libdwarf/dwarf_str_offsets.c +++ b/src/lib/libdwarf/dwarf_str_offsets.c @@ -90,10 +90,7 @@ dwarf_open_str_offsets_table_access(Dwarf_Debug dbg, Dwarf_Small *offsets_start_ptr = 0; Dwarf_Unsigned sec_size = 0; - if (!dbg) { - _dwarf_error(NULL,error,DW_DLE_STR_OFFSETS_NULL_DBG); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_open_str_offsets_table_access()"); if (!table_data) { _dwarf_error(dbg,error,DW_DLE_STR_OFFSETS_NULLARGUMENT); return DW_DLV_ERROR; diff --git a/src/lib/libdwarf/dwarf_stringsection.c b/src/lib/libdwarf/dwarf_stringsection.c index 930690b..6f2c79a 100644 --- a/src/lib/libdwarf/dwarf_stringsection.c +++ b/src/lib/libdwarf/dwarf_stringsection.c @@ -55,13 +55,7 @@ dwarf_get_str(Dwarf_Debug dbg, void *begin = 0; void *end = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(NULL, error, DW_DLE_DBG_NULL, - "DW_DLE_DBG_NULL:calling dwarf_get_str()" - "Either null or it contains" - "a stale Dwarf_Debug pointer"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_str()"); if (offset == dbg->de_debug_str.dss_size) { /* Normal (if we've iterated thru the set of strings using dwarf_get_str and are at the end). */ diff --git a/src/lib/libdwarf/dwarf_tied.c b/src/lib/libdwarf/dwarf_tied.c index 1eeb8d1..5866fac 100644 --- a/src/lib/libdwarf/dwarf_tied.c +++ b/src/lib/libdwarf/dwarf_tied.c @@ -166,6 +166,7 @@ _dwarf_loop_reading_debug_info_for_cu( memset(&signature,0,sizeof(signature)); sres = _dwarf_next_cu_header_internal(tieddbg, is_info, + /* no CU die wanted*/ NULL, &cu_header_length, &version_stamp, &abbrev_offset, &address_size, &length_size,&extension_size, diff --git a/src/lib/libdwarf/dwarf_util.c b/src/lib/libdwarf/dwarf_util.c index 99113ef..3dec46f 100644 --- a/src/lib/libdwarf/dwarf_util.c +++ b/src/lib/libdwarf/dwarf_util.c @@ -148,7 +148,7 @@ dwarf_get_endian_copy_function(Dwarf_Debug dbg) Dwarf_Bool _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return FALSE; } if (dbg->de_cu_hashindex_data) { @@ -159,7 +159,7 @@ _dwarf_file_has_debug_fission_cu_index(Dwarf_Debug dbg) Dwarf_Bool _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return FALSE; } if (dbg->de_tu_hashindex_data ) { @@ -171,7 +171,7 @@ _dwarf_file_has_debug_fission_tu_index(Dwarf_Debug dbg) Dwarf_Bool _dwarf_file_has_debug_fission_index(Dwarf_Debug dbg) { - if (!dbg) { + if (IS_INVALID_DBG(dbg)) { return FALSE; } if (dbg->de_cu_hashindex_data || @@ -629,8 +629,8 @@ copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin, Dwarf_Abbrev_List listent = entry_in[k]; Dwarf_Abbrev_List nextlistent = 0; for (; listent ; listent = nextlistent) { - unsigned long newtmp = listent->abl_code; - unsigned long newhash = newtmp HT_MOD_OP + Dwarf_Unsigned newtmp = listent->abl_code; + Dwarf_Unsigned newhash = newtmp HT_MOD_OP (entry_out_count -1); nextlistent = listent->abl_next; @@ -743,7 +743,7 @@ _dwarf_get_abbrev_for_code(Dwarf_CU_Context context, Dwarf_Byte_Ptr end_abbrev_ptr = 0; Dwarf_Small *abbrev_section_start = dbg->de_debug_abbrev.dss_data; - unsigned long hashable_val = 0; + Dwarf_Unsigned hashable_val = 0; if (!hash_table_base->tb_entries) { hash_table_base->tb_table_entry_count = @@ -883,7 +883,7 @@ printf("debugging: initial size %u\n",HT_DEFAULT_TABLE_SIZE); return DW_DLV_NO_ENTRY; } do { - unsigned long new_hashable_val = 0; + Dwarf_Unsigned new_hashable_val = 0; Dwarf_Off abb_goff = 0; Dwarf_Unsigned atcount = 0; Dwarf_Unsigned impl_const_count = 0; diff --git a/src/lib/libdwarf/dwarf_util.h b/src/lib/libdwarf/dwarf_util.h index c2d7d4b..a20f3e1 100644 --- a/src/lib/libdwarf/dwarf_util.h +++ b/src/lib/libdwarf/dwarf_util.h @@ -153,6 +153,13 @@ _dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error, (ptr) += lu_leblen; \ } while (0) +/* This is for use where the action taken must be local. + One cannot do a return. Reasons vary. + Use this in an if or assign the result to a + local small integer (normally an int). */ +#define IS_INVALID_DBG(d) \ + ((!(d) || ((d)->de_magic != DBG_IS_VALID))?TRUE:FALSE) + /* Any error found here represents a bug that cannot be dealloc-d as the caller will not know there was no dbg */ #define CHECK_DIE(die, error_ret_value) \ @@ -178,6 +185,21 @@ _dwarf_create_area_len_error(Dwarf_Debug dbg, Dwarf_Error *error, } \ } while (0) +/* Any error found here represents a bug that cannot + be fixed. Pass cd_funcname as a quoted string, + for example "dwarf_crc32" */ +#define CHECK_DBG(cd_dbg,cd_er,cd_funcname) \ + do { \ + if (!(cd_dbg) || (cd_dbg)->de_magic != DBG_IS_VALID) { \ + _dwarf_error_string(NULL, (cd_er), DW_DLE_DBG_NULL, \ + "DW_DLE_DBG_NULL: " \ + "dbg argument to " cd_funcname \ + "either null or it contains" \ + "a stale Dwarf_Debug pointer"); \ + return DW_DLV_ERROR; \ + } \ + } while (0) + /* Reads 'source' for 'length' bytes from unaligned addr. diff --git a/src/lib/libdwarf/dwarf_xu_index.c b/src/lib/libdwarf/dwarf_xu_index.c index 85a19b8..01e5982 100644 --- a/src/lib/libdwarf/dwarf_xu_index.c +++ b/src/lib/libdwarf/dwarf_xu_index.c @@ -195,13 +195,8 @@ dwarf_get_xu_index_header(Dwarf_Debug dbg, Dwarf_Unsigned section_sizes_tab_offset = 0; unsigned datalen32 = SIZEOFT32; Dwarf_Small *section_end = 0; -/* FIXME */ - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, - "DW_DLE_XU_TYPE_ARG_ERROR: Dwarf_Debug pointer " - "is not valid"); - return DW_DLV_ERROR; - } + + CHECK_DBG(dbg,error,"dwarf_get_xu_index_header()"); if (!section_type || !xuptr) { _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, "DW_DLE_XU_TYPE_ARG_ERROR: section type or header " @@ -540,12 +535,7 @@ dwarf_get_xu_section_names(Dwarf_Xu_Index_Header xuhdr, } dbg = xuhdr->gx_dbg; /* FIXME */ - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, - "DW_DLE_XU_TYPE_ARG_ERROR: Dwarf_Debug pointer " - "from Dwarf_Xu_Index_Header is not valid"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_xu_section_names()"); if ( column_index >= xuhdr->gx_column_count_sections) { dwarfstring s; @@ -608,12 +598,7 @@ dwarf_get_xu_section_offset(Dwarf_Xu_Index_Header xuhdr, } /* FIXME */ dbg = xuhdr->gx_dbg; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, - "DW_DLE_XU_TYPE_ARG_ERROR: Dwarf_Debug pointer " - "from Dwarf_Xu_Index_Header is not valid"); - return DW_DLV_ERROR; - } + CHECK_DBG(dbg,error,"dwarf_get_xu_section_offset()"); sizerow = xuhdr->gx_section_sizes_offset + xuhdr->gx_section_data; offsetrow = xuhdr->gx_section_offsets_offset + @@ -931,6 +916,7 @@ _dwarf_get_debugfission_for_offset(Dwarf_Debug dbg, Dwarf_Unsigned sect_index_base = 0; Dwarf_Sig8 key; + CHECK_DBG(dbg,error,"_dwarf_get_debugfission_for_offset()"); sect_index_base = DW_SECT_INFO; key = zerohashkey; sres = _dwarf_get_xuhdr(dbg,key_type, &xuhdr,error); @@ -960,13 +946,7 @@ dwarf_get_debugfission_for_key(Dwarf_Debug dbg, Dwarf_Unsigned percu_index = 0; Dwarf_Xu_Index_Header xuhdr = 0; - if (!dbg || dbg->de_magic != DBG_IS_VALID) { - _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, - "DW_DLE_XU_TYPE_ARG_ERROR: Dwarf_Debug pointer " - "is not valid"); - return DW_DLV_ERROR; -/*FIXME */ - } + CHECK_DBG(dbg,error,"dwarf_get_debugfission_for_key()"); if (!key || !key_type || !percu_out) { _dwarf_error_string(0,error,DW_DLE_XU_TYPE_ARG_ERROR, "DW_DLE_XU_TYPE_ARG_ERROR: dw_key, dw_keytype, or " diff --git a/src/lib/libdwarf/libdwarf.h b/src/lib/libdwarf/libdwarf.h index 9a0783e..ed3d1d0 100644 --- a/src/lib/libdwarf/libdwarf.h +++ b/src/lib/libdwarf/libdwarf.h @@ -134,7 +134,7 @@ extern "C" { associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer - was unable to analyse the + was unable to analyze the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) @@ -777,7 +777,7 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head; associated with a dwarf frame. */ #define DW_DLX_NO_EH_OFFSET (-1LL) /* The following value indicates that the producer - was unable to analyse the + was unable to analyze the source file to generate Exception tables for this function. */ #define DW_DLX_EH_OFFSET_UNAVAILABLE (-2LL) @@ -1733,16 +1733,26 @@ DW_API int dwarf_get_tied_dbg(Dwarf_Debug dw_dbg, @{ */ -/*! @brief Return information on the next CU header. +/*! @brief Return information on the next CU header(e). + + New in v0.9.0 November 2023. The library keeps track of where it is in the object file and it knows where to find 'next'. + + It returns the CU_DIE pointer through dw_cu_die; + @param dw_dbg The Dwarf_Debug of interest. @param dw_is_info Pass in TRUE if reading through .debug_info Pass in FALSE if reading through DWARF4 .debug_types. + @param dw_cu_die + Pass in a pointer to a Dwarf_Die. the call + sets the passed-in pointer to be a Compilation + Unit Die for use with dwarf_child() or any + other call requiring a Dwarf_Die argument. @param dw_cu_header_length Returns the length of the just-read CU header. @param dw_version_stamp @@ -1783,9 +1793,55 @@ DW_API int dwarf_get_tied_dbg(Dwarf_Debug dw_dbg, Returns DW_DLV_OK on success. Returns DW_DLV_NO_ENTRY if all CUs have been read. - @see examplecuhdr + @see examplecuhdre */ +DW_API int dwarf_next_cu_header_e(Dwarf_Debug dw_dbg, + Dwarf_Bool dw_is_info, + Dwarf_Die *dw_cu_die, + Dwarf_Unsigned *dw_cu_header_length, + Dwarf_Half *dw_version_stamp, + Dwarf_Off *dw_abbrev_offset, + Dwarf_Half *dw_address_size, + Dwarf_Half *dw_length_size, + Dwarf_Half *dw_extension_size, + Dwarf_Sig8 *dw_type_signature, + Dwarf_Unsigned *dw_typeoffset, + Dwarf_Unsigned *dw_next_cu_header_offset, + Dwarf_Half *dw_header_cu_type, + Dwarf_Error *dw_error); + +/*! @brief Return information on the next CU header(d) + + This is the version to use for linking against + libdwarf v0.8.0 and earlier (and it also works + for later versions). + + This version will evenually be deprecated, but + that won't be for years. + + The library keeps track of where it is in the object file + and it knows where to find 'next'. + + In order to read the DIE tree of the CU this + records information in the dw_dbg data and + after a successful call to dwarf_next_cu_header_d() + only an immediate call to + dwarf_siblingof_b(dw_dbg,NULL,dw_is_info, &cu_die,...) + is guaranteed to return the correct DIE (a Compilation + Unit DIE). + + Avoid any call to libdwarf + between a successful call to dwarf_next_cu_header_d() and + dwarf_siblingof_b(dw_dbg,NULL,dw_is_info, &cu_die,...) + to ensure the intended and correct Dwarf_Die is returned. + + @see examplecuhdrd + + All arguments are the same as dwarf_next_cu_header_e() + except that there is no dw_cu_die argument here. +*/ + DW_API int dwarf_next_cu_header_d(Dwarf_Debug dw_dbg, Dwarf_Bool dw_is_info, Dwarf_Unsigned *dw_cu_header_length, @@ -1800,6 +1856,25 @@ DW_API int dwarf_next_cu_header_d(Dwarf_Debug dw_dbg, Dwarf_Half *dw_header_cu_type, Dwarf_Error *dw_error); +/*! @brief Return the next sibling DIE. + + @param dw_die + Pass in a known DIE and this will retrieve + the next sibling in the chain. + @param dw_return_siblingdie + The DIE returned through the pointer. + @param dw_error + The usual error information, if any. + @return + Returns DW_DLV_OK etc. + + @see example4 + @see dwarf_get_die_infotypes +*/ +DW_API int dwarf_siblingof_c(Dwarf_Die dw_die, + Dwarf_Die *dw_return_siblingdie, + Dwarf_Error *dw_error); + /*! @brief Return the first DIE or the next sibling DIE. @param dw_dbg @@ -1833,6 +1908,7 @@ DW_API int dwarf_siblingof_b(Dwarf_Debug dw_dbg, Any Dwarf_Die will work. The values returned through the pointers are about the CU for a DIE + @param dw_die Some open Dwarf_Die. @param dw_version @@ -2102,7 +2178,7 @@ DW_API Dwarf_Bool dwarf_addr_form_is_indexed(int dw_form); /*! @brief Return the CU DIE offset given any DIE Returns - the global debug_info section offset of the CU die + the global debug_info section offset of the CU DIE in the CU containing the given_die (the passed in DIE can be any DIE). @@ -3239,6 +3315,49 @@ DW_API int dwarf_discr_entry_s(Dwarf_Dsc_Head dw_dsc, /*! @brief The list of source files from the line table header + The array returned by this function applies to + a single compilation unit (CU). + + The returned array is indexed from 0 (zero) to + dw_filecount-1 when the function returns + DW_DLV_OK. + + In referencing the array via a file-number from + a DW_AT_decl_file attribute one needs to + know if the CU is DWARF5 or not. + + Line Table Version numbers match compilation unit + version numbers except that an experimental line table + with line table version 0xfe06 has + sometimes been used with DWARF4. + + For DWARF5: + The file-number from a \b DW_AT_decl_file + is the proper index into the array of string pointers. + + For DWARF2,3,4, including experimental line table + version 0xfe06 and a file-number from a \b DW_AT_decl_file: + -# If the file-number is zero there is no file name to find. + -# Otherwise subtract one(1) from the file-number and + use the new value as the index into the array + of string pointers. + + The name strings returned are each assembled in the + following way by dwarf_srcfiles(): + + -# The file number denotes a name in the line table header. + -# If the name is not a full path (i.e. not starting + with / in posix/linux/MacOS) then prepend the appropriate + directory string from the line table header. + -# If the name is still not a full path then prepend + the content of the DW_AT_comp_dir attribute + of the CU DIE. + + To retrieve the line table version call + dwarf_srclines_b() and dwarf_srclines_version(). + + @see examplec + @param dw_cu_die The CU DIE in this CU. @param dw_srcfiles @@ -3267,8 +3386,11 @@ DW_API int dwarf_srcfiles(Dwarf_Die dw_cu_die, /*! @brief Initialize Dwarf_Line_Context for line table access Returns Dwarf_Line_Context pointer, needed for - access to line table data. + access to line table data. Returns the line table + version number (needed to use dwarf_srcfiles() + properly). + @see examplec @see exampled @param dw_cudie @@ -3295,7 +3417,7 @@ DW_API int dwarf_srclines_b(Dwarf_Die dw_cudie, /*! @brief Access source lines from line context - The access to Dwarf_Line data from + Provides access to Dwarf_Line data from a Dwarf_Line_Context on a standard line table. @param dw_linecontext @@ -3517,7 +3639,6 @@ DW_API int dwarf_srclines_files_indexes( @return DW_DLV_OK if it succeeds. - @see examplec */ DW_API int dwarf_srclines_files_data_b( Dwarf_Line_Context dw_context, @@ -3577,9 +3698,15 @@ DW_API int dwarf_srclines_include_dir_data( Dwarf_Error * dw_error); /*! @brief The DWARF version number of this compile-unit - The .debug_lines[.dwo] t - actual tables:0 (header with no lines), - 1 (standard table), or 2 (experimental). + + The .debug_lines[.dwo] table count informs about + the line table version and the + type of line table involved. + + Meaning of the value returned via dw_table_count: + - 0 The table is a header with no lines. + - 1 The table is a standard line table. + - 2 The table is an experimental line table. @param dw_line_context The Line Context of interest. @@ -4703,16 +4830,17 @@ DW_API int dwarf_debug_addr_table(Dwarf_Debug dw_dbg, Dwarf_Unsigned *dw_length, Dwarf_Half *dw_version, Dwarf_Small *dw_address_size, - Dwarf_Unsigned *dw_dw_at_addr_base, + Dwarf_Unsigned *dw_at_addr_base, Dwarf_Unsigned *dw_entry_count, Dwarf_Unsigned *dw_next_table_offset, Dwarf_Error *dw_error); /*! @brief Return .debug_addr address given table index - @param dw_table_header + + @param dw_dat Pass in a Dwarf_Debug_Addr_Table pointer. - @param dw_table_header + @param dw_entry_index Pass in a Dwarf_Debug_Addr_Table index to an address. If out of the valid range 0 through dw_entry_count-1 the function returns @@ -4727,8 +4855,7 @@ DW_API int dwarf_debug_addr_table(Dwarf_Debug dw_dbg, If the dw_section_offset passed in is out of range it returns DW_DLV_NO_ENTRY. If it returns DW_DLV_ERROR only dw_error is - set, dw_address and dw_segment are not - set through the pointers. + set, dw_address is not set. */ DW_API int dwarf_debug_addr_by_index(Dwarf_Debug_Addr_Table dw_dat, @@ -4738,7 +4865,7 @@ DW_API int dwarf_debug_addr_by_index(Dwarf_Debug_Addr_Table dw_dat, /*! @brief dealloc (free) a Dwarf_Attr_Table record. - @param dw_table_header + @param dw_dat Pass in a valid Dwarf_Debug_Addr_Table pointer. Does nothing if the dw_dat field is NULL. @@ -4825,7 +4952,8 @@ DW_API int dwarf_get_macro_context_by_offset(Dwarf_Die dw_die, Dwarf_Unsigned * dw_macro_ops_data_length, Dwarf_Error * dw_error); -/* New December 2020. Sometimes its necessary to know +/* New December 2020. libdwarf 0.1.0 + Sometimes its necessary to know a context total length including macro 5 header */ /*! @brief Return a macro context total length @@ -5333,6 +5461,7 @@ DW_API int dwarf_get_fde_instr_bytes(Dwarf_Fde dw_fde, /*! @brief Return information on frame registers at a given pc value An FDE at a given pc (code address) + This function is new in October 2023 version 0.9.0. @param dw_fde Pass in the FDE of interest. @@ -5345,6 +5474,14 @@ DW_API int dwarf_get_fde_instr_bytes(Dwarf_Fde dw_fde, On success returns the address of the row of frame data which may be a few counts off of the pc requested. + @param dw_has_more_rows + On success returns FALSE if there are no more rows, + otherwise returns TRUE. + @param dw_subsequent_pc + On success this returns the address of the next pc + for which there is a register row, making access + to all the rows in sequence much more efficient + than just adding 1 to a pc value. @param dw_error The usual error detail return pointer. @return @@ -5353,6 +5490,23 @@ DW_API int dwarf_get_fde_instr_bytes(Dwarf_Fde dw_fde, in the table. */ +DW_API int dwarf_get_fde_info_for_all_regs3_b(Dwarf_Fde dw_fde, + Dwarf_Addr dw_pc_requested, + Dwarf_Regtable3* dw_reg_table, + Dwarf_Addr* dw_row_pc, + Dwarf_Bool* dw_has_more_rows, + Dwarf_Addr* dw_subsequent_pc, + Dwarf_Error* dw_error); + +/*! @brief @brief Return information on frame registers at a given pc value + + Identical to dwarf_get_fde_info_for_all_regs3_b() except that + this doesn't output dw_has_more_rows and dw_subsequent_pc. + + If you need to iterate through all rows of the FDE, consider + switching to dwarf_get_fde_info_for_all_regs3_b() as it is more + efficient. +*/ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde, Dwarf_Addr dw_pc_requested, Dwarf_Regtable3* dw_reg_table, @@ -5362,9 +5516,9 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde, /* See discussion of dw_value_type, libdwarf.h. */ /*! @brief Return details about a particular pc and register. - It is inefficient to iterate across all table_columns (registers) + It is efficient to iterate across all table_columns (registers) using this function (dwarf_get_fde_info_for_reg3_c()). - Instead call dwarf_get_fde_info_for_all_regs3() + Or one could instead call dwarf_get_fde_info_for_all_regs3() and index into the table it fills in. If dw_value_type == DW_EXPR_EXPRESSION or @@ -5374,8 +5528,8 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde, on runtime frame data which cannot be calculated without a stack frame including registers (etc). - dwarf_get_fde_info_for_reg3_c() is new in Septmber 2023 - to correct the incorrect type of the dw_offset + dwarf_get_fde_info_for_reg3_c() is new in libdwarf 0.8.0. + It corrects the incorrect type of the dw_offset argument in dwarf_get_fde_info_for_reg3_b(). Both versions operate correctly. @@ -5396,7 +5550,7 @@ DW_API int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde dw_fde, On success returns a register number. @param dw_offset On success returns a signed register offset value when - dw_value_tyoe is DW_EXPR_OFFSET or DW_EXPER_VAL_OFFSET. + dw_value_type is DW_EXPR_OFFSET or DW_EXPER_VAL_OFFSET. @param dw_block_content On success returns a pointer to a block. For example, for DW_EXPR_EXPRESSION the block @@ -5456,11 +5610,11 @@ DW_API int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde dw_fde, /*! @brief Get the value of the CFA for a particular pc value - @see dwarf_get_fde_info_for_reg3_c + @see dwarf_get_fde_info_for_reg3_c() has essentially the same return values as dwarf_get_fde_info_for_reg3_c but it refers to the CFA (which is not part of the register - table) so function has no table column argument. + table) so this function has no table column argument. New in September 2023, release 0.8.0. dwarf_get_fde_info_for_cfa_reg3_c() returns dw_offset @@ -6370,8 +6524,8 @@ DW_API int dwarf_get_debug_sup(Dwarf_Debug dw_dbg, /*! @defgroup debugnames Fast Access to .debug_names DWARF5 @{ - The section is new in DWARF5 supersedes .debug_pubnames and - .debug_pubtypes in DWARF2, DWARF3, and DWARF4. + The section is new in DWARF5 and supersedes .debug_pubnames + and .debug_pubtypes in DWARF2, DWARF3, and DWARF4. The functions provide a detailed reporting of the content and structure of the table (so one @@ -7235,7 +7389,7 @@ DW_API int dwarf_get_gnu_index_block(Dwarf_Gnu_Index_Head dw_head, @param dw_head Pass in the Dwarf_Gnu_Index_head interest. - @param dw_number + @param dw_blocknumber Pass in the block number of the block of interest. 0 through dw_index_block_count_out-1. @param dw_entrynumber @@ -7878,7 +8032,17 @@ DW_API int dwarf_get_debugfission_for_key(Dwarf_Debug dw_dbg, such arguments. Useful if you only care about some of the data potentially returned. - Caller frees space returned by debuglink_fullpath_returned. + If dw_debuglink_fullpath returned is set by + the call the space allocated must be freed + by the caller with free(dw_debuglink_fullpath_returned). + + if dw_debuglink_paths_returned is set by the call + the space allocated must be free by + the caller with free(dw_debuglink_paths_returned). + + dwarf_finish() will not free strings + dw_debuglink_fullpath_returned or + dw_debuglink_paths_returned. @param dw_dbg The Dwarf_Debug of interest. @@ -7896,7 +8060,6 @@ DW_API int dwarf_get_debugfission_for_key(Dwarf_Debug dw_dbg, @param dw_debuglink_path_length_returned On success returns the strlen() of dw_debuglink_fullpath_returned . - @param dw_buildid_type_returned On success returns a pointer to integer with a type code. See the buildid definition. @@ -7910,11 +8073,12 @@ DW_API int dwarf_get_debugfission_for_key(Dwarf_Debug dw_dbg, On success this is set to the length of the set of bytes pointed to by dw_buildid_returned . @param dw_paths_returned - On success returns a pointer to an array of + On success sets a pointer to an array of pointers to strings, each with a global path. - It actually points to an array of pointers - followed by a blob of strings, and freeing - all of that just means calling free(dw_paths_returned). + These strings must be freed by the caller, + dwarf_finish() will not free these strings. + Call free(dw_paths_returned). + @param dw_paths_length_returned On success returns the length of the array of string pointers dw_paths_returned points at. @@ -8351,6 +8515,11 @@ DW_API int dwarf_get_FORM_CLASS_name(enum Dwarf_Form_Class dw_fc, /*! @defgroup objectsections Object Sections Data @{ + These functions are not often used. They + give access to section- and objectfile-related + information, and that sort of information + is not generally needed to understand DWARF content.. + Section name access. Because names sections such as .debug_info might end with .dwo or be .zdebug or might not. @@ -8364,6 +8533,14 @@ DW_API int dwarf_get_FORM_CLASS_name(enum Dwarf_Form_Class dw_fc, MacOS puts in its object sections (which the MacOS reader translates). + These calls returning selected object header + {machine architecture,flags) + and section (offset, flags) data + are not of interest to most library callers: + dwarf_machine_architecture(), + dwarf_get_section_info_by_index_a(), and + dwarf_get_section_info_by_name_a(). + The simple calls will not be documented in full detail here. */ @@ -8497,15 +8674,16 @@ DW_API int dwarf_get_ranges_section_name(Dwarf_Debug dw_dbg, This is not from DWARF information, it is from object file headers. */ -DW_API int dwarf_get_offset_size(Dwarf_Debug /*dbg*/, +DW_API int dwarf_get_offset_size(Dwarf_Debug dw_dbg, Dwarf_Half * dw_offset_size, Dwarf_Error * dw_error); + /*! @brief Get the address size as defined by the object This is not from DWARF information, it is from object file headers. */ -DW_API int dwarf_get_address_size(Dwarf_Debug /*dbg*/, +DW_API int dwarf_get_address_size(Dwarf_Debug dw_dbg, Dwarf_Half * dw_addr_size, Dwarf_Error * dw_error); @@ -8540,7 +8718,20 @@ DW_API int dwarf_get_line_section_name_from_die(Dwarf_Die dw_die, const char ** dw_section_name_out, Dwarf_Error * dw_error); -/*! @brief Given a section name, get its size and address +/*! @brief Given a section name, get its size, address, etc + + New in v0.9.0 November 2023. + + This is not often used and is completely + unnecessary for most to call. + + See dwarf_get_section_info_by_name() for the + older and still current version. + + Any of the pointers + dw_section_addr, dw_section_size, dw_section_flags, + and dw_section_offset may be passed in as zero + and those will be ignored by the function. @param dw_dbg The Dwarf_Debug of interest. @@ -8553,18 +8744,61 @@ DW_API int dwarf_get_line_section_name_from_die(Dwarf_Die dw_die, @param dw_section_size On success returns the section size as defined by an object header. + @param dw_section_flags + On success returns the section flags as defined + by an object header. + The flag meaning depends on which object format + is being read and the meaning is defined by + the object format. + We hope it is of some use. + In PE object files this + field is called @b Characteristics. + @param dw_section_offset + On success returns the section offset as defined + by an object header. + The offset meaning is supposedly an object file offset + but the meaning depends on the object file type(!). + We hope it is of some use. @param dw_error On error returns the usual error pointer. @return Returns DW_DLV_OK etc. */ +DW_API int dwarf_get_section_info_by_name_a(Dwarf_Debug dw_dbg, + const char * dw_section_name, + Dwarf_Addr * dw_section_addr, + Dwarf_Unsigned* dw_section_size, + Dwarf_Unsigned* dw_section_flags, + Dwarf_Unsigned* dw_section_offset, + Dwarf_Error * dw_error); + +/*! @brief Given a section name, get its size and address + + See dwarf_get_section_info_by_name_a() for the + newest version which returns additional values. + + Fields and meanings in dwarf_get_section_info_by_name() + are the same as in + dwarf_get_section_info_by_name_a() + except that the arguments dw_section_flags + and dw_section_offset are missing here. +*/ + DW_API int dwarf_get_section_info_by_name(Dwarf_Debug dw_dbg, const char * dw_section_name, Dwarf_Addr * dw_section_addr, Dwarf_Unsigned* dw_section_size, Dwarf_Error * dw_error); -/*! @brief Given a section index, get its size and address +/*! @brief Given a section index, get its size and address, etc + + See dwarf_get_section_info_by_index() for the + older and still current version. + + Any of the pointers + dw_section_addr, dw_section_size, dw_section_flags, + and dw_section_offset may be passed in as zero + and those will be ignored by the function. @param dw_dbg The Dwarf_Debug of interest. @@ -8580,11 +8814,46 @@ DW_API int dwarf_get_section_info_by_name(Dwarf_Debug dw_dbg, @param dw_section_size On success returns the section size as defined by an object header. + @param dw_section_flags + On success returns the section flags as defined + by an object header. + The flag meaning depends on which object format + is being read and the meaning is defined by + the object format. In PE object files this + field is called @b Characteristics. + We hope it is of some use. + @param dw_section_offset + On success returns the section offset as defined + by an object header. + The offset meaning is supposedly an object file offset + but the meaning depends on the object file type(!). + We hope it is of some use. @param dw_error On error returns the usual error pointer. @return Returns DW_DLV_OK etc. */ +DW_API int dwarf_get_section_info_by_index_a(Dwarf_Debug dw_dbg, + int dw_section_index, + const char ** dw_section_name, + Dwarf_Addr* dw_section_addr, + Dwarf_Unsigned* dw_section_size, + Dwarf_Unsigned* dw_section_flags, + Dwarf_Unsigned* dw_section_offset, + Dwarf_Error* dw_error); + +/*! @brief Given a section index, get its size and address + + See dwarf_get_section_info_by_index_a() for the + newest version which returns additional values. + + Fields and meanings in dwarf_get_section_info_by_index() + are the same as in + dwarf_get_section_info_by_index_a() + except that the arguments dw_section_flags + and dw_section_offset are missing here. +*/ + DW_API int dwarf_get_section_info_by_index(Dwarf_Debug dw_dbg, int dw_section_index, const char ** dw_section_name, @@ -8592,6 +8861,95 @@ DW_API int dwarf_get_section_info_by_index(Dwarf_Debug dw_dbg, Dwarf_Unsigned* dw_section_size, Dwarf_Error* dw_error); +/*! @brief Get basic object information from Dwarf_Debug + + Not all the fields here are relevant for all object + types, and the dw_obj_machine and dw_obj_flags + have ABI-defined values which have nothing to do + with DWARF. + + dwarf_ub_offset, dw_ub_count, dw_ub_index only + apply to DW_FTYPE_APPLEUNIVERSAL. + + dw_comdat_groupnumber only applies to DW_FTYPE_ELF. + + Other than dw_dbg one can pass in NULL for any + pointer parameter whose value is not of interest. + + @param dw_dbg + The Dwarf_Debug of interest. + @param dw_ftype + Pass in a pointer. On success the value + pointed to will be set to the the applicable + DW_FTYPE value (see libdwarf.h). + @param dw_obj_pointersize + Pass in a pointer. On success the value + pointed to will be set to the the applicable + pointer size, which is almost always either 4 or 8. + @param dw_obj_is_big_endian + Pass in a pointer. On success the value + pointed to will be set to either 1 (the object being + read is big-endia) or 0 (the object being read is + little-endian. + @param dw_obj_machine + Pass in a pointer. On success the value + pointed to will be set to a value that + the specific ABI uses for the machine-architecture + the object file says it is for. + @param dw_obj_flags + Pass in a pointer. On success the value + pointed to will be set to a value that + the specific ABI uses for a header record + flags word (in a PE object the flags word is + called @b Characteristics ). + @param dw_path_source + Pass in a pointer. On success the value + pointed to will be set to a value that + libdwarf sets to a DW_PATHSOURCE value + indicating what caused the file path. + @param dw_ub_offset + Pass in a pointer. On success + if the value of dw_ftype is DW_FTYPE_APPLEUNIVERSAL + the returned value will be set to the count + (in all other cases, the value is set to 0) + @param dw_ub_count + Pass in a pointer. On success + if the value of dw_ftype is DW_FTYPE_APPLEUNIVERSAL + the returned value will be set to the number + of object files in the binary + (in all other cases, the value is set to 0) + @param dw_ub_index + Pass in a pointer. On success + if the value of dw_ftype is DW_FTYPE_APPLEUNIVERSAL + the returned value will be set to the number + of the specific object from the universal-binary, + usable values are 0 through dw_ub_count-1. + (in all other cases, the value is set to 0) + @param dw_comdat_groupnumber + Pass in a pointer. On success + if the value of dw_ftype is DW_FTYPE_ELF + the returned value will be the comdat group + being referenced. + (in all other cases, the value is set to 0) + @return + Returns DW_DLV_NO_ENTRY if the Dwarf_Debug passed in + is null or stale. Otherwise returns DW_DLV_OK + and non-null return-value pointers will have + meaningful data. + +*/ +DW_API int dwarf_machine_architecture(Dwarf_Debug dw_dbg, + Dwarf_Small *dw_ftype, + Dwarf_Small *dw_obj_pointersize, + Dwarf_Bool *dw_obj_is_big_endian, + Dwarf_Unsigned *dw_obj_machine, /*architecture*/ + Dwarf_Unsigned *dw_obj_flags, + Dwarf_Small *dw_path_source, + Dwarf_Unsigned *dw_ub_offset, + Dwarf_Unsigned *dw_ub_count, + Dwarf_Unsigned *dw_ub_index, + Dwarf_Unsigned *dw_comdat_groupnumber); + /*! @brief Get section count (of object file sections). */ DW_API int dwarf_get_section_count(Dwarf_Debug dw_dbg); @@ -8607,10 +8965,12 @@ DW_API int dwarf_get_section_count(Dwarf_Debug dw_dbg); with MIPSpro 7.3.1.3 toolchain.). @param dw_dbg - Pass in the Dwarf_Debug of interest. + Pass in a valid Dwarf_Debug of interest. @return - Always returns DW_DLV_OK. + If the dw_dbg is non-null it returns DW_DLV_OK. + If dw_dbg is NULL it returns DW_DLV_NO_ENTRY. + */ DW_API int dwarf_get_section_max_offsets_d(Dwarf_Debug dw_dbg, Dwarf_Unsigned * dw_debug_info_size, @@ -8641,6 +9001,11 @@ DW_API int dwarf_get_section_max_offsets_d(Dwarf_Debug dw_dbg, /*! @defgroup secgroups Section Groups Objectfile Data @{ + + Section Groups are defined in the extended + Elf ABI and are usually seen in relocatable + Elf object files. + @link dwsec_sectiongroup Section Groups Overview @endlink */ @@ -8948,6 +9313,11 @@ DW_API int dwarf_get_universalbinary_count( actually opening a Dwarf_Debug. These are crucial for libdwarf itself. + The dw_ftype returned is one of + DW_FTYPE_APPLEUNIVERSAL + DW_FTYPE_MACH_O + DW_FTYPE_ELF + DW_FTYPE_PE */ DW_API int dwarf_object_detector_path_b(const char * dw_path, diff --git a/src/lib/libdwarf/meson.build b/src/lib/libdwarf/meson.build index ac4c273..8edf613 100644 --- a/src/lib/libdwarf/meson.build +++ b/src/lib/libdwarf/meson.build @@ -64,15 +64,90 @@ libdwarf_src = [ zlib_deps = dependency('zlib', method: 'pkg-config', required: false) libzstd_deps = dependency('libzstd', method: 'pkg-config', required: false) -if zlib_deps.found() == true - # set10 means set to 1 or 0. Ref man, see cfg_data.set10 - # A variation on set(). - config_h.set10('HAVE_ZLIB', true) - config_h.set10('HAVE_ZLIB_H', true) +if zlib_deps.found() + message(['mesondebug found base zlib',zlib_deps.found()]) endif -if libzstd_deps.found() == true - config_h.set10('HAVE_ZSTD', true) - config_h.set10('HAVE_ZSTD_H', true) +if libzstd_deps.found() + message(['mesondebug found base libzstd',libzstd_deps.found()]) +endif + +if zlib_deps.found() + message(['mesondebug found base zlib',zlib_deps.found()]) +else + if fs.is_dir('/opt/local/lib') and fs.is_file('/opt/local/include/zlib.h') + message(['mesondebug /opt/local/include/zlib.h exists']) + zlib_deps = declare_dependency(link_args: [ '-L/opt/local/lib','-lz' ], + include_directories: ['/opt/local/include']) + message(['mesondebug zlib in /opt/local',zlib_deps.found()]) + endif +endif + +if libzstd_deps.found() + message(['mesondebug found base libzstd',libzstd_deps.found()]) +else + if fs.is_dir('/opt/local/lib') and fs.is_file('/opt/local/include/zstd.h') + message(['mesondebug /opt/local/include/zstd.h exists']) + libzstd_deps = declare_dependency(link_args: ['-L/opt/local/lib','-lzstd' ], + include_directories: ['/opt/local/include']) + message(['mesondebug zstd in /opt/local', libzstd_deps.found()]) + endif +endif + +if zlib_deps.found() + message(['Have zlib']) +else + if fs.is_dir('/usr/local/lib') and fs.is_file('/usr/local/include/zlib.h') + message(['mesondebug /usr/local/include/zlib.h exists']) + zlib_deps = declare_dependency(link_args: [ '-L/usr/local/lib','-lz' ], + include_directories: ['/usr/local/include']) + message(['mesondebug zlib in /usr/local',zlib_deps.found()]) + endif +endif + +if libzstd_deps.found() + message(['Have libzstd']) +else + if fs.is_dir('/usr/local/lib') and fs.is_file('/usr/local/include/zstd.h') + message(['mesondebug /usr/local/include/zstd.h exists']) + libzstd_deps = declare_dependency(link_args: [ '-L/usr/local/lib', + '-lzstd' ], + include_directories: ['/usr/local/include']) + message(['mesondebug zstd in /usr/local',libzstd_deps.found()]) + endif +endif + +if zlib_deps.found() + if libzstd_deps.found() + message('mesondebug Have zlib and libzstd') + config_h.set10('HAVE_ZSTD_H',true) + config_h.set10('HAVE_ZSTD',true) + config_h.set10('HAVE_ZLIB_H',true) + config_h.set10('HAVE_ZLIB',true) + else + config_h.set10('HAVE_ZLIB_H',false) + config_h.set10('HAVE_ZLIB',false) + zlib_deps = dependency('',required: false) + if zlib_deps.found() + error('mesondebug libdwarf error zlib') + endif + message('mesondebug no libzstd, set zlib_deps', zlib_deps.found()) + message('mesondebug Since builds and tests both ') + message('mesondebug leaving zlib set will be ignored in build and test') + endif +else + if libzstd_deps.found() + config_h.set10('HAVE_ZSTD_H',false) + config_h.set10('HAVE_ZSTD',false) + libszstd_deps = dependency('',required: false) + if libzstd_deps.found() + error('mesondebug libdwarf error libzstd') + endif + message('mesondebug no zlib, set libzstd_deps',libzstd_deps.found()) + message('mesondebug Since builds and tests want both') + message('mesondebug leaving libzstd set will be ignored in build and test') + else + message('mesondebug found neither zlib nor libzstd') + endif endif if (lib_type == 'shared')